Example: Building a Source Designer Plug-in

 < Day Day Up > 



This section shows you how to develop a source designer plug-in for SAS ETL Studio. The SourceDesignerPlugin sample provides a method for building a new source designer, along with links to Web site resources for more detailed information.

Before you can design a new source designer plug-in, determine the format of the source and the metadata that you want to capture about the source. You need this information in order to design property windows that will gather information about your source.

Mapping the Metadata and Building the Plug-in

Decide what type of metadata you want to register as a result of running your plug-in. For more details about defining metadata, see the SAS Metadata Model in the SAS Open Metadata Architecture: Reference, which is available in SAS Help and Documentation.

Source designer plug-ins are integrated into SAS ETL Studio using the SourceDesignerInterface, which is a Java interface. For technical details about the SAS ETL Studio Plug-In Framework and the SourceDesignerInterface (com.sas.wadmin.plugins.SourceDesignerInterface), see the SAS BI Package Libraries at http://support.sas.com/rnd/gendoc/bi/api/

You can also refer to the following sample Java programs:

  • Manifest.mf:

           Manifest-Version: 1.0       Main-Class: plugindir       Created-By: 1.3.0 (Sun Microsystems Inc.)       Plugin-Init: plugindir.SourceDesignerPlugin.class 
  • PropertyBundle.properties

           ImageLocation.notrans = com/sas/wadmin/visuals/res/       StepOut.image=DataSetSource16.gif       Common.warehouse_w2.image=warehouse_w2.gif       Common.warehouse_w3.image=warehouse_w3.gif       Common.warehouse_w4.image=warehouse_w4.gif       Common.warehouse_w5.image=warehouse_w5.gif       Common.warehouse_w6.image=warehouse_w6.gif       wa_source_connectInfo.image=wa_source_connectInfo.gif       gen_select_table.image=gen_select_table.gif       gen_target_location.image=gen_target_location.gif       gen_summary.image=gen_summary.gif       gen_subset_tables.image=gen_subset_tables.gif       FinishTab.Title.txt=Finish 
  • SourceDesignerPlugin.class

  • SourceDesignerPlugin.java

           /**        * Title:        SourceDesignerPlugin        * Description:  Implements a basic Source Designer Interface        * Copyright:    Copyright (c) 2003 by SAS Institute Inc. Cary, NC 27513 USA        * Company:      SAS Institute Inc.        * */       package plugindir;       import javax.swing.Icon;       import javax.swing.ImageIcon;       import plugindir.visuals.*;       import com.sas.plugins.PluginResourceBundle;       import com.sas.wadmin.plugins.SourceDesignerInterface;       import com.sas.workspace.WATransitionWizardModel;       import com.sas.workspace.WAWizardDialog;       import com.sas.workspace.Workspace;       import com.sas.workspace.visuals.WizardFinishTab;       /**        *        * The SourceDesignerInterface is used to describe Source Designer addins        * @see com.sas.plugins for additional information about the plug in        * methodology        *        */       public class SourceDesignerPlugin extends Object implements       SourceDesignerInterface       {         protected WAWizardDialog            m_wizardDialog;         protected WATransitionWizardModel   m_wizardModel;         protected String m_name;         protected ImageIcon                 m_icon;         protected String                    m_tooltip;         protected String                    m_category;         protected Workspace                 m_workspace;         private static PluginResourceBundle bundle =       new PluginResourceBundle( SourceDesignerPlugin.class );       protected String[][]                  m_transitionList =                { {"tab1", "NEXT", "tab2"},                  {"tab2", "NEXT", "tab3"}};       /**        * Common constructor that enables the appropriate fields for the given        * metadata object.        */       public SourceDesignerPlugin()       {          m_name = "SourceDesignerPlugin";          m_icon = bundle.getImageIcon("Icon.image" );          m_tooltip = "SD Tooltip";          m_category = "Source Designers";          m_workspace = Workspace.getWorkspace();       }//end public SourceDesignerPlugin()       /**        * This method should be used by the wizard to add the wizard tabs        * to the wizard dialog, and add the wizard transitions so the wizard model.        *        * @param wizardDialog is the wizard dialog that is calling        * to place this plugin into itself        * @param wizardModel is the wizard dialog transition model which        * the plugin should add transitions to @return true if the initialization        * was successful, false otherwise        */       public boolean initializeWizard(WAWizardDialog wizardDialog,        WATransitionWizardModel wizardModel)       {          m_wizardDialog = wizardDialog;          m_wizardModel = wizardModel;          m_wizardDialog.setHelpProduct("hlp");          ImageIcon image = bundle.getImageIcon( "wa_source_connectInfo.image" );          m_wizardDialog.addTab("Tabber1 Title",                                 "tab1",                                 new Tab1(),                                 "wa_source_connectInfo.gif",                                 image,                                 false );          image = bundle.getImageIcon( "gen_subset_tables.image" );          m_wizardDialog.addTab( bundle.getString(            "TableSelectionMethodWizardTab.Title.txt"),                                 "tab2",                                 new Tab2(),                                 "gen_subset_tables.gif",                                 image,                                 false );          image = bundle.getImageIcon("gen_summary.image" );          WizardFinishTab finish = new WizardFinishTab();          finish.setHelpTopic("finishwindow");          m_wizardDialog.addTab(bundle.getString("FinishTab.Title.txt"),                                "tab3",                                finish,                                "gen_summary.gif",                                image,                                true );          m_wizardModel.addTransitions( m_transitionList );          return true;       }//end public initializeWizard ( Frame frame, String title )       /**        * Method defined in PluginInterface...        */       public void initPlugin() {}       /**        * Returns the name of the plugin.        *        * @return String name of this plugin.        */       public String getName()       {          return m_name;       }//end public String getName()       /**        * Return the tab name of the initial tab in this wizard        *        * @return a string that is the initial tab name of this wizard.        * This is the name specified in the transition list. Note that        * this name is NOT visible; it is a unique per wizard name that        * is used only within the wizard to manage transitions. It matches        * the transition list names that the plugin provided. It is a good        * idea to prefix your tab names with the name of your plugin in        * order to ensure that they are unique.        * For example "OracleImporterTab4".        */       public String getInitialTabName()       {          return "tab1";       }       /**        * Return a string array of all of the tabs that are endpoint tabs        * in the wizard (the tabs that should have finish turned on        * after them).        *        * @return String[] array of all the tabs that are the endpoint        * tabs in the wizard        */       public String[] getLastTabNames()       {          String[] value = {"tab3"};          return (value);       }       /**        * Required by PluginInterface, returns the icon to be used with the        * Interface        * In the Source Designer, this is the icon that shows up in the tree.        *        * @return Icon to be displayed with the Plugin        */       public Icon getIcon(){return m_icon;};       /**        * Return a tooltip string that to be displayed        *        * @return String containing the tooltip to be displayed.        */        public String getToolTip() {return m_tooltip;};        /**        * The designer can choose to place the plugin in any category that the        * designer chooses.        * You can concatenate categories with a "."; each level is a level Source        * Designer selection tree. For example, a category name of Levels.MyStuff        * would show up as:        *        * - Source Designers        *   - Levels        *     - MyStuff        *        + mynewtransform        *        * Designers should take care not when describing these hierarchies        * such that they fit in well with other similar designers.        *        * @return the Category to place this addin into        */       public String getCategory() {return m_category;}       /**        * Required by the PluginInterface: returns the description of the Plugin.        *        * @return String containing the description of the plugin        */       public String getDescription() {return "";}       public void dispose()       {       }       }//end public class 

  • Panel1.class

  • Panel1.java

           /**        * Title:        Panel1        * Description:  Panel1        * Copyright:    Copyright 2003, SAS Institute Inc * Company: SAS Institute        * Inc. * @version 1.0        */       package plugindir.visuals;       import java.awt.GridBagConstraints;       import java.awt.GridBagLayout;       import java.awt.Insets;       import java.awt.event.ActionEvent;       import java.awt.event.ActionListener;       import javax.swing.*;       import javax.swing.JRadioButton;       import javax.swing.border.EtchedBorder;       import com.sas.metadata.MdException;       import com.sas.plugins.PluginResourceBundle;       import com.sas.workspace.WAPanel;       /**        * Panel1        */       public class Panel1 extends WAPanel       {          /** Property bundle */          private static PluginResourceBundle bundle =                new PluginResourceBundle( Panel1.class );          protected JLabel m_label = new JLabel("Put Label here..");          /** Boolean to turn on a border around this panel */          protected boolean             m_fBorder=false;          /**           * Constructs a panel1           *           * @param fBorder - create a border around this panel (true) or not           * (false)           */          public Panel1(boolean fBorder)          {             super();             m_fBorder = fBorder;             initialize();             layoutWidgets();          }         /**          * Initialization routine. Creates and initializes all of the widgets          * on the panel.          */          public void initialize()          {             super.initialize();          }//end public void initialize()         /**          * Validate the data on the panel.          */         public boolean validateData()         {            return true;         }//end public boolean validateData()         /**          * Just like in a property tab, this method is called before the panel          * is made visible to do the model/view data exchange.          * @param saveToModel true - move widget values to model values;          *                    false - move model values to widgets values          */         public boolean doDataExchange(boolean bSaveToModel) throws MdException         {            if (bSaveToModel == false)            {            }            return true;         }//end public boolean doDataExchange(boolean bsaveToModel)             throws MdException         /**          * Arrange the widgets in displayed panel.          *          */         public void layoutWidgets()         {            //Let's layout the button panel            GridBagLayout gridBagLayout1 = new GridBagLayout();            GridBagConstraints gbc1 = new GridBagConstraints();            WAPanel myPanel = new WAPanel();            myPanel.setLayout( gridBagLayout1 );            myPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED));            // Add the radio buttons to the panel            gbc1.gridx = 0;            gbc1.gridy = 0;            gbc1.gridwidth = GridBagConstraints.RELATIVE;            gbc1.gridheight = 1;            gbc1.weightx = 1.0;            gbc1.weighty = 1.0;            gbc1.anchor = GridBagConstraints.WEST;            gbc1.fill = GridBagConstraints.HORIZONTAL;            gbc1.insets = new Insets(0,5,0,0);            gridBagLayout1.setConstraints( m_label, gbc1 );            myPanel.add( m_label );            //The Main panel's gridbaglayout stuff            GridBagLayout gridBagLayout = new GridBagLayout();            GridBagConstraints gbc = new GridBagConstraints();            setLayout( gridBagLayout );            // Add the radio buttons to the panel            gbc.gridx = 0;            gbc.gridy = 0;            gbc.gridwidth = GridBagConstraints.RELATIVE;            gbc.gridheight = 1;            gbc.weightx = 1.0;            gbc.weighty = 1.0;            gbc.anchor = GridBagConstraints.NORTHWEST;            gbc.fill = GridBagConstraints.HORIZONTAL;            gbc.insets = new Insets(0,0,0,0);            gridBagLayout.setConstraints( myPanel, gbc );            add( myPanel );         }//end public void layoutWidgets()       } 

  • Panel2.class

  • Panel2.java

           /**        * Title:        Panel2        * Description:  Panel2        * Copyright:    Copyright 2003, SAS Institute Inc * Company: SAS Institute        * Inc. * @version 1.0        */       package plugindir.visuals;       import java.awt.GridBagConstraints;       import java.awt.GridBagLayout;       import java.awt.Insets;       import javax.swing.JLabel;       import javax.swing.border.EtchedBorder;       import com.sas.metadata.MdException;       import com.sas.plugins.PluginResourceBundle;       import com.sas.workspace.WAPanel;       /**        * Panel 2        *        */       public class Panel2 extends WAPanel {        /** Property bundle */        private static PluginResourceBundle bundle =         new PluginResourceBundle(Panel2.class);        /** Boolean to turn on a border around this panel */         protected boolean m_fBorder = false;         protected JLabel m_label;         /**          *          * @param fBorder - create a border around this panel (true) or not (false)          */         public Panel2(boolean fBorder) {          super();          m_fBorder = fBorder;          initialize();          layoutWidgets();         }        /**         * Initialization routine. Creates and initializes all of the widgets         * on the panel.         */        public void initialize() {         m_label = new JLabel("Put Label here ");         super.initialize();        } //end public void initialize()        /**         * Validate the data on the panel.         */        public boolean validateData() {         return true;        } //end public boolean validateData()        /**         * Just like in a property tab, this method is called before the          * panel is made visible to do the model/view data exchange.         * @param saveToModel true - move widget values to model values;         *                    false - move model values to widgets values         */         public boolean doDataExchange(boolean bSaveToModel) throws MdException {          if (bSaveToModel == false) {          } else          {          }          return true;         } //end public boolean doDataExchange(boolean bsaveToModel)               throws MdException         /**          * Arrange the widgets in displayed panel.          *          */         public void layoutWidgets() {          //Let's layout the button panel          GridBagLayout gridBagLayout1 = new GridBagLayout();          GridBagConstraints gbc1 = new GridBagConstraints();          WAPanel myPanel = new WAPanel();          myPanel.setLayout(gridBagLayout1);          myPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED));          // Add the radio buttons to the panel          gbc1.gridx = 0;          gbc1.gridy = 0;          gbc1.gridwidth = GridBagConstraints.RELATIVE;          gbc1.gridheight = 1;          gbc1.weightx = 1.0;          gbc1.weighty = 1.0;          gbc1.anchor = GridBagConstraints.WEST;          gbc1.fill = GridBagConstraints.HORIZONTAL;          gbc1.insets = new Insets(0, 5, 0, 0);          gridBagLayout1.setConstraints(m_label, gbc1);          myPanel.add(m_label);          //The Main panel's gridbaglayout stuff          GridBagLayout gridBagLayout = new GridBagLayout();          GridBagConstraints gbc = new GridBagConstraints();          setLayout(gridBagLayout);          // Add the radio buttons to the panel          gbc.gridx = 0;          gbc.gridy = 0;          gbc.gridwidth = GridBagConstraints.RELATIVE;          gbc.gridheight = 1;          gbc.weightx = 1.0;          gbc.weighty = 1.0;          gbc.anchor = GridBagConstraints.NORTHWEST;          gbc.fill = GridBagConstraints.HORIZONTAL;          gbc.insets = new Insets(0, 0, 0, 0);          gridBagLayout.setConstraints(myPanel, gbc);          add(myPanel);          } //end public void layoutWidgets()          } 

  • Tab1.class

  • Tab1.java

           /**        * Title:        Tab1        * Description:  Tab1        * Copyright:    Copyright 2003, SAS Institute Inc * Company: SAS        * Institute Inc. * @version 1.0        */       package plugindir.visuals;       import java.awt.GridBagConstraints;       import java.awt.GridBagLayout;       import java.awt.Insets;       import com.sas.plugins.PluginResourceBundle;       import com.sas.workspace.WsDescriptionWizardTab;       /**        * Tab1        *        *        */       public class Tab1 extends WsDescriptionWizardTab       {          /** Property bundle */          private static PluginResourceBundle bundle =                   new PluginResourceBundle(Tab1.class);         private PluginResourceBundle m_eda_bundle;         protected Panel1 myPanel1;         /**          * Main constructor          */         public Tab1()         {            super();            setHelpTopic("selecttablesbyapplicationareawindow");            myPanel1 = new Panel1(false);            initialize();         }         /**          * Initialize the widgets and their layout.          */         public void initialize()         {            this.setLayout(new GridBagLayout());            this.add(myPanel1, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0                     ,GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH,                      new Insets(0, 0, 0, 0), 0, 0));         }//end public void initialize()         /**          * Transfer data to and from the model.          *          * @param bSaveToModel True if transfering from view to model, false if          * vice versa          */         public boolean doDataExchange( boolean bSaveToModel ) throws         com.sas.metadata.MdException         {               return myPanel1.doDataExchange(bSaveToModel);         }//end public boolean doDataExchange( boolean bSaveToModel ) throws         com.sas.metadata.MdException         /**          * Validate data entered into panel.          *          * @return boolean to determine if there is validate data in the panel          * or not          */         public boolean validateData()         {            return myPanel1.validateData();         }//end public boolean validateData()         /**          * Run when the Next button is selected.          */         public void onNext()         {            super.onNext();         }//end public void onNext()         /**          * Run when the back button is selected.          */         public void onBack()         {               super.onBack();         }//end public void onBack()         /**          * Create the finish string that shows up in WAWizardFinish          */         public String createFinishString()         {            String finishString = "This is the finish string";            return finishString;         }//end public String createFinishString()      }// 

  • Tab2.class

  • Tab2.java

           /**        * Title:        Tab2        * Description:  Tab2        * Copyright:    Copyright 2003, SAS Institute Inc * Company:  SAS        * Institute Inc. * @author        * @version      1.0        */       package plugindir.visuals;       import java.awt.GridBagConstraints;       import java.awt.GridBagLayout;       import java.awt.Insets;       import com.sas.metadata.CMetadata;       import com.sas.metadata.MdObjectFactory;       import com.sas.metadata.MdObjectStore;       import com.sas.metadata.PhysicalTable;       import com.sas.metadata.SASLibrary;       import com.sas.plugins.PluginResourceBundle;       import com.sas.workspace.WAPropertyTab;       import com.sas.workspace.WAWizardDialog;       import com.sas.workspace.Workspace;       import com.sas.workspace.WsDescriptionWizardTab;       /**        * Tab2        *        */       public class Tab2 extends WsDescriptionWizardTab       {          /** Property bundle */          private static PluginResourceBundle bundle =                   new PluginResourceBundle(Tab2.class);          private PluginResourceBundle m_eda_bundle;          protected Panel2 myPanel2;          /**           * Main constructor           */          public Tab2()          {             super();             setHelpTopic("Tabber2");             myPanel2 = new Panel2(false);             initialize();          }       /**        * Initialize the widgets and their layout.        */       public void initialize()       {          this.setLayout(new GridBagLayout());          this.add(myPanel2, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0                   ,GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH,                   new Insets(0, 0, 0, 0), 0, 0));       }//end public void initialize()       /**        * Transfer data to and from the model.        *        * @param bSaveToModel True if transfering from view to model, false        * if vice versa        */       public boolean doDataExchange( boolean bSaveToModel ) throws       com.sas.metadata.MdException       {             if (bSaveToModel == false)                 myPanel2.doDataExchange(bSaveToModel);             else             // this is performed after the user has selected FINISH on the                wizard screen       write_metadata();      return true;       }//end public boolean doDataExchange( boolean bSaveToModel ) throws          com.sas.metadata.MdException       /**        * Validate data entered into panel.        *        * @return boolean to determine if there is validate data in the panel        * or not        */       public boolean validateData()       {          return myPanel2.validateData();       }//end public boolean validateData()       /**        * Run when the Next button is selected.        */       public void onNext()       {          super.onNext();       }//end public void onNext()       /**        * Run when the back button is selected.        */       public void onBack()       {          super.onBack();       }//end public void onBack()       /**        * Create the finish string that shows up in WAWizardFinish        */       public String createFinishString()       {          String finishString = "This is the finish string for tab2";          return finishString;       }//end public String createFinishString()       public void write_metadata() throws com.sas.metadata.MdException {        WAWizardDialog myWizard = (WAWizardDialog) this.getTopLevelAncestor();        //Get the Right repository to add it to, we hope...        Workspace workspace = Workspace.getWorkspace();        CMetadata myRepository = workspace.getDefaultRepository();        String strID = myRepository.getFQID().substring(9, 17);        MdObjectStore store =         (MdObjectStore) myWizard.getWizardData("OBJECTSTORE");        SASLibrary dbLibrary = (SASLibrary) myWizard.getWizardData("Library");        PhysicalTable newTable =         (PhysicalTable) MdObjectFactory.createComplexMetadataObject(          store,          store,          "TableName",          "PhysicalTable",          strID);         myWizard.setMasterObject(newTable);         //Let's set the attributes for this table         newTable.setIsCompressed(0);         newTable.setIsEncrypted(0);         newTable.setDBMSType("");         newTable.setSASTableName("TableName");         newTable.setTableName("TableName");         newTable.setName("TableName");         newTable.setDesc("Table Description");         newTable.setNumRows(-1);         // we are assuming everything is DATA not View at this point in the game...         newTable.setMemberType("DATA");         for (int i = 0; i < 10; i++) {          com.sas.metadata.Column newColumn =           (com.sas.metadata.Column) MdObjectFactory.createComplexMetadataObject(            store,            store,            "Column" + i,            "Column",            strID);          newTable.addElementToChangeList(newColumn);          newColumn.setSASColumnName("Column" + i);          newColumn.setSASColumnType("C");          newColumn.setSASColumnLength(10);          String format = "$10.";          newColumn.setSASFormat(format);          newColumn.setSASInformat("$10.");          newColumn.setColumnName("ColumnName" + i);          newColumn.setIsNullable(1);          newTable.getColumns().addElement(newColumn);         }         newTable.updateMetadataAll();        } //end public void tableDefinition()     }// 

In the sample source designer programs, the SourceDesignerPlugin.java class provides the needed plug-in navigation, where tabs display each panel of the plug-in. For example, public class Tab1 and public class Tab2 extend WsDescriptionWizardTab. Each tab then references a panel that displays that panel. For example, public class Panel1 and public class Panel2 extend WAPanel.

Installing and Running the Plug-in

In SAS ETL Studio, you must provide a JAR file that contains all class files, property bundles, and a manifest. Place this JAR file in the plug-ins subdirectory where SAS ETL Studio is located—for example, ETLStudioDirectoryLocation\9.1\plugins.

In the JAR file for each plug-in must be a manifest that includes the following information:

   Manifest-Version:  1.0   Main-Class:        plugindir /* Directory where your plug-in class that */                                /* extends SourceDesignerInterface resides */   Created-By:        1.3.0 (Sun Microsystems Inc.)   Plugin-Init:       plugindir.SourceDesignerPlugin.class 

You might also need to set the Class-Path for the plug-in to run properly.

Plug-in Output

The write_metadata method in Tab2 shows an example of writing the physical table, TableName, with 10 columns, named Column0 through Column9. This table shows up in the Custom tree of SAS ETL Studio.



 < Day Day Up > 



SAS Institute - SAS 9.1.3 ETL Studio. User's Guide
SAS 9.1.3 ETL Studio: Users Guide
ISBN: 1590476352
EAN: 2147483647
Year: 2004
Pages: 127
Authors: SAS Institute

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net