ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » Where to find more info on creating custom property editors

Post new topic  Reply to topic
 Where to find more info on creating custom property editors « View previous topic :: View next topic » 
Author Message
bbakerman
PostPosted: Wed Sep 21, 2005 8:17 pm    Post subject: Where to find more info on creating custom property editors Reply with quote

Apprentice

Joined: 17 Dec 2003
Posts: 41

The manual on WBi has the following to say about creating your own custom property editors in WBI.


Quote:

Once you have imported the plugin API into the workbench, you can then use the API to create a new Java class for your property editor or compiler, as follows:

From the UDN project, select the /src directory.
Click File > New > Class.
Type a name for your class in the Name text field.
Delete any text in the Superclass text field, and click Browse.
Select AbstractPropertyEditor.
Click OK.
Click the Add button next to the Interface text field.
Select the IPropertyEditor interface or the IPropertyCompiler interface, or both.
Click Finish.


I want to create a node that has a long text field (much like the standard long description) as a custom property editor.

Can someone point me in the right direction where I can get some more detailed information about how to create my own custom property editor.

Alternatively perhaps I can re-used the standard long description property.

I discovered by accident that nodes have a auto defined property called "traceLevel" so how can I find out the names of the other standard properties say for long description.
Back to top
View user's profile Send private message
javaforvivek
PostPosted: Wed Sep 21, 2005 10:29 pm    Post subject: Reply with quote

Master

Joined: 14 Jun 2002
Posts: 282
Location: Pune,India

Have you gone through this:
Creating a new user-Defined Node Plug-in, Defining Properties,
http://publib.boulder.ibm.com/infocenter/wbihelp/index.jsp?topic=/com.ibm.etools.mft.doc/as04496_.htm

This might help you...

Quote:


    1. Right-click on Basic in the hierarchy and click Add Property. To create separate pages of properties, you can use the Add Property Group function.
    2. Select the correct attribute type. This can be one of the built-in types, or a type to match the list of values the property can have.
    3. Enter any default values. This value applies as if the flow developer had set this value themselves. It will be shown in the Properties dialog.
    4. If you want to generate a property editor or a compiler, specify the location for these resources in the relevant field.

_________________
Vivek
------------------------------------------------------
...when you have eliminated the impossible, whatever remains, however improbable, must be the truth.
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
bbakerman
PostPosted: Thu Sep 22, 2005 3:39 pm    Post subject: Reply with quote

Apprentice

Joined: 17 Dec 2003
Posts: 41

Yes I have been busy creating many simple properties such as boolean, strings and enums.

what I am after is a way to have a UI representation much like the Trace node where you can enter in multiple lines of text.

I gather I need to create my own property editor as hinted to by point 4.

Quote:

4. If you want to generate a property editor or a compiler, specify the location for these resources in the relevant field.


My question is where tyo find more detail documentation on how one creates such a property editor class. I gather it will be a SWT class that implements a WBI UI interface but thats all I know.

The second part of my question is from some reverse engineering and accidentaly dicovering (that hard) way that nodes have some auto defined properties that you are not allowed to overrride.

For example I added a "traceLevel" property to my node and found out that this is in effect a reserved property. It will always error on deploy if you have a property with this name. In fact if you do a java call in the node like this

String val = getAttribute("traceLevel");

then it usually returns a value of "none". I gather this is related the user trace settings.

All nodes appear to have a short description and long description property (at least from a UI point of view). I was hoping I couold some how get access to these values on the broker side of things when the node is deployed.

This way I would not have to add my own special "big text field" property editor class.

Does any one know if the short or long description is available to the node at run time?
Back to top
View user's profile Send private message
bbakerman
PostPosted: Wed Sep 28, 2005 10:38 pm    Post subject: Reply with quote

Apprentice

Joined: 17 Dec 2003
Posts: 41

For any one who may be interested I discovered a neat way to find out what properties you node can support.

I wrote a simple java program that dump the contents of the broker database to "reverse guess" what the structure of the message flows are.

Of most interest is the table BROKERRESOURCES. It contains amonst many other things the message flows.

For example

Quote:

