Skip Ribbon Commands
Skip to main content
Navigate Up
Sign In

Quick Launch

Average Rating:

facebook Twitter
Email
Print Bookmark Alert me when this article is updated

Feedback

PowerCenter Custom Transformation Guide
Content

Custom transformations can be used to develop new types of transformations outside of the Designer interface to extend PowerCenter functionality. The following types of Custom transformations can be created:

  • Plug-In XML: The plug-in XML is used to register the transformation in the PowerCenter repository.
  • Client DLL: The client DLL is used to display the transformation in the PowerCenter client.
  • Server DLL: The server DLL (or shared library) is used to execute the transformation when running the PowerCenter session.

Plug-In XML

The following are the components of a plug-in XML PowerCenter Custom transformation:

Transformation Name, Component Version and Description

These fields will be registered in the repository and will appear in the PowerCenter Designer and Repository Administration Console.
The ID of the Custom transformation should be unique across all the plug-ins supported by Informatica. This will be generated on demand by the product management.

<TEMPLATETYPE="CUSTOMTRANSFORMATIONTEMPLATE"
ID="909001"
NAME="Looping"

Server run time library information

The DLL (library) is created for the server to do the required transformation logic for each platform and the transformation type and scope must be specified:

<TEMPLATEATTRIBUTENAME="Module Identifier" VALUE="pmloopingtrans"ISCLIENTEDITABLE = "NO"/>
<TEMPLATEATTRIBUTE NAME="Function Identifier "VALUE="pmloopingfunc" ISCLIENTEDITABLE = "NO"/>
<TEMPLATEATTRIBUTE NAME="Transformation Scope" VALUE="Row "ISCLIENTEDITABLE = "NO"/>

Client library

This is added to the registry. This library is loaded when Designer is launched.

<LIBRARY NAME ="pmloopingtransform" OSTYPE = "NT" TYPE = "CLIENT" />

Validation libraries for each operating system

This is optional, if the transformation does not support all platforms.

<LIBRARY NAME ="pmloopingvldn.dll" OSTYPE = "NT" TYPE = "VALIDATION" />
<LIBRARY NAME = "libpmloopingvldn.sl" OSTYPE = "HPUX" TYPE ="VALIDATION" />

Metadata Definitions

Metadata for the transformation can be specified in the Designer. It is saved to the repository when the user is finished editing the transformation.

<MEDEFINITION
NAME ="StartTime" TEMPLATEID="909002" DATATYPE = "STRING" MAXLENGTH ="2147483647"
OBJECTTYPE = "Custom Transformation" DESCRIPTION = "Metadata for Looping transformation"
ISSHAREREAD = "YES" ISSHAREWRITE = "YES" ISCLIENTVISIBLE = "NO" ISCLIENTEDITABLE = "NO" />

The pmloopingplugin.xml file

