Customization
Dispatcher: TaskPrep and DatabaseOperation
These are the two Dispatcher Client classes that own the Teamcenter side of a translation. Together they are the "extract-transform-load" model the admin guide refers to.
| Class | Runs at state | Owns |
|---|---|---|
TaskPrep |
PREPARING |
What comes out of Teamcenter and onto the staging directory |
DatabaseOperation |
LOADING |
What goes back into Teamcenter and how it is related |
Before writing either, check whether the preference-driven generic implementations already cover your case. See Zero-Java custom translator.
Binding
In DispatcherClient/conf/Service.properties:
Translator.<provider>.<service>.Prepare=<your package>.TaskPrep
Translator.<provider>.<service>.Load=<your package>.DatabaseOperation
Provider and service must exactly match the provider and service attributes
of the translator's block in the Module's translator.xml. The recommended
package convention from the guide is
<your path>.translator.<provider name>.<translator name>.
Note from the shipped Service.properties: direct translators do not use
these classes at all. SIEMENS.ugtopvdirect and friends store results in
Teamcenter themselves, so they specify no Load class and configure their file
mapping in PostProcessor.xml instead. If you are extending a *direct
translator you are in a different mechanism.
There is a third optional binding, FileMap, used by the Loader to match
translator output files back to source data.
TaskPrep
Extend com.teamcenter.ets.extract.DefaultTaskPrep and override
prepareTask(). Its job, per the shipped javadoc:
- Validate that all data necessary to translate the primary objects is available. Primary objects that are data-incomplete should be excluded with appropriate logging rather than failing the whole task.
- Collect all input files and build a
TranslationTaskobject.
The shipped proetojt example, annotated
package com.teamcenter.ets.translator.ugs.proetojt;
import com.teamcenter.ets.extract.DefaultTaskPrep;
import com.teamcenter.ets.request.TranslationRequest;
import com.teamcenter.soa.client.model.strong.Dataset;
import com.teamcenter.soa.client.model.strong.ImanFile;
import com.teamcenter.soa.client.model.strong.ItemRevision;
import com.teamcenter.translationservice.task.TranslationTask;
public class TaskPrep extends DefaultTaskPrep
{
public TranslationTask prepareTask() throws Exception
{
m_scSourceFileExt = ".prt";
TranslationTask zTransTask = new TranslationTask();
ModelObject primary_objs[] = request.getPropertyObject(
TranslationRequest.PRIMARY_OBJS ).getModelObjectArrayValue();
ModelObject secondary_objs[] = request.getPropertyObject(
TranslationRequest.SECONDARY_OBJS ).getModelObjectArrayValue();
for (int i = 0; i < primary_objs.length; i++)
{
Dataset dataset = (Dataset) primary_objs[i];
if (!dataset.getTypeObject().getName().equalsIgnoreCase("ProPrt"))
continue; // skip, do not fail the task
ItemRevision itemRev = (ItemRevision) secondary_objs[i];
// walk named references to find the one with the right extension
ModelObject[] contexts = dataset.get_ref_list();
ImanFile zIFile = null;
for (int j = 0; j < contexts.length; j++) { /* match .prt */ }
if (zIFile == null)
throw new Exception("No named reference found for "
+ dataset.get_object_string());
File zFile = TranslationRequest.getFileToStaging(zIFile, stagingLoc);
// sanitize, rename in staging, then register with the task
zTransTask = prepTransTask(zTransTask, dataset, itemRev,
exportFilename, true, true, ".jt", 0, null);
}
return addRefIdToTask(zTransTask, 0);
}
}
Points worth carrying forward:
- It uses the SOA strong client model (
Dataset,ItemRevision,ImanFile), not ITK. Same object model you would use from any SOA client. primary_objs[i]andsecondary_objs[i]are index-paired. Primary is the dataset, secondary is its item revision.- Non-matching primaries are
continued, not thrown on. A missing named reference is thrown on. That asymmetry is deliberate: wrong type is a no-op, malformed data is an error. TranslationRequest.getFileToStaging()is the volume-to-disk extraction primitive.prepTransTask()andaddRefIdToTask()are the inherited builders. You rarely constructTranslationTaskmembers by hand.- Filename sanitizing happens before translation specifically so that source-to-result file mapping still matches afterwards. If your translator rewrites names, sanitize on the way out or the load will fail to map.
Registry.getRegistry("...proetojt.proetojt")loads a siblingproetojt.propertiesfile, which is how per-translator tunables (here,TaskPrep.BadChars) stay out of the code.
DatabaseOperation
Extend com.teamcenter.ets.load.DefaultDatabaseOperation and override load()
at minimum.
package com.teamcenter.ets.translator.ugs.proetojt;
import com.teamcenter.ets.load.DefaultDatabaseOperation;
import com.teamcenter.ets.util.DataSetHelper;
import com.teamcenter.translationservice.task.TranslationDBMapInfo;
public class DatabaseOperation extends DefaultDatabaseOperation
{
protected void load( TranslationDBMapInfo zDbMapInfo, List<String> zFileList )
throws Exception
{
String type = sourceDataset.get_dataset_type().get_datasettype_name();
if ( type.equals("ProPrt") ) loadPart( zFileList );
}
protected void loadPart( List<String> zFileList ) throws Exception
{
zDtSetHelper.createInsertDataset( sourceItemRev,
sourceDataset,
DataSetHelper.TC_DS_TYPE_DIRECT_MODEL,
DataSetHelper.TC_REL_TYPE_RENDERING,
DataSetHelper.TC_NR_TYPE_JT_PART,
m_scResultDir,
zFileList,
false );
}
}
DataSetHelper.createInsertDataset() is the workhorse. Its signature is the
whole load contract:
| Argument | Meaning |
|---|---|
sourceItemRev |
What the new dataset gets related to |
sourceDataset |
The source, for update-in-place cases |
| dataset type | e.g. TC_DS_TYPE_DIRECT_MODEL |
| relation type | e.g. TC_REL_TYPE_RENDERING (IMAN_Rendering) |
| named reference type | e.g. TC_NR_TYPE_JT_PART |
m_scResultDir |
Where the translator wrote its output |
zFileList |
The mapped files |
| replace flag | Whether to replace existing visualization data |
Inherited protected fields available to you: sourceDataset, sourceItemRev,
zDtSetHelper, m_scResultDir, m_zTaskLogger. The replace behavior is also
governed by the UpdateExistingVisualizationData service property, read by the
abstract base.
Notice this class dispatches on sourceDataset type. That branch is exactly
what the preference-driven generic implementation cannot do, and is the clearest
signal that you have genuinely outgrown level 0.
Build and package
From the admin guide:
javac -classpath <classpath created by runDispatcherClient.bat/sh> myFile.java
In practice: put every jar in DispatcherClient/lib on the classpath.
Then create TS<Translator name>Service.properties carrying your integration
keys, and jar it together with the classes, with the properties file at the
jar root:
jar cf mytranslator.jar MyTaskPrep.class MyDatabaseOperation.class TS<Translator>Service.properties
Copy the jar to DispatcherClient/lib and edit Service.properties to import
your TS<Translator name>Service.properties.
Preferences still matter
Even at this level you import a preference bundle. Use
DispatcherClient/install/basic_env.xml and ets_env.xml as the reference for
what preferences exist, put yours in <Translator name>_env.xml under
DispatcherClient/install/, and import with preferences_manager:
preferences_manager -u=<user> -p=<password> -g=dba -mode=import -scope=SITE -action=override -context=Teamcenter -file=<your_XML_file>
One site preference called out explicitly:
ETS_trans_rqst_referenced_dataset_types. Adding a dataset type here allows
a Dispatcher request to be cancelled and its primary objects deleted while the
translation is still in process. If you are adding a new primary dataset type,
this is the preference that governs whether users can back out mid-flight.
Shipped reference files
DispatcherClient/sample/integration/translators/
DefaultTaskPrep.java (17 KB — read this one)
DefaultDatabaseOperation.java ( 9 KB)
proetojt/TaskPrep.java
proetojt/DatabaseOperation.java
proetojt/proetojt.properties
ppttopdf/ (the zero-Java route)
DispatcherClient/sample/integration/filters/TranslatorFilter.java
DispatcherClient/docs/dc/javadoc/index.html
Packages in the client javadoc: com.teamcenter.ets.extract,
com.teamcenter.ets.load, com.teamcenter.ets.request,
com.teamcenter.ets.soa, com.teamcenter.ets.translator,
com.teamcenter.ets.util.
Source: DispatcherClient/sample/integration/translators/ (shipped SDK); admin guide ch. 7 · retrieved 2026-08-03