=================================
DB2ADMIN.BROKERRESOURCES
=================================
Row 1
_________________________________
BROKERUUID (BINARY){class [B} = [B@4a6d5613
Raw Bytes : 2166fc5c030100000080be3cc6dcc426
Raw Str : !fü\

EXECGROUPUUID (BINARY){class [B} = [B@4b205613
Raw Bytes : 2266fc5c030100000080be3cc6dcc426
Raw Str : "fü\

RESOURCETYPE (VARBINARY){class [B} = [B@48f69613
Raw Bytes : 4d657373616765466c6f77
Raw Str : MessageFlow

RESOURCENAME (VARBINARY){class [B} = [B@48625613
Raw Bytes : 34373363363936372d303330312d303030302d303038302d663238626266373834393462
Raw Str : 473c6967-0301-0000-0080-f28bbf78494b

RESOURCEDATA (BLOB){class COM.ibm.db2.jdbc.app.DB2Blob} = COM.ibm.db2.jdbc.app.DB2Blob@4ee39613
BLOB (length=12516)________________________
<Definition><MessageFlow uuid="473c6967-0301-0000-0080-f28bbf78494b" userTraceLevel="none" traceLevel="none" userTraceFilter="none" traceFilter="none"
label="TestTCPIPInbound" additionalInstances="0" commitCount="1" commitInterval="0" coordinatedTransaction="no" StatsArchivalOn="inactive" StatsArchi
veThreadDataLevel="none" StatsArchiveNodeDataLevel="none" StatsSnapPublicationOn="inactive" StatsSnapThreadDataLevel="none" StatsSnapNodeDataLevel="no
ne" StatsArchiveOutputFormat="usertrace" StatsSnapOutputFormat="usertrace" StatsArchiveReset="no" StatsArchiveAccountingOrigin="none" StatsSnapAccount
ingOrigin="none"><TcpHL7InputNode uuid="TestTCPIPInbound#FCMComposite_1_1" userTraceLevel="none" traceLevel="none" userTraceFilter="none" traceFilter=
"none" label="TcpHL7Input on 8192" validateMaster="none" validateFailureAction="exception" validateTiming="deferred" validateValueConstraints="full" v
alidateFixup="none" messageDomainProperty="BLOB" messageSetProperty="" messageTypeProperty="" messageFormatProperty="" topicProperty="" rootParserClas
sName="GenericRoot" firstParserClassName="MQHMD" tcpipPort="8192" tcpipConnectionTimeout="30" nodeTraceLevel="On" nodeTraceFile="/home/wbihmb/${Broker
Name}/trace/${FlowName}.trace" tcpipReadTimeout="30"><OutputTerminal uuid="Out"/></TcpHL7InputNode><ComIbmMQOutputNode uuid="TestTCPIPInbound#FCMCompo
site_1_2" userTraceLevel="none" traceLevel="none" userTraceFilter="none" traceFilter="none" label="test.tcpip.inbound" validateMaster="inherit" valida
teFailureAction="exception" validateTiming="immediate" validateValueConstraints="full" validateFixup="none" queueManagerName="" queueName="test.tcpip.
inbound" destinationMode="fixed" transactionMode="automatic" persistenceMode="automatic" format=" " newMsgId="yes" newCorrelId="no" segmentatio
nAllowed="no" alternateUserAuthority="no" messageContext="none" request="no" replyToQMgr="" replyToQ="" hpo="no"><InputTerminal uuid="in"/><OutputTerm
inal uuid="out"/><OutputTerminal uuid="failure"/></ComIbmMQOutputNode><ComIbmComputeNode uuid="TestTCPIPInbound#FCMComposite_1_3" userTraceLevel="none
" traceLevel="none" userTraceFilter="none" traceFilter="none" label="Add MQMQD" dataSource="" transaction="automatic" treatWarningsAsErrors="no" throw
ExceptionOnDatabaseError="yes" initialStackSize="256" computeExpression="
CREATE SCHEMA &quot;&quot;

PATH csv,db,fld

CREATE COMPUTE MODULE Tcpip_Add
_MQMD_Module
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
set OutputRoot.Properties = InputRoot.Properties;

SET OutputRoot.MQMD.StrucId=MQMD_
STRUC_ID;
SET OutputRoot.MQMD.Version=MQMD_CURRENT_VERSION;
-- set OutputRoot.MQMD.Format = MQFMT_NONE;
-- set OutputRoot.MQMD.Persistence = MQP
ER_PERSISTENT;
-- set OutputRoot.MQMD.Expiry = MQEI_UNLIMITED;
-- set OutputRoot.MQMD.MsgId = cast(&apos;C0FFEE&apos; as blob);
-- set OutputRoot.M
QMD.CorrelId = cast(&apos;CAFE&apos; as blob);

set OutputRoot.BLOB = InputBody;
RETURN TRUE;
END;

END MODULE;


The other great thing of interest here is that the properties of the nodes and the flow are exposed in the RESOURCEDATA BLOB column. Its a big XMl document decribing the flow.

I managed to deduce that there is a node property called "userTraceFilter" which gets set to the current state of the "user trace" for a message flow.

I have used this to allow "my own custom tracing" for an custom input node and yet have the "switch" for this custom tracing be controlled via the standard broker mqsichangetrace or the Toolkit "set Trace Level" commands.

This is really cool and allows dynamic control of your own custom nodes, without requiring any redeployment to change trace settings.

I also discovered that if you write your own input node you geta stack of properties like these ones whcih are only marginally documented ..


Quote:

<TcpHL7InputNode

uuid="TestTCPIPInbound#FCMComposite_1_1"
userTraceLevel="none"
traceLevel="none"
userTraceFilter="none"
traceFilter="none"
label="TcpHL7Input on 8192"

validateMaster="none"
validateFailureAction="exception"
validateTiming="deferred"
validateValueConstraints="full" v
alidateFixup="none"
messageDomainProperty="BLOB" messageSetProperty="" messageTypeProperty=""
messageFormatProperty=""
topicProperty=""
rootParserClassName="GenericRoot"
firstParserClassName="MQHMD"

The following are my custom properties, then ones above are the broker defined ones.


tcpipPort="8192"
tcpipConnectionTimeout="30"
nodeTraceLevel="On"
nodeTraceFile="/home/wbihmb/${BrokerName}/trace/${FlowName}.trace" tcpipReadTimeout="30">



I hope this helps someone with any node development issues.
Back to top
View user's profile Send private message
javaforvivek
PostPosted: Wed Sep 28, 2005 10:45 pm    Post subject: Reply with quote

Master

Joined: 14 Jun 2002
Posts: 282
Location: Pune,India

Baker,
Great work..
So finally, you managed to create your own custom property editor, huh??

I think, the documentation for user-defined-nodes, needs considerable improvement. Don't you think so?
_________________
Vivek
------------------------------------------------------
...when you have eliminated the impossible, whatever remains, however improbable, must be the truth.
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
bbakerman
PostPosted: Wed Sep 28, 2005 10:52 pm    Post subject: Reply with quote

Apprentice

Joined: 17 Dec 2003
Posts: 41

Not quite. I gather I have to create a SWT control that implements special interfaces. This is PDE development with which I am not familair. I was hoping there would be a tutorial somewhere specifically about WBI tollkit but it looks like I will have to crack out an Eclipse book and have a go at that.


I did find some more javadoc doco whose existence is vaguely hinted to in the main doco.

Its on the ibtookit directory not the eclipse directory.


C:\Program Files\IBM\WBIMB\ibtoolkit\eclipse\plugins\com.ibm.etools.mft.api.doc_5.0.0

for anyone interested I have posted my very rough DB dump code that handles the blobs etc..

Code:

package db;

import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.HashMap;
import java.util.Map;

import junit.framework.TestCase;

/**
 * @author bbake
 *
 * To change this generated comment edit the template variable "typecomment":
 * Window>Preferences>Java>Templates.
 * To enable and disable the creation of type comments go to
 * Window>Preferences>Java>Code Generation.
 */
public class TestDBConnection extends TestCase {

   /**
    * Constructor for TestDBConnection.
    * @param arg0
    */
   public TestDBConnection(String arg0) {
      super(arg0);
   }

   public void testDB() {

      Connection connection = null;
      try {
         String driverName = "COM.ibm.db2.jdbc.app.DB2Driver";
         Class.forName(driverName);

         String url = "jdbc:db2:WBRKBKDB";
         connection = DriverManager.getConnection(url, null, null);

         System.out.println("Connected to " + url);
      } catch (Exception e) {
         e.printStackTrace();
         return;
      }
      
      dumpTable(connection,"DB2ADMIN.BCLIENTUSER");
      dumpTable(connection,"DB2ADMIN.BMULTICASTTOPICS");
      dumpTable(connection,"DB2ADMIN.BNBRCONNECTIONS");
      dumpTable(connection,"DB2ADMIN.BPUBLISHERS");
      dumpTable(connection,"DB2ADMIN.BRETAINEDPUBS");
      dumpTable(connection,"DB2ADMIN.BRMINFO");
      dumpTable(connection,"DB2ADMIN.BRMINFO");
      //dumpTable(connection,"DB2ADMIN.BRMPHYSICALRES"); large DICTIONARY BASED INFO
      dumpTable(connection,"DB2ADMIN.BRMRTDINFO");
      dumpTable(connection,"DB2ADMIN.BRMWFDINFO");
      dumpTable(connection,"DB2ADMIN.BROKERAA");
      dumpTable(connection,"DB2ADMIN.BROKERAAEG");
      dumpTable(connection,"DB2ADMIN.BSUBSCRIPTIONS");
      
      dumpTable(connection,"DB2ADMIN.BROKERRESOURCES"," where RESOURCETYPE = 'MessageFlow'");
   }
   
   private void dumpTable(Connection connection, String tableName) {
      dumpTable(connection, tableName, null);
   }
   
   private void dumpTable(Connection connection, String tableName, String sqlConditions) {
      Statement stmt;
      ResultSet rs;
      try {
         String sqlQuery = "SELECT * FROM " + tableName;
         if (sqlConditions != null) {
            sqlQuery += " " + sqlConditions;
         }
            
         stmt = connection.createStatement();
         rs = stmt.executeQuery(sqlQuery);
         dumpRS(rs,tableName);

      } catch (Exception e) {
         e.printStackTrace();
         return;
      }
   }

   private void dumpRS(ResultSet rs, String tableName) throws SQLException {
      System.out.println();
      System.out.println();
      System.out.println();
      System.out.println();
      System.out.println("=================================");
      System.out.println(tableName);
      System.out.println("=================================");
      
      ResultSetMetaData rsmd = rs.getMetaData();
      int rowCount = 0;
      int numberOfColumns = rsmd.getColumnCount();
      while (rs.next()) {
         rowCount++;
         System.out.println("Row " + rowCount);
         System.out.println("_________________________________");

         for (int i = 1; i <= numberOfColumns; i++) {
            int columnType = rsmd.getColumnType(i);
            String columnName = rsmd.getColumnName(i);

            Object obj = rs.getObject(i);

            System.out.print(columnName);
            System.out.print(" (");
            System.out.print(toTypeName(columnType));
            System.out.print(")");
            if (obj != null) {
               //System.out.print(obj.getClass().getName());
               System.out.print("{");
               System.out.print(obj.getClass());
               System.out.print("}");
            }
            System.out.print(" = ");
            System.out.print(obj);
            System.out.println();

            if (columnType == Types.BINARY && obj != null) {
               dumpBinary(obj);
            }
            if (columnType == Types.VARBINARY && obj != null) {
               dumpBinary(obj);
            }
            if (columnType == Types.BLOB && obj != null) {
               dumpBlob(obj);
            }

            System.out.println();
         }
         System.out.println();
      }
      System.out.println("=================================");
      System.out.println(rowCount + " row(s)");
      System.out.println("=================================");
   }

   private void dumpBinary(Object objValue) {
      if (objValue instanceof byte[]) {
         byte[] bytes = (byte[]) objValue;
         try {
            System.out.println("Raw Bytes : " + dumpBytes(bytes));
            
            String byteStr = new String(bytes);
            System.out.println("Raw Str : " + byteStr);
         } catch (Exception e) {
            System.out.println(e);
         }
      }
   }

   private void dumpBlob(Object objValue) {
      if (objValue instanceof Blob) {
         Blob blob = (Blob) objValue;
         try {
            long blobLength = blob.length();
            // Get bytes from the BLOB in a byte array
            int pos = 1; // position is 1-based
            byte[] blobBytes;

            System.out.println("BLOB (length=" + blobLength + ")________________________");

            int bytesRequired = (int) blobLength;
            while (bytesRequired > 0) {
               int len = (int) Math.min(bytesRequired,150);
               blobBytes = blob.getBytes(pos, len);
               String blobStr = new String(blobBytes);
               System.out.println(blobStr);
               
               bytesRequired -= blobBytes.length;
               pos += blobBytes.length;
            }
            
         } catch (SQLException e) {
            System.out.println(e);
         }
      }
   }

   private static final Map typeMap = new HashMap();
   static {
      typeMap.put(String.valueOf(Types.ARRAY), "ARRAY");
      typeMap.put(String.valueOf(Types.BIGINT), "BIGINT");
      typeMap.put(String.valueOf(Types.BINARY), "BINARY");
      typeMap.put(String.valueOf(Types.BIT), "BIT");
      typeMap.put(String.valueOf(Types.BLOB), "BLOB");
      typeMap.put(String.valueOf(Types.CHAR), "CHAR");
      typeMap.put(String.valueOf(Types.CLOB), "CLOB");
      typeMap.put(String.valueOf(Types.DATE), "DATE");
      typeMap.put(String.valueOf(Types.DECIMAL), "DECIMAL");
      typeMap.put(String.valueOf(Types.DOUBLE), "DOUBLE");
      typeMap.put(String.valueOf(Types.FLOAT), "FLOAT");
      typeMap.put(String.valueOf(Types.INTEGER), "INTEGER");
      typeMap.put(String.valueOf(Types.JAVA_OBJECT), "JAVA_OBJECT");
      typeMap.put(String.valueOf(Types.LONGVARBINARY), "LONGVARBINARY");
      typeMap.put(String.valueOf(Types.LONGVARCHAR), "LONGVARCHAR");
      typeMap.put(String.valueOf(Types.REAL), "REAL");
      typeMap.put(String.valueOf(Types.REF), "REF");
      typeMap.put(String.valueOf(Types.SMALLINT), "SMALLINT");
      typeMap.put(String.valueOf(Types.STRUCT), "STRUCT");
      typeMap.put(String.valueOf(Types.TIME), "TIME");
      typeMap.put(String.valueOf(Types.TIMESTAMP), "TIMESTAMP");
      typeMap.put(String.valueOf(Types.TINYINT), "TINYINT");
      typeMap.put(String.valueOf(Types.VARBINARY), "VARBINARY");
      typeMap.put(String.valueOf(Types.VARCHAR), "VARCHAR");
   }
   
   private String dumpBytes(byte[] bytes) {
      StringBuffer sb = new StringBuffer();
      for (int i = 0; i < bytes.length; i++) {
         byte b =  bytes[i];
         String firstNibble = Integer.toHexString(b & 0xF0).toLowerCase();
         String secondNibble = Integer.toHexString(b & 0x0F).toLowerCase();
         sb.append(firstNibble.substring(0,1));
         sb.append(secondNibble.substring(0,1));
      }
      return sb.toString();
   }


   private String toTypeName(int sqlType) {
      String typeName = (String) typeMap.get(String.valueOf(sqlType));
      if (typeName == null)
         return "UNKNOWN:" + sqlType;
      else
         return typeName;
   }
Back to top
View user's profile Send private message
bbakerman
PostPosted: Thu Oct 27, 2005 9:43 pm    Post subject: Reply with quote

Apprentice

Joined: 17 Dec 2003
Posts: 41

For the record I found an article that discusses creating your own custom nodes and specifically about creating your own custom property editors.


http://www-128.ibm.com/developerworks/websphere/library/techarticles/0504_belyavsky/0504_belyavsky.html
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic  Reply to topic Page 1 of 1

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » Where to find more info on creating custom property editors
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.