<?xml version="1.0" encoding="us-ascii"?>
<!DOCTYPE POWERMART SYSTEM "plugin.dtd">
<POWERMART>
<REPOSITORY CODEPAGE ="us-ascii">
<PLUGIN NAME="looping" ID="909000" VENDORNAME ="Informatica" VENDORID="1"
DESCRIPTION ="looping Transformation" VERSION ="7.1.1">
<MEDOMAIN
NAME="Looping_transformation" ID = "909002" DESCRIPTION ="Loopingtransformation"
CLIENTVISIBLE = "NO" COMPONENTVERSION = "1.0.0">
<MEDEFINITION
NAME = "StartTime" TEMPLATEID="909002" DATATYPE = "STRING"MAXLENGTH ="2147483647"
OBJECTTYPE = "Custom Transformation" DESCRIPTION = "Metadata for Looping transformation"
ISSHAREREAD = "YES" ISSHAREWRITE = "YES" ISCLIENTVISIBLE = "NO" ISCLIENTEDITABLE = "NO" />
NAME = "EndTime" TEMPLATEID="909002" DATATYPE = "STRING" MAXLENGTH= "2147483647"
OBJECTTYPE = "Custom Transformation" DESCRIPTION = "Metadata for Looping transformation"
ISSHAREREAD = "YES" ISSHAREWRITE = "YES" ISCLIENTVISIBLE = "NO" ISCLIENTEDITABLE = "NO" />
<MEDEFINITION
NAME = "LoopingVar" TEMPLATEID="909002" DATATYPE = "STRING"MAXLENGTH = "2147483647"
OBJECTTYPE = "Custom Transformation" DESCRIPTION = "Method for Httptransformation"
ISSHAREREAD = "YES" ISSHAREWRITE = "YES" ISCLIENTVISIBLE = "NO" ISCLIENTEDITABLE = "NO" />
</MEDOMAIN>
<TEMPLATE TYPE="CUSTOMTRANSFORMATIONTEMPLATE"
ID="909001"
NAME="Looping Transformation"
COMPONENTVERSION="1.0.0"
DESCRIPTION="Looping Transformation">
<TEMPLATEATTRIBUTE NAME="Module Identifier"VALUE="pmloopingtrans" ISCLIENTEDITABLE = "NO"/>
<TEMPLATEATTRIBUTE NAME="Function Identifier"VALUE="pmloopingfunc" ISCLIENTEDITABLE = "NO"/>
<TEMPLATEATTRIBUTE NAME="Is Partitionable" VALUE="YES"ISCLIENTEDITABLE = "NO"/>
<TEMPLATEATTRIBUTE NAME="Inputs Must Block" VALUE="NO"ISCLIENTEDITABLE = "NO"/>
<TEMPLATEATTRIBUTE NAME="Is Active" VALUE="YES"ISCLIENTEDITABLE = "NO"/>
<TEMPLATEATTRIBUTE NAME="Transformation Scope" VALUE="Row"ISCLIENTEDITABLE = "NO"/>
<TEMPLATEATTRIBUTE NAME="Generate Transaction" VALUE="YES"ISCLIENTEDITABLE = "NO"/>
<TEMPLATEATTRIBUTE NAME="Output Is Repeatable"VALUE="Never" ISCLIENTEDITABLE = "NO"/>
<TEMPLATEATTRIBUTE NAME="Update Strategy Transformation"VALUE="NO" ISCLIENTEDITABLE ="NO"/>
<LIBRARY NAME = "ctloopingtransformation" OSTYPE ="NT" TYPE = "CLIENT"/>
</TEMPLATE>
</PLUGIN>
</REPOSITORY>
</POWERMART>

Client Plug-In DLL

You can also create a reusable custom transformation client plug-in as a native transformation. This transformation uses icons on the menu item in the same way the other native transformations (such as a Sorter or Union transformation). You can bind this shared library or DLL to create a wizard for the new transformation.

The following is an example of how to implement a client plug-in PowerCenter Custom transformation:

Client Plug-in:

  1. Start Visual C++.
  2. Choose File >Add New .
  3. In the New dialog box, select the Projects tab and select the MFC AppWizard(dll) option.
  4. Enter the project's location.
  5. Enter the name of the project.
    You must use the module name specified for the Custom transformation as the project name.
    For this example, enter "LoopingTrans".
  6. Click OK .
  7. In the wizard, select Regular DLL Using Shared MFC DLL and click Finish .
  8. Click Finish in the MFC App Wizard dialog box.

Visual C++ creates the project files in the directory you specified.

  1. Choose Build > Build <module_name>.dll or press F7 to build the project.
    Visual C++ creates the DLL and places it in the debug or release directory under the project directory.

Build Resource Module:

Create a new CPP file ( loopingPlugin.cpp ) and implement the following Global functions:

  1. Right click on the CT Looping transformation workspace and add new project to this workspace.
  2. In the New dialog box, click the Projects tab and select the MFC AppWizard(dll) option.
  3. Enter the location and name of the project.
  4. In the wizard, select regular DLL using shared MFC DLL and click Finish .
  5. Click Finish in the MFC app wizard dialog box.
    Visual C++ creates the project files in the directory you specified.
  6. Go to the Resource view.
  7. Add a new dialogue to the project.
  8. Generate property pages for the new dialogue, and add new pages to the Plug-in dll.
  9. Build the resource module.

Client Plug-in workspace and Resource module:

/** LTPlugin.cpp:Plug-In for Looping Transformation Plug-in */
#include "resource.h"
#include "LTPlugin.hpp"
#include "LTResource409/LoopingPropPage.h"
/**
** Initialize LTplugin: static (Statndard way ofdoing)
*/
static LTPlugin _theLTPlugin;
/**
** Entry function for getting the version information about thisplugin
*/
extern "C" ISTATUS __declspec(dllexport)getClientPluginVersion
(const IVersion* pClientVersion, IVersion*pPluginVersion)
{
pClientVersion;
returnpPluginVersion->setVersion(SDKCOMPTVERSION);
}
/**
** Entry function for getting the description about thisplugin
*/
extern "C" void __declspec(dllexport)getClientPluginDescription(IPluginDescription&pluginDescription)
{
_theLTPlugin.getPluginDescription(pluginDescription);
}
/**
** The entry point into this DLL. Route all messages to theplugin.
*/
extern "C" int __declspec(dllexport)pluginNotificationHandler(PMCPLUGIN_MSG &msg)
{
return _theLTPlugin.handleMessage(msg);
}
/**
** Need to provide plugin name, and icons to show ontransformations to show
** on different widgets.
** IDB_TOOLBAR -- 16 X 16
** IDB_LARGE -- 32 X 32
** IDB_SMALL -- 16 X 16
*/
extern "C" void __declspec(dllexport) getSupportedTransformations(IVector<ITransformationInfo*> *pTransList )
{
IASSERT(pTransList);
ITransformationInfo* pInfo = newITransformationInfo;
pInfo->m_displayName = LT_PLUGIN_NAME;
pInfo->m_idToolbarIcon = IDB_TOOLBAR;
pInfo->m_idLargeIcon = IDB_LARGE;
pInfo->m_idSmallIcon =IDB_SMALL;
pInfo->m_transformationID =LT_TEMPLATE_ID;
pInfo->m_version = 1;
pTransList->insert(pInfo);
}
/**
** Initialize plugin and plugin message handler with plugin nameand vendor name
*/
LTPlugin::LTPlugin() : DPluginMsgHandler(PLUGINVERSION,
PLUGINFULLNAME,
PLUGINSHORTNAME,
VENDORNAME)
{
m_hResourceDll = NULL;
m_pWidget = NULL;
}
LTPlugin::~LTPlugin()
{}

/**
** DPluginMsgHandler Overrides
** Function name: onLoadPlugin
** Description : Called oncejust after the plugin is loaded
*/
IINT32 LTPlugin::onLoadPlugin(IUINT32 /*uAppId*/,IUINT32/*uInstallType*/,
LCID resourceLangId)
{
// this loads resourcefileprefix409.dll for english elseloads based on
// resource lang id.
m_hResourceDll =DPluginMsgHandler::loadResourceModule(resourceLangId,
"LTResource");
if ( m_hResourceDll == NULL )
{
// try loading theenglish resource as the default resource
m_hResourceDll =DPluginMsgHandler::loadResourceModule(DEFAULT_UI_LANG,
"LTResource");
if(!m_hResourceDll)
return PMCPLUGIN_FAILURE;
}
// set resource handle to handle messages andother user created widgets.
setResourceHandle(m_hResourceDll);
return PMCPLUGIN_CONTINUE;
}

/**
** Description : Called once justafter the plugin is unloaded
*/
IINT32 LTPlugin::onUnloadPlugin()
{
// free resource dll
::FreeLibrary(m_hResourceDll);
m_hResourceDll = NULL;
return PMCPLUGIN_CONTINUE;
}

/**
** Description: Try doing drag
**drop of fields without this.. it wont work :-)
*/
IINT32 LTPlugin::onGetSupportedDBTypes(IVector<IUINT32>*pDBTypeList)
{
pDBTypeList->insert(DBTYP_LT);
return PMCPLUGIN_CONTINUE;
}

