Community Tip - If community subscription notifications are filling up your inbox you can set up a daily digest and get all your notifications in a single email. X
I am using Windchill PDMLink Release 11.1 and Datecode with CPS M020-CPS20
We would like to move the Data from Existing Container to the new Container through customization.
Please suggest your thoughts on this.
Hello,
We have move API for that. Below link will be helpful to develop a utility.
All the versions and iterations will be moved to new context.
https://www.ptc.com/en/support/article/CS69568
Regards
Ajit
Hello Ajit,
Thank you for your reply. We will be able to move the data by using this API but in my case there are 1 lakh+ objects which has to move and its taking so long to move the objects (1000 objects in a day).
Would like to know if any other code or any other method to move the data faster. It helps if we have any other method to proceed.
Thank you !
Thanks for your reply. I think you need to fine-tune the utility. The whole 1 lakh+ should not take a day.
I may be able to help you to fine-tune it if you would like.
Regards
Ajit
Thank you!
Yes, would like to know the solution.
Please send me your utility.
We are passing the input like this :
object type, PDMLinkProduct , Target container, Target folder path, organization name
we have one separate utility to retrieve the objects. that utility will get the objects and feed input as mentioned above to this utility.
package ext.bdk.rest;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import com.ptc.windchill.enterprise.change2.commands.RelatedChangesQueryCommands;
import com.ptc.windchill.enterprise.part.commands.PartDocServiceCommand;
import com.ptc.windchill.uwgm.common.container.OrganizationHelper;
import wt.change2.ChangeHelper2;
import wt.change2.Changeable2;
import wt.change2.Complexity;
import wt.change2.VersionableChangeItem;
import wt.change2.WTChangeIssue;
import wt.change2.WTChangeOrder2;
import wt.change2.WTChangeRequest2;
import wt.dataops.containermove.ContainerMoveHelper;
import wt.enterprise.RevisionControlled;
import wt.epm.EPMDocument;
import wt.fc.ObjectReference;
import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.fc.WTObject;
import wt.fc.collections.WTArrayList;
import wt.fc.collections.WTCollection;
import wt.fc.collections.WTKeyedMap;
import wt.fc.collections.WTValuedHashMap;
import wt.fc.collections.WTValuedMap;
import wt.folder.Folder;
import wt.folder.FolderHelper;
import wt.folder.Foldered;
import wt.inf.container.WTContained;
import wt.inf.container.WTContainer;
import wt.inf.container.WTContainerHelper;
import wt.inf.container.WTContainerRef;
import wt.inf.library.WTLibrary;
import wt.lifecycle.State;
import wt.log4j.LogR;
import wt.maturity.PromotionNotice;
import wt.method.RemoteAccess;
import wt.method.RemoteMethodServer;
import wt.note.NoteHelper;
import wt.note.NoteHolderNoteLink;
import wt.org.WTOrganization;
import wt.part.WTPart;
import wt.part.WTPartHelper;
import wt.part.WTPartUsageLink;
import wt.pdmlink.PDMLinkProduct;
import wt.pds.StatementSpec;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.session.SessionServerHelper;
import wt.team.TeamHelper;
import wt.team.TeamTemplate;
import wt.team.TeamTemplateReference;
import wt.util.WTException;
import wt.vc.VersionControlHelper;
import wt.vc.Versioned;
import wt.vc.wip.WorkInProgressHelper;
import wt.vc.wip.Workable;
/**
* A Generic Utility Class to move objects from one container to another. This utility can read data from an input file, which will hold the details. Any folder resident object can
* be moved from one folder to another either within the same container or between different containers.
*
*/
public class SBDKMoveObjects implements RemoteAccess{
private static final Logger logger = LogR.getLogger(SBDKMoveObjects.class.getName());
/**
* The main method.
*
* @param args the arguments
* @throws Exception the exception
*/
/*
* public static void main(String args[]) throws Exception {
*
* String password = ""; if (args.length > 1) { String inputPath = args[0];
* RemoteMethodServer rms = RemoteMethodServer.getDefault();
* rms.setUserName(args[1]); try { File file = new
* File("E:\\output\\password1.txt"); BufferedReader br = new BufferedReader(new
* FileReader(file)); String listEntry; while ((listEntry = br.readLine()) !=
* null) { password = listEntry; } } catch (IOException e1) {
* System.out.println("password error"); e1.printStackTrace(); }
* rms.setPassword(password); // String processName = args[3]; try { Object obj
* = rms.invoke("processDataFromFile", SBDKMoveObjects.class.getName(), null,
* new Class[] { String.class }, new Object[] { inputPath });
* System.out.println(
* "*************************************************************************");
* System.out.println("Result: "); System.out.println("" + obj.toString());
* System.out.println(
* "*************************************************************************");
* System.out.
* println("Check log file 'SBDKMoveObjects.txt' at location: E:\\output\\MOOV_TOOL\\"
* ); System.out.println(
* "*************************************************************************");
* } catch (RemoteException | InvocationTargetException e) {
* logger.debug("Error occurred while invoking processDataFromFile method...");
* e.printStackTrace(); }
*
* }
*
*
* }
*/
public static String processDataFromFile(String inputFilePath) throws Exception {
//log(log, "NUMBER CONTAINER TYPE CONTAINER NAME ORGANIZATION NAME LOAD_STATUS ERROR_MESSAGE");
System.out.println("Inside processDataFromFile");
// log(log, "ACTION PRODUCT_TYPE COMPLEXITY ROLE PRINCIPAL LOAD_STATUS
// ERROR_MESSAGE");
int numberOfLines = 0;
int numberOfLinesSuccessfull = 0;
int numberOfLinesFailed = 0;
String returnMessage = "";
BufferedReader reader = null;
FileWriter fw = null;
BufferedWriter bw = null;
boolean acceessEnfored = SessionServerHelper.manager.setAccessEnforced(false);
try {
//File file = new File("E:\\input.txt");
File file = new File(inputFilePath);
File outputFile = new File("E:\\output\\MOVE_TOOL\\MoveObjects_status.txt");
if (!outputFile.exists()) {
outputFile.createNewFile();
}
fw = new FileWriter(outputFile);
bw = new BufferedWriter(fw);
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line = null;
while ((line = reader.readLine()) != null) {
if (line.trim().startsWith("#") || "".equals(line.trim())) {
continue;
}
WTValuedMap valuedMap = new WTValuedHashMap();
String[] details = line.trim().split("[{" + " " + "}]");
if (details.length != 6) {
int addTab = 5 - details.length;
for (int i = 0; i < addTab; i++) {
line += "\t";
}
}
if (details.length < 6) {
log(bw, line + "\tFAILED\tInput not in correct format");
numberOfLinesFailed++;
numberOfLines++;
continue;
}
String objectClass = details[0].trim();
String objectNumber = details[1].trim();
String containerType = details[2].trim();
String containerName = details[3].trim();
String folderLocation = details[4].trim();
String organizationName = details[5].trim();
Foldered foldered=null;
try {
if(objectClass.equalsIgnoreCase("wt.maturity.PromotionNotice")) {
foldered=getPromotionRequest(objectClass,objectNumber);
}else {
foldered = getFoldered(objectClass, objectNumber);
}
if (foldered == null) {
log(bw, objectNumber + "\tFAILED\tObject Not Found");
numberOfLinesFailed++;
numberOfLines++;
continue;
}
if (foldered instanceof Workable && (WorkInProgressHelper.isCheckedOut((Workable) foldered) || WorkInProgressHelper.isWorkingCopy((Workable) foldered))) {
log(bw, objectNumber + "\tFAILED\tThe object is checkedout");
numberOfLinesFailed++;
numberOfLines++;
continue;
}
//WTContainer container = containerMap.get(organizationName + ":" + containerType + ":" + containerName);
WTOrganization organization = OrganizationHelper.getOrganizationByName(organizationName);
if (organization == null) {
log(bw, objectNumber+"\tFAILED\tOrganization not Found");
numberOfLinesFailed++;
numberOfLines++;
continue;
}
WTContainer container = SBDKMoveHelper.getContainer(organization, containerType, containerName);
if (container == null) {
log(bw, objectNumber+"\tFAILED\t Product container not Found");
numberOfLinesFailed++;
numberOfLines++;
continue;
}
if(foldered instanceof WTContained && ((WTContained) foldered).getContainerName().equalsIgnoreCase(container.getName())) {
log(bw, objectNumber+"\tFAILED\t Object is already present in Target container");
numberOfLinesFailed++;
numberOfLines++;
continue;
}
// Moving part to target context.
WTContainerRef container_ref = WTContainerHelper.service.getByPath(
"/wt.inf.container.OrgContainer=Black and Decker - IPG/wt.pdmlink.PDMLinkProduct="
+ containerName);
Folder folder = SBDKMoveHelper.getFolderForGivenPath(container, folderLocation);
// code to create new folder if folder does not exist.
// code to move data at default location if input given folder is not exist.
if(folder==null) {
folder = FolderHelper.service.getFolder("/Default", container_ref);
System.out.println("got null folder..." + folder);
}
valuedMap.put(foldered, folder);
//System.out.println("Part: "+part.getVersionIdentifier().getValue()+"."+part.getIterationIdentifier().getValue());
/*
* if (foldered instanceof WTPart) {
* System.out.println("describe doc size: "+PartDocServiceCommand.
* getAssociatedDescribeDocuments((WTPart) foldered).size());
* System.out.println("ref doc size: "+PartDocServiceCommand.
* getAssociatedReferenceDocuments((WTPart) foldered).size());
* System.out.println("CR size: "+ChangeHelper2.service.
* getRelevantChangeRequests((WTPart) foldered).size());
* System.out.println("PR size: "+ChangeHelper2.service.
* getReportedAgainstChangeIssue((WTPart) foldered).size());
* System.out.println("Af CN size: "+RelatedChangesQueryCommands.
* getRelatedAffectingChangeNotices((WTPart) foldered).size());
* System.out.println("Resulting CN size: "+RelatedChangesQueryCommands.
* getRelatedResultingChangeNotices((WTPart) foldered).size());
* System.out.println("CAD size: "+PartDocServiceCommand.
* getAssociatedCADDocuments((WTPart) foldered).size());
* System.out.println("CAD1 size: "+WTPartHelper.service.getDescribedByDocuments
* ((WTPart) foldered).size()); }
*/ /*
* if (foldered instanceof WTPart) { valuedMap =
* SBDKMoveHelper.getAssociatedObjectInMap(PartDocServiceCommand.
* getAssociatedDescribeDocuments((WTPart) foldered), valuedMap, folder,
* container); valuedMap =
* SBDKMoveHelper.getAssociatedObjectInMap(PartDocServiceCommand.
* getAssociatedReferenceDocuments((WTPart) foldered), valuedMap, folder,
* container); if(PartDocServiceCommand.getAssociatedCADDocuments((WTPart)
* foldered).size()>0) { valuedMap =
* SBDKMoveHelper.getAssociatedObjectInMap(PartDocServiceCommand.
* getAssociatedCADDocuments((WTPart) foldered), valuedMap, folder, container);
* }else if(WTPartHelper.service.getDescribedByDocuments((WTPart)
* foldered).size()>0) { valuedMap =
* SBDKMoveHelper.getAssociatedObjectInMap(WTPartHelper.service.
* getDescribedByDocuments((WTPart) foldered), valuedMap, folder, container); }
*
* valuedMap = SBDKMoveHelper.getAssociatedObjectInMap(ChangeHelper2.service.
* getRelevantChangeRequests((WTPart) foldered), valuedMap, folder, container);
* valuedMap = SBDKMoveHelper.getAssociatedObjectInMap(ChangeHelper2.service.
* getReportedAgainstChangeIssue((WTPart) foldered), valuedMap, folder,
* container); valuedMap =
* SBDKMoveHelper.getAssociatedObjectInMap(RelatedChangesQueryCommands.
* getRelatedAffectingChangeNotices((WTPart) foldered), valuedMap, folder,
* container); valuedMap =
* SBDKMoveHelper.getAssociatedObjectInMap(RelatedChangesQueryCommands.
* getRelatedResultingChangeNotices((WTPart) foldered), valuedMap, folder,
* container); }
*/
// if (valuedMap.size() > 0) {
ContainerMoveHelper.service.moveAllVersions(valuedMap);
//}
log(bw, objectNumber+"\tSUCCESS\t"+"All objects are moved successfully to "+containerName+" context");
numberOfLinesSuccessfull++;
numberOfLines++;
// valuedMap.clear();
} catch (Exception e) {
e.printStackTrace();
log(bw, line + "\tFAILED\tERROR Processing line due to exception : " + e.getLocalizedMessage().replaceAll("[\\n\\r]+", "\\\\n"));
numberOfLinesFailed++;
numberOfLines++;
}
}
} catch (Exception ex) {
ex.printStackTrace();
log(bw, "Tool Ended unexpectedly, Check Method Server logs for more details : " + ex.getLocalizedMessage());
returnMessage += "Tool Ended unexpectedly, Check Method Server logs for more details";
numberOfLinesFailed++;
numberOfLines++;
} finally {
if (reader != null) {
reader.close();
}
SessionServerHelper.manager.setAccessEnforced(acceessEnfored);
}
returnMessage += "*** Total Number of Lines processed from Input file : " + numberOfLines;
returnMessage += "\n*** Number of Lines Succeeded : " + numberOfLinesSuccessfull;
returnMessage += "\n*** Number of Lines Failed : " + numberOfLinesFailed;
if (numberOfLinesFailed != 0) {
returnMessage += "\n*** Some of the Lines have not passed. Please see Error Logs for More Details.";
}
return returnMessage;
}
private static Foldered getPromotionRequest(String objectClass, String objectNumber) {
Class<?> objectClazz;
try {
objectClazz = Class.forName(objectClass);
QuerySpec spec = new QuerySpec(objectClazz);
spec.appendWhere(new SearchCondition(objectClazz, PromotionNotice.NUMBER, SearchCondition.EQUAL, objectNumber), new int[] { 0 });
QueryResult result = PersistenceHelper.manager.find((StatementSpec) spec);
while (result.hasMoreElements()) {
Foldered foldered = (Foldered) result.nextElement();
WTContainer container = WTContainerHelper.getContainerRef((WTContained) foldered).getReferencedContainer();
//System.out.println("foldered: "+foldered.getIdentity()+" container: "+container);
if (container instanceof PDMLinkProduct || container instanceof WTLibrary) {
return foldered;
}
}
} catch (WTException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* Method calculate engg version from mfg version
* @param WTPart tkp
* @return String version
*/
/*
* public String getEnggVersion(WTPart tkp) { String version = tkp.getVersionIdentifier().getValue(); version = version.substring(0, version.indexOf(".")); return version; }
*/
/**
* Method returns list of checkedout BOM or Notes for given part
* @param WTPart foldered
* @return Set foldered
* @throws WTException
*/
/**
* Gets the foldered object given the object class and object number. The object class should be a subclass of 'Foldered' class.
*
* @param objectClass the object class
* @param objectNumber the object number
* @return the foldered
* @throws Exception the exception
*/
public static Foldered getFoldered(String objectClass, String objectNumber) throws Exception {
Class<?> objectClazz = Class.forName(objectClass);
QuerySpec spec = new QuerySpec(objectClazz);
spec.appendWhere(new SearchCondition(objectClazz, "master>number", SearchCondition.EQUAL, objectNumber), new int[] { 0 });// Modified for I_4797 CCBGQB
QueryResult result = PersistenceHelper.manager.find((StatementSpec) spec);
while (result.hasMoreElements()) {
QueryResult result1 = VersionControlHelper.service.allVersionsOf((Versioned) result.nextElement());
//System.out.println("result1.size: "+result1.size());
if (result1.hasMoreElements()) {
Foldered foldered = (Foldered) result1.nextElement();
WTContainer container = WTContainerHelper.getContainerRef((WTContained) foldered).getReferencedContainer();
//System.out.println("foldered: "+foldered.getIdentity()+" container: "+container);
if (container instanceof PDMLinkProduct || container instanceof WTLibrary) {
return foldered;
}
}
}
return null;
}
/**
* This method logs the message that is passed to it.
*
* @param bw
* the bw
* @param msg
* the msg
*/
public synchronized static void log(BufferedWriter bw, String msg) {
try {
bw.write(msg + "\n");
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Hi @AG_10330040,
This is Bhushan from PTC Customization Technical Support.
Can you please elaborate if you are facing any specific problem with API or if you need any clarification on move object API usage?
Thanks for the suggestions, @AG_10330040 you can consider feedback here as well.
Hi @AG_10330040,
Kindly let us know if you are facing any issues or need assistance with Supported API usage.
Thanks,
Bhushan Dhamdhere
PTC Customization Technical Support
How often do you need to move files between contexts?
Is it really worth a custom app if it is a few times when it can be done manually very easily.
We would like to move the bulk amount of Data (1 lakh+).
Thank you!
When you move data it can retain the access permissions from the old context. There is an action "Reset Teams" that you might need to do so the permissions are correct.