4.2 Sample UCX Component

text goes here

4.2.1 Prerequisites for building UCX Components

CodeWarrior or Watcom compiler along with the NetWare NLM SDK files is required to build the UCX components.

4.2.2 Sample

This section provides a sample component to demonstrate the creation of UCX components.

The steps involved in creating an UCX component are

Source Files

The following directories are created during the installation.

  1. SYS:NSN\SDK\IMP - Import files required for creation of UCX components.

  2. SYS:NSN\SDK\INCLUDE - Include files required to build the UCX components.

  3. SYS:NSN\SDK\C\CW - CodeWarrior project for the sample component.

  4. SYS:NSN\SDK\C\WATCOM - Watcom make file for building the component using Watcom.

  5. SYS:NSN\SDK\C\SRC - Sample component C source file and an ASP file which uses the component

Build Instructions

text goes here

CodeWarrior Build

Proceed with the following steps to build the component using CodeWarrior.

  1. Open the CodeWarrior make file.

  2. Set the paths properly to include and library directory.

  3. Select Make.

Watcom Build

Proceed with the following steps to build the component using Watcom.

  1. In the command (MS-DOS) prompt change the working directory to watcom.

  2. Open the batch file BUILD.BAT and set the path to the directory in which the watcom binaries are present.

  3. Execute the batch file.

    NOTE:You can also build the NLM by executing the command wmake -f <make file name>

Creating a Sample Component

For creating an UCX component a clear component design document explaining the required properties, methods and sub objects of the component should be available.