IINT32 LTPlugin::onUpdateMenuItem(UINT uCommandId, CCmdUI*pCmdUI)
{
return PMCPLUGIN_CONTINUE;
}
/**
** add new widgets to this plugin. add resource and widget tostd transformation
** widget.
*/
IINT32 LTPlugin::onExtendEditor(IObject *pObject, IPMCEditor*pEditor,
enumPMCEDITOR /*editorType*/)
{
IASSERT(pObject);
IASSERT(pEditor);
IMultiGroupExtProcWidget* pWidget = NULL;
IMultiGroupExtProcWidgetInstance* pWidgetInst =NULL;
// The pObject input arguement is a widgetinstead of a widget instance
// in mapping designer if the widget isnon-reusable.
pObject = pEditor->getObject();
switch(pObject->getObjectType())
{
case IObject::eMULTIGROUPEXTPROCWIDGET:
pWidget =(IMultiGroupExtProcWidget*) pObject;
break;
case IObject::eMULTIGROUPEXTPROCWIDGETINSTANCE:
pWidgetInst =(IMultiGroupExtProcWidgetInstance*) pObject;
pWidget =(IMultiGroupExtProcWidget*) pWidgetInst->getTable();
break;
default:
// Not MGEP
return ignoreMessage();
}
IUINT32 templateId = 0;
pWidget->getTemplateID(templateId);
if ( templateId != LT_TEMPLATE_ID )
returnignoreMessage();
// disabling of editor pages.
pEditor->setPageReadOnly(ePAGE_ATTRIBUTES);
pEditor->setPageReadOnly(ePAGE_INITPROP);
pEditor->setPageReadOnly(ePAGE_FIELDATTR);
pEditor->setPageReadOnly(ePAGE_COLUMNS);
pEditor->setPageReadOnly(ePAGE_INDEXES);
pEditor->setPageReadOnly(ePAGE_PROPERTIES);
pEditor->setPageReadOnly(ePAGE_METADATA_EXTENSIONS);
pEditor->setPageReadOnly(ePAGE_DATATYPES);
// resouce handle for property pages
HINSTANCE hInstance = m_hResourceDll;
// add the groups page
LoopingPropPage *pGroups = newLoopingPropPage(IDD_PROPPAGE_LARGE, pWidget, pEditor);
pGroups->m_psp.hInstance = hInstance;
pEditor->addPluginPage(pGroups);
return PMCPLUGIN_CONTINUE;
}

/**
** Called when a folder is open
*/
IINT32 LTPlugin::onFolderOpen(IUINT32 uFolderId,
IUINT32uVerId,
IUStringsFolderVerName)
{
return PMCPLUGIN_CONTINUE;
}

/**
** Called before a folder is closed
*/
IINT32 LTPlugin::onFolderClose(IUINT32 uFolderId, IUINT32uVerId,
IUStringsFolderVerName)
{
return PMCPLUGIN_CONTINUE;
}

/**
** Sent each time a Tool becomes active.
** One of these is sent each time the user switches tools.
** Can be used to regenerate information like we do with Mapplets,etc.
*/
IINT32 LTPlugin::onActivateTool(IUINT32 uToolId)
{
return PMCPLUGIN_CONTINUE;
}
/**
** this will be called on init,
*/
IINT32 LTPlugin::onInitTool(IUINT32 uToolId)
{
return PMCPLUGIN_CONTINUE;
}
/**
** this will be called on tool bar click.
*/
IINT32 LTPlugin::onToolBarClick(IWidget *pWidget, IBOOLEAN&bValid)
{
return PMCPLUGIN_CONTINUE;
}
/**
** returns true or false based on the DBTYPE is Lopping ornot.
*/
BOOL LTPlugin::isSupportedDbType(IUINT32 uDBType)
{
return (uDBType == DBTYP_LT)? ITRUE : IFALSE;
}

Build Resource DLL:

  1. Go to the Resource view.
  2. Add a new dialogue to the project.
  3. Generate property pages for the new dialogue, and add new pages to the plug-in DLL.

