TeamcenterKnowledge

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 TranslationTask object.

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] and secondary_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() and addRefIdToTask() are the inherited builders. You rarely construct TranslationTask members 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 sibling proetojt.properties file, 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