進階自訂 > Services and Infrastructure Customization > Import Export Framework > How to Write Exp/Imp Handlers
  
How to Write Exp/Imp Handlers
Writing Export Handlers for the Export Process
To create an export handler for a class, one needs to know three things:
1. How to use XML files that contain handlers information.
2. How to update DTD files that contain information about objects that will be exported/imported.
3. How to write a handler.
XML files that contain handlers information
These XML files reside in the folder <Windchill>\codebase\registry\ixb\handlers. The whole folder is processed as the root element of XML tags, and the contents of XML files in this folder are processed as child elements. So, the XML files in this folder are not well formed, and they have contents similar to the following:
<classExporter>
<class>
[class name of the object that will be exported with full path name]
</class>
<dtd>
[String DTD, specifies where DTD for the class is stored]
</dtd>
<targetTag>default</targetTag>
<handler>
[class name of the handler that is used to export the object]
</handler>
</classExporter>
For example:
<classExporter>
<class>wt.part.WTPart</class>
<dtd>standardX20.dtd</dtd>
<targetTag>default</targetTag>
<handler>wt.ixb.handlers.forclasses.ExpImpForWTPart</handler>
</classExporter>
All handlers with the <dtd> tag “standard.dtd” are handlers for export object in Windchill Release 10.X.
For example:
<classExporter>
<class>wt.part.WTPart</class>
<dtd>standardX20.dtd</dtd>
<targetTag>default<targetTag>
<handler>wt.ixb.handlers.forclasses.ExpImpForWTPart60</handler>
</classExporter>
So we know that the class wt.ixb.handlers.forclasses.ExpImpForWTPart is a handler for exporting the class wt.part.WTPart in Windchill Release 10.X format.
The class IxbHandlersManager contains all necessary methods to manipulate handlers.
DTD Files
In the folder <Windchill>\codebase\registry\ixb\dtds\standardX20.dtd there is a file named coreobjects.dtd that is the DTD file for all objects that will be exported/imported.
How to Write a Class Export Handler
1. Create a Class that extends ClassExporterImporterTemplate
2. Implement exportAttributes(Object obj, Exporter exp) method, which retrieves the data from the object and adds it to the XML DOM Document. The following is an example of this method for the object of “MyClass”:
public void exportAttributes (Object object, Exporter exporter) throws WTException {
try {

MyClass ob = (MyClass)object;
// export the local id
IxbHndHelper.exportAttribute(
ExpImpForLocalIdAttr.class, ob, fileXML, exporter);
// export other attributes that are specific to
// MyObject; e.g. name, number
IxbHndHelper.exportAttribute(
ExpImpForMyObjectAttr.class, ob, fileXML, exporter);
// export version information
IxbHndHelper.exportAttribute(
ExpImpForVersionAttr.class, ob, fileXML, exporter);
// export content
IxbHndHelper.exportAttribute(
ExpImpForContentAttr.class, ob, fileXML, exporter);

}
catch (Exception e) {
LogHelper.devExc ( e,
"exportAttributes: could not export
object=<"+object+">");
}
}
3. Override getRootTag() method, which returns the desired root tag for the object type to be exported. The following is an example of this method for the object of “MyClass”:
protected String getRootTag() {
return "MyClass";
}
4. Add an entry in the handlers XML file (<Windchill>\registry\ixb\handlers\coreX10.dtd) that specifies the class being exported (com.mycompany.MyObject), the XML DTD for core Windchill objects (standardX20.dtd), and the handler for the class (wt.ixb.handlers.forclasses.ExpImpForMyObject). An example entry follows:
<classExporter>
<class>com.mycompany.MyObject</class>
<dtd>standardX20.dtd</dtd>
<targetTag>default</target>
<handler>wt.ixb.handlers.forclasses.ExpImpForMyObject</handler>
</classExporter>
How to Write an Attribute Export Handler
If there is an attribute that is required to be exported the same way for different classes or if you simply decide to handle it is a separate handler, you can create an attribute handler. The steps to follow are:
1. Create a Java class extending AttrExporterImporterTemplate.
2. Implement exportAttribute(Object ob,IxbElement fileXML, Exporter exporter) method, which retrieves the attribute data from the object and adds it to the XML DOM Document. The following is an example of this method for the object “MyObject”. This method gets the part type and the part source of the object.
public void exportAttribute (
Object obj,
IxbElement fileXML,
Exporter exporter) throws WTException {
try {
MyClass ob = (MyClass) obj;
LocalizableMessage localMessage1 = ob.getDisplayType();
Locale locale1 = new Locale("English", "US");
String dispType = localMessage1.getLocalizedMessage(locale1);
fileXML.addValue(IxbHndHelper.XML_ATTR_PARTTYPE, dispType);
fileXML.addValue(
IxbHndHelper.XML_ATTR_SOURCE,ob.getSource ().toString() );
}
catch (Exception e) {
LogHelper.devExc (e,
"Exception in ExpImpForLTPartAttr, ob=<"+obj+">");
}
}
3. After adding this, the export handler for class may call this method to have the part attribute exported.
How to Write Handlers for the Import Process
To create import handlers for a class, there are two things to know:
1. XML files that contain handlers information.
2. How to write a handler.
XML files that contain handlers information
These XML files are in the folder <Windchill>\codebase\registry\ixb\handlers.
The whole folder is processed as the root element of XML tags, and the contents of XML files in this folder are processed as child elements. So the XML files in this folder are not well formed, and their contents are similar to the following:
<elementImporter>
<tag>
[class name of the object that will be imported without full path name ]
</tag>
<dtd>
[String DTD, specifies where DTD for the class is stored]
</dtd>
<handler>
[class name of the handler that is used to import the object]
</handler>
</elementImporter>
For example:
<elementImporter>
<tag>WTPart</tag>
<dtd>standardX20.dtd</dtd>
<handler>wt.ixb.handlers.forclasses.ExpImpForWTPart</handler>
</elementImporter>
All handlers with the <dtd> tag “standardX20.dtd” are handlers for import object in Windchill Release 10.X.
For example::
<elementImporter>
<tag>WTPart</tag>
<dtd>standardX20.dtd</dtd>
<handler>wt.ixb.handlers.forclasses.ExpImpForWTPart</handler>
</elementImporter>
So we know that the class wt.ixb.handlers.forclasses.ExpImpForWTPart is handler for import of the class wt.part.WTPart in Windchill Release 10.X.
The class IxbHandlersManager contains all methods to manipulate handlers.
How to Write a Class (Element) Import Handler
Import handlers for classes can be divided in to two types:
Import handlers for versioned objects.
Import handlers for non-versioned objects.
Handler for Non-Versioned Object
1. Create a Java class that extends ClassExporterImporterTemplate
2. Implement method: public Object createObject (IxbElement fileXML, Importer importer)
3. Override the following methods if necessary:
public Object importObjectsAttributes ( List<ElementObjectpair> pairs,
Importer importer);
public ObjectstoreObjects (
List<ElementObjectPair> pairs,
Importer importer);
public Object,importObjectsAttributesAfterStore(
List<ElementObjectPair> pairs,
Importer importer);
public Object findAmongExistingObjectsInternal (IxbElement fileXML,
Importer importer);
* 
An object is imported by the following sequence: createObject(), importObjectsAttributes(), storeObjects(), importObjectsAttributesAfterStore().
createObject(): if the object doesn’t exist in database (is not found by findAmongExistingObjects), it will be created, and all the Ufid attribute of the object is imported.
importObjectsAttributes(): import all attributes of the object storeObjects(): the method storeObjects() will call to PersistenceHelper.manager.store().
importObjectsAttributesAfterStore() imports all attributes that must be imported after the object is stored.
4. Add an entry to the handlers registry file (<Windchill>\registry\ixb\handlers\coreX10). The entry specifies the class being imported (MyObject), XML DTD for core Windchill objects (standardX20.dtd), and the handler for the class com.ptc.mypackage.ExpImpForMyObject. An example entry follows:
<elementImporter>
<tag>MyObject</tag>
<dtd>standardX20.dtd</dtd>
<handler>com.ptc.mypackage.ExpImpForMyObject</handler>
</ elementImporter >
Handler for Link Object
1. Create a Java class that extends ExpImpForLinkObject.
2. Implement method: public Object createObject (IxbElement fileXML, Importer importer)
3. Override the following methods:
protected abstract Class getLinkClass();
protected abstract String getLinkRoleATag();
protected abstract String getLinkRoleBTag();
protected abstract LinkStoreOwnershipType getLinkStoreOwnershipType();
protected abstract Persistable getRoleAObject(IxbElement, Importer);
protected abstract Persistable getRoleAObject(IxbElement, Importer);
protected abstract Object createLinkObject(IxbElement, Importer,
Persistable roleAObj, Persistable roleBObj);
4. Override following methods if necessary.
public Object importObjectAttributes ( Object ob,
IxbElement fileXML,
Importer importer);
public Object storeObjects (List<ElementObjectPair> elements,
Importer importer);
public Object importObjectAttributesAfterStore(IxbElement fileXML,
Importer importer);
public Object findAmongExistingObjectsInternal (IxbElement fileXML,
Importer importer);
Import handlers for non-versioned objects (Link objects) are quite straightforward, and any of the following classes can be referred as example:
ExpImpForWTPartDescribeLink
ExpImpForWTPartReferenceLink
Handler for Versioned Object
1. Create a Java class that extends ExpImpVersionedObject
2. Implement the following methods:
public List<IxbHndHelper.ElementObjectPair> getMasters(Collection<IxbElement>, Importer, WTcontainerRef) : returns the list of ElementObjectPair if there is any version of the importing object/s in the database.
3. Override the following methods if necessary:
public Object importObjectsAttributes ( List<IxbHndHelper.ElementObjectPair>,
Importer importer);
public Object importObjectsAttributesAfterStore(
List<IxbHndHelper.ElementObjectPair>,
Importer importer);
public Object findAmongExistingObjectsInternal (
IxbElement fileXML,,Importer importer);
* 
An object is imported by the following sequence: createObject(), importObjectAttributes(), storeObjects(), importObjectAttributesAfterStore().
createObject()
This method is implemented in the class ExpImpForVersionedObject. The creation of objects will be delegated to Actor classes, depends on the actor name in the XML file (The actor name is writen into the XML file by import application). Particular object handlers don’t have to worry about createObject() and Actor.
importObjectAttributes()
Import all attributes of the object that can be imported before the object is stored.
storeObject()
This method is implemented in the class ExpImpForVersionedObject. The store of objects will be delegated to Actor classes, depends on the actor name in the XML file (The actor name is writen into the XML file by import application). Particular object handlers don’t have to worry about storeObject() and Actor.
importObjectAttributesAfterStore()
Import all attributes of the object that must be imported after the object is stored
ExpImpForWTPart, ExpImpForDocument, ExpImpForEPMDocument are examples of import handlers for versioned objects.
4. Add an entry to the handlers registry file (<Windchill>\registry\ixb\handlers\coreX10.xml). The entry specifies the class being imported (MyObject), XML DTD for core Windchill objects (standardX20.dtd ), and the handler for the class com.ptc.mypackage.ExpImpForMyObject. An example entry follows:
<elementImporter>
<tag>MyObject</tag>
<dtd>standardX20.dtd</dtd>
<handler>com.ptc.mypackage.ExpImpForMyObject</handler>
</ elementImporter >
How to Write an Attribute Import Handler
If there is an attribute that is required to be imported the same way for different classes or if you simply decide to handle it is a separate handler, you can create an attribute handler. The steps to follow are:
1. Create a Java class that extends AttrExporterImporterTemplate.
2. Override the following methods if needed:
prepareForCheckConflicts(Importer importer): prepares for conflict checking. It is likely never be implemented by a particular handler.
checkConflictForAttribute( Object existingOb, IxbElement fileXML, Importer importer) : This method does the conflict checking for particular attribute, so if the imported attribute can potentially have conflicts with an attribute that exists in the database, this method must be overridden.
importAttribute ( Object object,

IxbElement fileXML,

Importer importer):
Retrieves the attribute data from the XML DOM Document and set it to the imported object. This method must be overridden to suit particular attribute.
Here is an example for importAttribute() for the attribute MyAttr to the object MyObject:
public Object importAttribute
( Object object,
IxbElement fileXML,
Importer importer)
throws WTException {
String myAttr;
try{
myAttr = fileXML.getValue(IxbHndHelper.XML_ATTR_MYATTR);
// XML_ATTR_MYATTR tag must be defined in IxbHndHelper
}
catch (Exception exc){
// The paragraph bellows allows the import process continue,
// even when the import of MyAttr fails. If the programmer
// wants the import process to stop when the import of
// MyAttr fails, please assign ob=null and throw exception
System.out.println(
"Exception when getting MyAttr in importAttribute");
System.out.println("MyAttr attribute is not imported");
return object;
}

MyObject ob = (MyObject) object;
try {
MyObjectHelper.service.setMyAttr(ob, myAttr);
}
catch (Exception e) {
if (! importer.
attributeExporterImporterManager.
overrideConflicts) {
ob = null;
throw e;
}
else{
// override the conflict by doing something here…
}
}
finally{
return ob;
}
Multi Threading Considerations
Starting in Windchill 10.2 M010, you can export and import Windchill package delivery files using multiple threads. Multiple threads provide one option that may be used to optimize performance. The use of multiple threads for the export of Windchill package delivery files is controlled using the wt.ixb.export.maxThreads property. The use of multiple threads for the import of Windchill received delivery files is controlled using the wt.ixb.import.maxThreads property.
Multi Thread Properties
* 
The import multithreading property only applies to import of a received delivery for importable packages.
Property
Description
wt.ixb.import.batchSize
Sets the batch size for a thread.
Batch size has lower impact on received delivery import performance. The property can be set to determine the number of objects in each import batch. By default, this property is set to 10000.
wt.ixb.import.maxThreads
Number of threads for import. The job list will be distributed over the number of threads you define.
Using multiple threads has the most significant impact on received delivery import performance. The threads share the same database connection, which can impact performance if the threshold is reached. The number of objects can also impact performance; the greater the number or objects, the greater the performance improvement when using multiple threads. In general, one thread will be sufficient for incremental package deliveries. An initial package delivery may benefit from multiple threads, particularly if the import time window is small. When importing CAD objects, this property must be set to 1. By default, this property is set to 1.
* 
The value of the wt.ixb.import.maxThreads property is used in conjunction with the wt.ixb.import.noOfParallelImportPaths property, which determines the number of transactions used for import.
Single Transaction Scenario: If the wt.ixb.import.noOfParallelImportPaths property is set to 1, the value of the wt.ixb.import.maxThreads property is the total number of threads used for import.
Multiple Transaction Scenario: If the value of the wt.ixb.import.noOfParallelImportPaths is set to more than 1, the value of the wt.ixb.import.maxThreads property is the number of threads used per import transaction.
wt.ixb.import.objPerThreadGuidance
Sets the number of objects included in each thread.
wt.ixb.export.maxThreads
Sets the maximum number of threads used for export. If there are fewer objects, the number of threads decreases accordingly. The recommended number is two.
wt.ixb.export.objPerThreadGuidance
Sets the number of objects included in each thread.
Related Documentation
For more information about this and other available properties that can affect Windchill package delivery file export performance, see Best Practices for Working with Packages. For more information about properties related to Windchill received delivery import performance, see Best Practices for Working with Received Deliveries.