Installation Instructions:

  1. Build the transformation plug-in DLL in release mode and copythe DLL to the <PowerCenter Client installation directory>/client/ directory.
  2. Build resource DLL in release mode and copy the DLL to the<PowerCenter Client installation directory>/client/directory.
  3. Go to Start> Run and enter "regedit" (this will open the Windows registry editor).
  4. Go to MyComputer\HKEY_LOCAL_MACHINE\SOFTWARE\Informatica\PowrMartClient Tools\Plugins\Informatica.
  5. Right click on this key and select New >StringValue .
  6. Enter the following:
    Name: "PM_LOOPING"
    Value: "ctloopingtransformation.dllPlug-In".

    Client Plugin workspace:  

    Resource Dialogue:

    // LoopingPropPage.cpp: implementation file
    #include "LoopingPropPage.h"
    //#include "LTResource409/LTResource409.h"
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif

    static const IUString gStartTime = IUString("StartTime");
    static const IUString gEndTime = IUString("EndTime");
    static const IUString gLoopingVar = IUString("LoopingVar");

    ////////////////////////////////////////////////////////////////////////////
    // LoopingPropPage property page
    IMPLEMENT_DYNCREATE(LoopingPropPage, CPropertyPageEx)

    LoopingPropPage::LoopingPropPage(UINT szPageName,IMultiGroupExtProcWidget *pWidget, IPMCEditor *pEditor) :
    CPropertyPageEx(LoopingPropPage::IDD,szPageName)
    {
    m_pWidget = pWidget;
    m_pEditor = pEditor;
    //{{AFX_DATA_INIT(LoopingPropPage)
    // NOTE: the ClassWizard will add member initializationhere
    //}}AFX_DATA_INIT
    }

    /**
    this function need to defined to create dynamic pagesIMPLEMENT_DYNCREATE.
    */
    LoopingPropPage::LoopingPropPage()
    {}

    LoopingPropPage::~LoopingPropPage()
    {}

    void LoopingPropPage::DoDataExchange(CDataExchange* pDX)
    {
    CPropertyPageEx::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(LoopingPropPage)
    // NOTE: the ClassWizard will add DDX and DDV callshere
    //}}AFX_DATA_MAP
    }
    BEGIN_MESSAGE_MAP(LoopingPropPage, CPropertyPageEx)
    //{{AFX_MSG_MAP(LoopingPropPage)
    DDX_CONTROL(
    // NOTE: the ClassWizard will add message map macroshere
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    BOOL LoopingPropPage::OnInitDialog()
    {
    TRACE("LoopingPage::OnInitDialog");
    //CResourceStateMgr res(m_psp.hInstance); // setour resource dll.
    CPropertyPageEx::OnInitDialog();

    EnableToolTips(TRUE);
    m_hStartTime.SubclassDlgItem(IDC_TEXT_STARTTIME,this);
    m_hEndTime.SubclassDlgItem(IDC_TEXT_ENDTIME,this);
    ISTATUS stat = getMetaDataExt();
    if(!m_startTime.isEmpty())
    m_hStartTime.SetWindowText(CString(m_startTime));
    if(!m_endTime.isEmpty())
    m_hEndTime.SetWindowText(CString(m_endTime));
    UpdateData(FALSE);
    return TRUE;
    }

    /**
    ** get metadata extension values
    */
    BOOL LoopingPropPage::OnKillActive()
    {
    setMetaDataExt();
    return TRUE;
    }

    /**
    ** set meta data extension values
    */
    ISTATUS LoopingPropPage::setMetaDataExt()
    {
    IVector<IMetaExtVal*> valList;
    m_pWidget->getMetaExtValList(valList,IMetaExt::eSHAREWRITE|IMetaExt::eSHAREWRITE|IMetaExt::eCLIENTVISIBLE|IMetaExt::eCLIENTEDITABLE,1, 909002);
    size_t count = valList.length();
    for(size_t i = 0; i < count; ++i)
    {
    IMetaExtVal* pVal =valList.at(i);
    IUString extName =pVal->getName();
    if(extName ==gStartTime)
    {
    CString name;
    m_hStartTime.GetWindowText(name);
    IUString tempStart = (IUString)name;
    // first get the value of this extension from repository..
    ISTATUS retStat = pVal->getValue(m_startTime);
    IASSERT( retStat != IFAILURE);
    // now compare it with the current value to be set..
    if (tempStart.compare(m_startTime))
    {
    // if the two values are different,tell the editor to savechanges
    m_pEditor->setModified(ITRUE);
    }
    retStat =pVal->setValue(tempStart);}
    else if(extName ==gEndTime)
    {
    CString name;
    m_hEndTime.GetWindowText(name);
    IUString tempEnd = (IUString)name;
    // first get the value of this extension from repository..
    ISTATUS retStat = pVal->getValue(m_endTime);
    IASSERT(retStat != IFAILURE);
    // now compare it with the current value to be set..
    if (tempEnd.compare(m_startTime))
    // if the two values are different,tell the editor to savechanges
    m_pEditor->setModified(ITRUE);
    retStat =pVal->setValue(tempEnd);
    }
    m_pEditor->setModified(ITRUE);}
    retStat =pVal->setValue(tempEnd);}
    SetModified(true);
    return ISUCCESS;
    }

    /**
    ** get metadata extension values
    */
    ISTATUS LoopingPropPage::getMetaDataExt()
    {
    IVector<IMetaExtVal*> valList;

    m_pWidget->getMetaExtValList(valList,
    IMetaExt::eSHAREWRITE|IMetaExt::eSHAREWRITE|IMetaExt::eCLIENTVISIBLE|IMetaExt::eCLIENTEDITABLE,
    1,
    909002);

    size_t count = valList.length();
    for(size_t i = 0; i < count; ++i)
    {
    IMetaExtVal* pVal =valList.at(i);
    IASSERT(pVal);
    IUString extName =pVal->getName();

    if(extName ==gStartTime)
    {
    ISTATUS retStat = pVal->getValue(m_startTime);
    IASSERT( retStat != IFAILURE);
    }
    else
    if(extName == gEndTime)
    {
    ISTATUS retStat = pVal->getValue(m_endTime);
    IASSERT( retStat != IFAILURE);
    }
    }
    SetModified(true);
    return ISUCCESS;
    }

  7. Copy both of these DLLs to the <Informaticainstallation>/client/ directory.