Proceed with the following steps for creating an UCX component based on a specific design. The design of sample component is assumed for this purpose. Sample Design Document will provide more details on creating a design for a UCX component.

  1. Create a C file and include the standard header files and the standard UCX macros.

    #include <stdio.h>
    #include <string.h>
    #include "ucx.h"
    
    
    
    UCXSTDPROCS();
    UCXDEFINELIB();
    UCXUNLOADERPROC();
    

    The macros, UCXSTDPROCS(), UCXDEFINELIB () and UCXUNLOADERPROC () define the required functions and the UCX component structure.

  2. Define the parameters for the methods of the component.

    // Parameter description for methods of Employees object
    // Parameters for ITEM Method
    
    UCXParameter EmployeesItemParams[] = {
    // Param Type       Param Name
       {UCX_OBJECT_TYPE,    (CHAR_PTR)"Employee"}, 
       {UCX_ANY_TYPE,       (CHAR_PTR)"Index" },
       {NULL,                NULL}
    };
    
    etc
    
  3. Declare the method list.Organize the methods in the ascending order of the method name.

    enum
    {
     HASMOREELEMENTS,
       ITEM,
       NEXT,
       RESET,
             
    };
    
    // Employees  Methods
    
    UCXMethod EmployeesMethods[] = { 
    //   Name of the method         Index(enum) of the method
    Parameter block 
        {(CHAR_PTR)"HASMOREELEMENTS",   HASMOREELEMENTS,   
    EmployeesHasMoreElementsParams},
        {(CHAR_PTR)"ITEM",         ITEM,         EmployeesItemParams}, 
        {(CHAR_PTR)"NEXT",       NEXT,   EmployeesNextParams},
    (CHAR_PTR)"RESET", RESET, EmployeesResetParams},
        {NULL, NULL, NULL}
    };
    
  4. Declare the property list.

    // Properties list of Company object
    
    UCXProperty CompanyPropertyList[] = {
    //Property Type Name of Property  Scope (PRIVATE/PUBLIC)
      { UCX_STRING_TYPE, CHAR_PTR)"NAME",UCX_PUBLIC },
      { UCX_STRING_TYPE, (CHAR_PTR)"ADDRESS", UCX_PUBLIC },
      { UCX_OBJECT_TYPE,  (CHAR_PTR)"EMPLOYEES",UCX_PUBLIC },
    { 0, NULL, 0 }
    
    };
    
  5. Declare the constant list.

    // Constant list 
    UCXConstant CompanyConstantList[] = {
      { UCX_INTEGER_TYPE, (CHAR_PTR)"ENGG_DEPT",(CHAR_PTR)"1"},
      { UCX_INTEGER_TYPE, (CHAR_PTR)"HR_DEPT", (CHAR_PTR)"2"},
      { UCX_INTEGER_TYPE, (CHAR_PTR)"ADMIN_DEPT",
    (CHAR_PTR)"3"},
      {0, NULL, NULL}
    };
    
  6. Declare the Events parameters and event list if the component raises events.

  7. Repeat all the steps from Step 2 to Step 6 for all the sub objects.

  8. Declare the class list.

    //Class list 
    
    static UCXClass CompanyClassList[] =  {
    {(CHAR_PTR)"UCX:COMPANY", 0, 0, 0, 0, &MyLib,NULL, NULL,
    CompanyPropertyList, CompanyLibProc , (CHAR_PTR)"NAME"},
    {(CHAR_PTR)"UCX:EMPLOYEES", 0, 0, 0, 0, &MyLib,
    EmployeesMethods, NULL,EmployeesPropertyList, 
    EmployeesLibProc },
    {(CHAR_PTR)"UCX:EMPLOYEE", 0, 0, 0, 0,
    &MyLib,EmployeeMethods, NULL, EmployeePropertyList, 
    EmployeeLibProc , (CHAR_PTR)"NAME"},
    {NULL}
    };
    
  9. Include the main function which takes care of registration of the component with the UCX library manager. Standard UCX macros can be used for this purpose.

    // main block entry point
    
    UCXENTRY(EMPLOYEE)
    // Initialization and component registration is done here
    {
       UCXINITLIBRARY2( CompanyClassList, 
       (CHAR_PTR) "COMPANY",
       (CHAR_PTR) "Company Object",
       (CHAR_PTR) "----------------------------",
       (CHAR_PTR) "Copyright (c) 2000 Novell Inc. ,    All 
        Rights Reserved.");
    
       UCXREGISTERLIBRARY();
    }
    
  10. Write the library procedure for the classes one by one. Include the code for performing various activities for getting and setting properties and invocation of methods.

    static UCX_API CompanyLibProc(void *CP, void *params,
    CHAR_PTR FN, uint32 Event, UCXClassLink *ClassLink, void
    *Object)
    { 
      void  *Object_ptr = NULL ;
    
       switch( Event )
       {
    
      // Export constants. These constants can be used as script
    constants.
        case UCX_EVENT_CONSTANT:
          return ( CompanyConstantList );
        break;
        
    // Instantiate object
        case UCX_EVENT_OBJECT_CREATE:
         {
       
    // Initialize the properties while creating the object.
    // Return TRUE if object creation is success otherwise
    return FALSE.
           UCXSetStringProperty(CP,Object,"NAME",COMPANY_NAME);
    UCXSetStringProperty(CP,Object,"ADDRESS",COMPANY_ADDRESS
    ); 
      return UCXCreateBoolean(CP, TRUE, FN);
         }
          break;
       
    // Object getting destroyed. Do any necessary cleanup.
        case UCX_EVENT_OBJECT_DESTROY:
        
          break;
    
     // Get property value
        case  UCX_EVENT_PROPERTY_GET:  
    
      // Identify the name of the property and perform the
    action.
          if(strcmp ((const char *)FN , "EMPLOYEES") == 0)
        {
    
    // Employees is the sub object. Create the sub object and
    return the object.
    // If required you can pass the arguments while creating
    the sub objects
          if((Object_ptr = UCXInstantiateObject(CP,
    "UCX:EMPLOYEES",NULL,NULL))==NULL)
             {
    // Set the runtime error if the object creation fails.   UCXSetErrorText(CP, ERR_INSTAT, FN, (CHAR_PTR)"Error in
    instantiating  Object");
            return  NULL;
             }
             else 
             {
               
         return Object_ptr;
             }
         }
          
         break;
    
      // Set property value
      case UCX_EVENT_PROPERTY_SET:
        
        // Name property is read-only 
        if ((strcmp ((const char *)FN ,"NAME") == 0) || (strcmp
    ((const char *)FN , "EMPLOYEES") == 0))
        {
          UCXSetErrorText(CP, ERR_PROPERTY_RO, FN,
    (CHAR_PTR)"Property can not be set ");
          return NULL ;
        }
    
        // The default dispatch handler can set the Read write
    properties.
    // If setting the property implies an API call is being
    made, which changes the system, 
    // then identify the property similar to above IF block
    and then call the required API.
        break;
        }
        return(UCXDispatchEvent(CP, params, FN, Event,
    ClassLink, Object));
    }
    
    
    Similarly handle the event,
    
        case UCX_EVENT_EXEC:
    
          // Identify the method index which helps in using a switch
    statement
          nMethodIndex = UCXMethodIndex(CP, ClassLink->Class, FN);
          
          if( nMethodIndex == -1 )      /* didn’t find the function */
            break;
    
          switch( nMethodIndex )
          {
            
    // HasMoreElements method
            case HASMOREELEMENTS:
    
              UCXGetIntegerProperty(CP, Object, "INDEX", &nIndex);
              if ( nIndex < 10 )
                return UCXCreateBoolean(CP, TRUE, FN);
              else
                return UCXCreateBoolean(CP, FALSE, FN);
              break;
            
          }
    

    Use UCXCreate<Data Type> functions to create required UCX return type and return the value from the library procedure.

Testing the Sample Component

Proceed with the following steps to test the sample component

  1. Copy the NLM built using the Build Instructions to SYS:UCS\UCX directory on your NetWare server.

  2. Add following line to SYS:\UCS\UCX.INI

    UCX:COMPANY=SYS:UCS\UCX\COMPANY.NLM
    
  3. Copy the file COMPANY.ASP to web sever document directory. Ensure that execute bit is set for this file. Setting the execute bit can be achieved by using NetWare Enterprise Web server administration.

  4. Verify the component by executing the ASP file, COMPANY.ASP from the browser.