These DLLs will be loaded, when Designer is launched.

When you open the Designer and then open the Transformation Developer you will see your transformation in the following:

  • List of the transformations.
  • Icon will appear in the top pane of the Designer.
  • Icon will appear on each transformation widget.

Server Shared library or DLL

The Custom transformation functions allow you to develop the transformation logic in a procedure you associate with a Custom transformation. PowerCenter provides two sets of functions;generated functions and API functions. The PowerCenter Server uses generated functions to interface with the procedure. When you create a Custom transformation and generate the source code files, the Designer includes the generated functions in the files.

Use the API functions in the procedure code to develop the transformation logic. When you write the procedure code, you can configure it to receive a block of rows from the PowerCenter Server or a single row at a time. You can increase the procedure performance when it receives and processes a block of rows.

For more information about receiving rows from the PowerCenter Server, refer to the "Custom Transformation Guide" chapter in the PowerCenter Designer Guide .

Create the DLL on Windows or shared libraries on UNIX with the name of the module in the registered plugin XML. We need to implement the functions mentioned in the XML. You have to implement functions defined in the pmloopingfunc.h andpmloopingtrans.h, the DLL name should be pmloopingtrans.dll for Windows and libpmloopingtrans.so for UNIX.

Refer to the "Custom Transformation Guide" chapter in the PowerCenter Designer Guide for for more information on creating and building server plug-in DLLs.

<TEMPLATEATTRIBUTENAME="Module Identifier" VALUE="pmloopingtrans" ISCLIENTEDITABLE ="NO"/>
<TEMPLATEATTRIBUTE NAME="Function Identifier"VALUE="pmloopingfunc" ISCLIENTEDITABLE = "NO"/>


Validation Library

You can specify the validation DLL or shared library to verify (created by Informatica mapping developer) metadata for the given instance of the transformation. AFter you specify this information in Designer it will be validated during the transformation create and save or import and export process.

<LIBRARY NAME ="pmloopingvldn.dll" OSTYPE = "NT" TYPE = "VALIDATION"/>
<LIBRARY NAME = "libpmloopingvldn.sl" OSTYPE ="HPUX" TYPE="VALIDATION" />



More Information


Reference

For more information about receiving rows from the PowerCenter Server, refer to the "Custom Transformation Guide" chapter in the PowerCenter Designer Guide .



Attachments


Applies To
Product: PowerCenter
Problem Type:
User Type: Administrator
Project Phase:
Product Version: PowerCenter
Database:
Operating System:
Other Software:

Last Modified Date: 8/30/2010 4:53 PM ID: 17621
People who viewed this also viewed

Feedback

Did this KB document help you?



What can we do to improve this information (2000 or fewer characters)