Sun WBEM SDK Developer's Guide

Chapter 4 Writing Client Applications

This chapter explains how to use the Client Application Programming Interfaces (APIs) to write client applications.

For detailed information on the CIM and Client APIs, see the Javadoc reference pages.

Overview

A Web-Based Enterprise Management (WBEM) application is a standard Java program that uses Sun WBEM SDK APIs to manipulate CIM objects. A client application typically uses the CIM API to construct an object (for example, a namespace, class, or instance) and then initialize that object. The application then uses the Client APIs to pass the object to the CIM Object Manager and request a WBEM operation, such as creating a CIM namespace, class, or instance.

Sequence of a Client Application

Sun WBEM SDK applications typically follow this sequence:

  1. Connect to the CIM Object Manager - (CIMClient).

    A client application contacts a CIM Object Manager to establish a connection each time it needs to perform a WBEM operation, such as creating a CIM Class or updating a CIM instance.

  2. Use one or more APIs to perform some programming tasks.

    Once a program connects to the CIM Object Manager, it uses the APIs to request operations.

  3. Close the client connection to the CIM Object Manager - (close).

    Applications should close the current client session when finished. Use the CIMClient interface to close the current client session and free any resources used by the client session.

Example — Typical Sun WBEM SDK Application

Example 4–1 is a simple application that connects to the CIM Object Manager, using all default values. The program gets a class and then enumerates and prints the instances in that class.


Example 4–1 Typical Sun WBEM SDK Application

import java.rmi.*;
import com.sun.wbem.client.CIMClient;
import com.sun.wbem.cim.CIMInstance;
import com.sun.wbem.cim.CIMValue;
import com.sun.wbem.cim.CIMProperty;
import com.sun.wbem.cim.CIMNameSpace;
import com.sun.wbem.cim.CIMObjectPath;
import com.sun.wbem.cim.CIMClass;
import com.sun.wbem.cim.CIMException;
import java.util.Enumeration;
 
/**
 * Returns all instances of the specified class.
 * This method takes two arguments: hostname (args[0]) 
 * and name of class to list (args[1]). 
 */
public class WBEMsample {
    public static void main(String args[]) throws CIMException {
        CIMClient cc = null;
            try {
                /* args[0] contains the namespace. We create
                a CIM namespace (cns) pointing to the default
	              root\cimv2 namespace on the specified host. *	/
						   CIMNameSpace cns = new CIMNameSpace(args[0]);
						   /* Connect to the CIM Object manager and pass it 
							 the namespace object containing the namespace. */
						   cc = new CIMClient(cns, "root", "root_password");
						   /* Create a CIMObjectPath from the class name. */
						   CIMObjectPath cop = new CIMObjectPath(args[1]);
						   /* Get the class, including qualifiers, 
	              class origin, and properties. */
	              cc.getClass(cop, true, true, true, null);
                // Return all instances names belonging to the class.
                Enumeration e = cc.enumerateInstanceNames(cop);
                while(e.hasMoreElements()) {
                    CIMObjectPath op = (CIMObjectPath)e.nextElement();
                    System.out.println(op);
                  } // end while
	  	        } catch (Exception e) {
                System.out.println("Exception: "+e);
            }
            if(cc != null) {
               cc.close();
            } 
     } // end main
 } // end WBEMsample


Typical Programming Tasks

Once a client application connects to the CIM Object Manager, it uses the API to request operations. The program's feature set determines which operations it needs to request. The typical tasks that most programs perform are:

In addition, applications may occasionally perform the following tasks:

Opening and Closing a Client Connection

The first task an application performs is to open a client session to a CIM Object Manager. WBEM Client applications request object management services from a CIM Object Manager. The client and CIM Object Manager can run on the same hosts or on different hosts. Multiple clients can establish connections to the same CIM Object Manager.

This section describes some basic concepts about namespaces and explains how to use:

Using Namespaces

Before writing an application, you need to understand the CIM concept of a namespace. A namespace is a directory-like structure that can contain other namespaces, classes, instances, and qualifier types. The names of objects within a namespace must be unique. All operations are performed within a namespace. The installation of Solaris WBEM Services creates two namespaces:

When an application connects to the CIM Object Manager, it must either connect to the default namespace (root\cimv2) or specify another namespace, for example, root\security or a namespace you created.

Once connected to the CIM Object Manager in a particular namespace, all subsequent operations occur within that namespace. When you connect to a namespace, you can access the classes and instances in that namespace (if they exist) and in any namespaces contained in that namespace. For example, if you create a namespace called child in the root\cimv2 namespace, you could connect to root\cimv2 and access the classes and instances in the root\cimv2 and root\cimv2\child namespaces.

An application can connect to a namespace within a namespace. This is similar to changing to a subdirectory within a directory. Once the application connects to the new namespace, all subsequent operations occur within that namespace. If you open a new connection to root\cimv2\child, you can access any classes and instances in that namespace but cannot access the classes and instances in the parent namespace, root\cimv2.

Connecting to the CIM Object Manager

A client application contacts a CIM Object Manager to establish a connection each time it needs to perform a WBEM operation, such as creating a CIM class or updating a CIM instance. The application uses the CIMClient class to create an instance of the client on the CIM Object Manager. The CIMClient class takes three optional arguments:

Once connected to the CIM Object Manager, all subsequent CIMClient operations occur within the specified namespace.

Examples — Connecting to the CIM Object Manager

The following examples show two ways of using the CIMClient class to connect to the CIM Object Manager.

In Example 4–2, the application takes all the default values. That is, it connects to the CIM Object Manager running on the local host (the same host the client application is running on), in the default namespace (root\cimv2), using the default user account and password, guest.


Example 4–2 Connecting to the Default Namespace

/* Connect to root\cimv2 namespace on the local 
host as user guest with password guest. */
 
cc = new CIMClient();


In Example 4–3, the application connects to the CIM Object Manager running on the local host, in the default namespace (root\cimv2). The application creates a UserPrincipal object for the root account, which has read and write access to all CIM objects in the default namespaces.


Example 4–3 Connecting to the Root Account

{
    ...

    host as root. Create a namespace object initialized with two null strings
    that specify the default host (the local host) and the default 
    namespace (root\cimv2).*/
 
    CIMNameSpace cns = new CIMNameSpace("", "");

    UserPrincipal up = new UserPrincipal("root");
	   PasswordCredential pc = new PasswordCredential("root_password"); 
    /* Connect to the namespace as root with the 
    root password. */
 
    CIMClient cc = new CIMClient(cns, up, pc");
    ...
}


In Example 4–4, the application connects to namespace A on host happy. The application first creates an instance of a namespace to contain the string name of the namespace (A). Next the application uses the CIMClient class to connect to the CIM Object Manager, passing it the namespace object, user name, and host name.


Example 4–4 Connecting to a Non-Default Namespace

{
    ...
    /* Create a namespace object initialized with A 
    (name of namespace) on host happy.*/
    CIMNameSpace cns = new CIMNameSpace("happy", "A");
    UserPrincipal up = new UserPrincipal("Mary");
    PasswordCredential pc = new PasswordCredential("marys_password");
     
    // Connect to the namespace as user Mary.
    cc = new CIMClient(cns, "Mary", "marys_password");
    ...

} 



Example 4–5 Authenticating as an RBAC Role Identity

Authenticating a user's role identity requires using the SolarisUserPrincipal and SolarisPasswordCredential classes. The following examples authenticates as Mary and assumes the role Admin.

{
...
CIMNameSpace cns = new CIMNameSpace("happy", "A");
SolarisUserPrincipal sup = new SolarisUserPrincipal("Mary", "Admin");
SolarisPasswordCredential spc = new
        SolarisPasswordCredential("marys_password", "admins_password");
CIMClient cc = new CIMClient(cns, sup, spc);


Closing a Client Connection

Applications should close the current client session when finished. Use the close method to close the current client session and free any resources used by the client session. The following sample code closes the client connection. The instance variable cc represents this client connection.

cc.close();

Working with Instances

This section describes how to create a CIM instance, delete a CIM instance, and update an instance (get and set the property values of one or more instances).

Creating an Instance

Use the newInstance method to create an instance of an existing class. If the existing class has a key property, an application must set it to a value that is guaranteed to be unique. As an option, an instance can define additional qualifiers that are not defined for the class. These qualifiers can be defined for the instance or for a particular property of the instance and do not need to appear in the class declaration.

Applications can use the getQualifiers method to get the set of qualifiers defined for a class.

Example — Creating an Instance

The code segment in Example 4–6 uses the newInstance method to create a Java class representing a CIM instance (for example, a Solaris package) from the Solaris_Package class.


Example 4–6 Creating an Instance (newInstance())

...
{ 
/*Connect to the CIM Object Manager in the root\cimv2 
namespace on the local host. Specify the username and password of an 
account that has write permission to the objects in the 
root\cimv2namespace. */
 
CIMClient cc = new CIMClient(cns, "root", "root_password");
 
// Get the Solaris_Package class
cimclass = cc.getClass(new CIMObjectPath("Solaris_Package"), true, true, true, null);
 
/* Create a new instance of the Solaris_Package 
 class populated with the default values for properties. If the provider
 for the class does not specify default values, the values of the 
 properties will be null and must be explicitly set. */
 
 ci = cimclass.newInstance();
}
... 


Deleting an Instance

Use the deleteInstance method to delete an instance.

Example — Deleting an Instance

The example in Example 4–7 connects the client application to the CIM Object Manager and uses the following interfaces to delete all instances of a class:


Example 4–7 Deleting Instances (deleteInstance)

 
import java.rmi.*;
import com.sun.wbem.client.CIMClient;
import com.sun.wbem.cim.CIMInstance;
import com.sun.wbem.cim.CIMValue;
import com.sun.wbem.cim.CIMProperty;
import com.sun.wbem.cim.CIMNameSpace;
import com.sun.wbem.cim.CIMObjectPath;
import com.sun.wbem.cim.CIMClass;
import com.sun.wbem.cim.CIMException;
import java.util.Enumeration;
 
/**
 * This example program takes four required command-line arguments and 
 * deletes all instances of the specified class and its subclasses. The 
 * running this program must specify the username and password of an
 * account that has write permission to the specified namespace.
 * /
public class DeleteInstances {
    public static void main(String args[]) throws CIMException {
    
		// Initialize an instance of the CIM Client class
		CIMClient cc = null;
	
		// Requires 4 command-line arguments. If not all entered, prints command string.
	
		if(args.length != 4) {
	      System.out.println("Usage: DeleteClass host className username password"); 
	      System.exit(1);
		 }
		 try {
	
				 /**
				  * Creates a name space object (cns), which stores the host name
				  * (args[0]) from the command line.
				  */ 
				 CIMNameSpace cns = new CIMNameSpace(args[0]);
 
				 /** 
				  * Connects to the CIM Object Manager, and passes it the
				  * namespace object (cns) and the username (args[2]) and 
				  * password (args[3]) from the command line. 
				  */
 
				 cc = new CIMClient(cns, args[2], args[3]);
 
				 /**
				  * Construct an object containing the CIM object path
				  * of the class to delete (args[1]) from the command line.
				  */
 
				 CIMObjectPath cop = new CIMObjectPath(args[1]);
	    
				 /**
				  * Get an enumeration of the instance object paths of the 
				  * class and all subclasses of the class. An instance object 
				  * path is a reference used by the CIM Object Manager to locate
          * the instance.
			    */
	     
				 Enumeration e = cc.enumerateInstanceNames(cop);
	    
				 /**
				  * Iterate through the instance object paths in the enumeration.
				  * Construct an object to store the object path of each
				  * enumerated instance, print the instance, and then 
				  * delete it.
				  */
	 
				 while(e.hasMoreElements()) {
				     CIMObjectPath op = (CIMObjectPath)e.nextElement();
					   System.out.println(op);
					   cc.deleteInstance(op);
	    		 }
			} catch (Exception e) {
	    	    System.out.println("Exception: "+e);
			}
			if(cc != null) {
	   	    cc.close();
			}
   }
}


Getting and Setting Instances

An application frequently uses the getInstance method to retrieve CIM instances from the CIM Object Manager. When an instance of a class is created, it inherits the properties of the class it is derived from and all parent classes in its class hierarchy. The getInstance method takes the Boolean argument localOnly. If localOnly is true, getInstance returns only the non-inherited properties in the specified instance. The non-inherited properties are those defined in the instance itself. If localOnly is false, all properties in the class are returned – those defined in the instance and all properties inherited from all parent classes in its class hierarchy.

To create a new instance, use the CIMInstance method in the CIMClass class to create the instance on the local system. Then use the CIMClient.setInstance method to update an existing instance in a namespace or use the CIMClient.createInstance method to add a new instance to a namespace.

Example — Getting Instances

The code segment in Example 4–8 lists all processes on a given system. This example uses the enumerateInstanceNames method to get the names of instances of the CIM_Process class. Running this code on a Microsoft Windows 32 system returns Windows 32 processes. Running this same code on a Solaris system returns Solaris processes.


Example 4–8 Getting Instances of a Class (getInstance)

...
{
//Create namespace cns
CIMnameSpace cns = new CIMNameSpace(); 
 
//Connect to the cns namespace on the CIM Object Manager
cc = new CIMClient(cns, "root", "root_password"); 
 
/* Pass the CIM Object Path of the CIM_Process class 
to the CIM Object Manager. We want to get instances of 
this class. */ 
 
CIMObjectPath cop = new CIMObjectPath("CIM_Process"); 
 
/* The CIM Object Manager returns an enumeration of 
object paths, the names of instances of 
the CIM_Process class. */
Enumeration e = cc.enumerateInstanceNames(cop); 
 
/* Iterate through the enumeration of instance object paths.
Use the CIM Client getInstance class to get 
the instances referred to by each object name. */

while(e.hasMoreElements()) {
    CIMObjectPath op = (CIMObjectPath)e.nextElement();
    // Get the instance. Returns only the properties
		// that are local to the instance (localOnly is true).
		CIMInstance ci = cc.getInstance(op, true);
		}
...


Example — Getting a Property

Example 4–9 prints the value of the lockspeed property for all Solaris processes. This code segment uses the following methods:


Example 4–9 Printing Processor Information (getProperty)

...
{
/* Create an object (CIMObjectPath) to store the name of the
Solaris_Processor class. */ 
 
CIMObjectPath cop = new CIMObjectPath("Solaris_Processor"); 
 
/* The CIM Object Manager returns an enumeration containing the names 
of instances of the Solaris_Processor class and
all its subclasses (cc.DEEP). */
 
Enumeration e = cc.enumInstances(cop, cc.DEEP); 
 
/* Iterate through the enumeration of instance object paths.
Use the getProperty method to get the lockspeed
value for each Solaris processor. */
 
while(e.hasMoreElements()) {
			CIMValue cv = cc.getProperty(e.nextElement(), "lockspeed");
    	System.out.println(cv);
}
...
}
 


Example — Setting a Property

The code segment in Example — Setting a Property sets a hypothetical lockspeed value for all Solaris processors. This code segment uses the following methods:


Example 4–10 Setting Processor Information (setProperty)

...
{
    /* Create an object (CIMObjectPath) to store the name of the
    Solaris_Processor class. */ 
 
    CIMObjectPath cop = new CIMObjectPath("Solaris_Processor"); 
 
    /* The CIM Object Manager returns an enumeration containing the names 
    of instances of the Solaris_Processor class and
    all its subclasses. */
 
    Enumeration e = cc.enumerateInstanceNames(cop); 
 
    /* Iterate through the enumeration of instance object paths.
    Use the setProperty method to set the lockspeed
    value to 500 for each Solaris processor. */
 
    for (; e.hasMoreElements(); cc.setProperty(e.nextElement(), "lockspeed", 
        new CIMValue(new Integer(500))));
 
...
}
 


Example — Setting Instances

The code segment in Example 4–11 gets a CIM instance, updates one of its property values, and passes the updated instances to the CIM Object Manager.

A CIM property is a value used to describe a characteristic of a CIM class. Properties can be thought of as a pair of functions, one to set the property value and one to get the property value.


Example 4–11 Setting Instances (setInstance)

...
{
    // Create an object path, an object that contains the
    // CIM name for "myclass"
    CIMObjectPath cop = new CIMObjectPath("myclass"); 
    /* Get instances for each instance object path in an enumeration, 
    update the property value of b to 10 in each instance, 
    and pass the updated instance to the CIM Object Manager. */
    
    while(e.hasMoreElements()) {
		    CIMInstance ci = cc.getInstance(CIMObjectPath)(e.nextElement(), 
                true, true, true, null);
        ci.setProperty("b", new CIMValue(new Integer(10)));
				cc.setInstance(new CIMObjectPath(),ci);
		}
}
...


Enumerating Namespaces, Classes, and Instances

An enumeration is a collection of objects that can be retrieved one at a time. The Sun WBEM SDK provides APIs for enumerating namespaces, classes, and instances.

The following examples show how to use the enumeration methods to enumerate namespaces, a classes, and instances.

Deep and Shallow Enumeration

The enumeration methods take a Boolean argument that can have the value deep or shallow. The behavior of deep and shallow depends upon the particular method being used, as shown in Table 4–1.

Table 4–1 Deep and Shallow Enumeration

Method 

deep

shallow

enumNameSpace

Returns the entire hierarchy of namespaces under the enumerated namespace. 

Returns the first-level children of the enumerated namespace. 

enumClass

Returns all subclasses of the enumerated class, but does not return the class itself. 

Returns the direct subclasses of that class. 

enumInstances

Returns the class instances and all instances of its subclasses. 

Returns the instances of that class 

Getting Class and Instance Data

The following enumeration methods return the class and instance data:

Getting Class and Instance Names

CIM WorkShop is an example of an application that uses enumeration methods to return the names of classes and instances. Once you get a list of object names, you can get the instances of that object, its properties, or other information about the object.

The following enumeration methods return the names of the enumerated class or instance:

Example — Enumerating Namespaces

The sample program in Example 4–12 uses the enumNameSpace method in the CIMClient class to print the names of the namespace and all the namespaces contained within the namespace.


Example 4–12 Enumerating Namespaces (enumNameSpace)

 
import java.rmi.*;
import com.sun.wbem.client.CIMClient;
import com.sun.wbem.cim.CIMInstance;
import com.sun.wbem.cim.CIMValue;
import com.sun.wbem.cim.CIMProperty;
import com.sun.wbem.cim.CIMNameSpace;
import com.sun.wbem.cim.CIMObjectPath;
import com.sun.wbem.cim.CIMClass;
import java.util.Enumeration;
 
/ **
  * This program takes a namespace argument and calls the 
  * enumNameSpace CIMClient interface to get a list of the 
  * namespaces within the namespace specified by the CIMObjectPath,
  * (cop) and all the namespaces contained in the namespace
  * (CIMClient.DEEP).  The program then prints the name of the specified 
  * namespace (CIMClient.SHALLOW).
 /**
 
public class EnumNameSpace {
 
    // EnumNameSpace takes a string of arguments
    public static void main (String args[ ]) {
		    CIMClient cc = null;
 
			  try {    
			      // Create a namespace object for the namespace passed as an argument
			      CIMNameSpace cns = new CIMNameSpace(args[0], "");
 
			      // Connect to the CIM Object Manager in the namespace passed as an argument
			      CIMClient cc = new CIMClient(cns);
 
			      // Create an object path to store the namespace name on the current host
			      CIMObjectPath cop = new CIMObjectPath("",args[1]);
 
			      // Enumerate the namespace and all namespaces it contains 
            // (deep is set to CIMClient.DEEP)
			      Enumeration e = cc.enumNameSpace(cop, CIMClient.DEEP);
 
			      // Iterate through the list of namespaces and print each name.
			      for (; e.hasMoreElements();
						    System.out.println(e.nextElement()));
						    System.out.println("++++++");
			      // Iterate through the list of namespaces (CIMClient.SHALLOW) and 
            // print each name.
			      e = cc.enumNamesSpace(cop, CIMClient.SHALLOW);
			      for (; e.hasMoreElements();
					      System.out.println(e.nextElement()));
	       } catch (Exception e) {
				    System.out.println("Exception: "+e);
			   }
         // If the client connection is open, close it.
		     if(cc != null) {
            cc.close();
         }
     }
}
 


Example — Enumerating Class Names

A Java GUI application might use the code segment in Example 4–13 to display a list of classes and subclasses to a user.


Example 4–13 Enumerating Class Names (enumClass)

...
{
    /* Creates a CIMObjectPath object and initializes it 
    with the name of the CIM class to be enumerated (myclass). */
    CIMObjectPath cop = new CIMObjectPath(myclass); 
    
    /* This enumeration contains the names of the classes and subclasses
    in the enumerated class. */
    Enumeration e = cc.enumClass(cop, cc.DEEP);
}
... 


An application might use the code segment in Example 4–14 to display the contents of a class and its subclasses.


Example 4–14 Enumerating Class Data (enumClass)

...
{
    /* Creates a CIMObjectPath object and initializes it 
    with the name of the CIM class to be enumerated (myclass). */
     
    CIMObjectPath cop = new CIMObjectPath(myclass); 
     
    /* This enumeration contains the classes and subclasses
    in the enumerated class (cc.DEEP). This enumeration
    returns only the non-inherited methods and properties 
    for each class and subclass (localOnly is true).*/
 
    Enumeration e = cc.enumClass(cop, cc.DEEP, true);  
}
...

The sample program in Example 4–15 does a deep and shallow enumeration of classes and instances. This example also shows the use of the localOnly flag to return class and instance data, instead of returning the names of the classes and instances.


Example 4–15 Enumerating Classes and Instances

import java.rmi.*;
import com.sun.wbem.client.CIMClient;
import com.sun.wbem.cim.CIMInstance;
import com.sun.wbem.cim.CIMValue;
import com.sun.wbem.cim.CIMProperty;
import com.sun.wbem.cim.CIMNameSpace;
import com.sun.wbem.cim.CIMObjectPath;
import com.sun.wbem.cim.CIMClass;
import com.sun.wbem.cim.CIMException;
import java.util.Enumeration;
 
/** 
 * This example enumerates classes and instances. It does 
 * a deep and shallow enumeration of a class that is passed 
 * from the command line. It uses the localOnly flag to return 
 * class and instance details. 
 */
 public class ClientEnum {
     public static void main(String args[]) throws CIMException {
		     CIMClient cc = null;
			   CIMObjectPath cop = null;
			   if(args.length != 2) {
				     System.out.println("Usage: ClientEnum host className"); 
				     System.exit(1);
	    		 }
			   try {
				    // Create a CIMNameSpace object that contains the 
				    // hostname (args[0] from the command line).
	    		    CIMNameSpace cns = new CIMNameSpace(args[0]);
 
				    // Creates a client connection to the CIM Object Manager
				    // on the specified host (args[0]).
	    		    cc = new CIMClient(cns);
 
	    		    // Get the class name from the command line
	    		    cop = new CIMObjectPath(args[1]);
 
	    		    // Do a deep enumeration of the class, which
				    // returns the class names.
	    		    Enumeration e = cc.enumClass(cop, cc.DEEP);
 
	    		    // Print the names of all subclasses of the enumerated class.
	    		    for (; e.hasMoreElements(); System.out.println(e.nextElement()));
	    		        System.out.println("+++++");
 
	    		    // Do a shallow enumeration of the class, which
				    // returns the class names.
	    		    e = cc.enumClass(cop, cc.SHALLOW);
 
	    		    // Prints the names of the first-level subclasses.
	    		    for (; e.hasMoreElements(); System.out.println(e.nextElement()));
	    		        System.out.println("+++++");
 
	    		    // Do a shallow enumeration of the class, which
				    // returns the class data, not just the class
				    // name (localOnly is true).
	    		    e = cc.enumClass(cop, cc.SHALLOW, true);
 
	    		    // Prints the details of the first-level subclasses.
	    		    for (; e.hasMoreElements(); System.out.println(e.nextElement()));
	    		        System.out.println("+++++");
 
				    // Do a deep enumeration of the instances of the class, which
				    // returns the names of the instances.
	    		    e = cc.enumInstances(cop, cc.DEEP);
 
	    		    // Prints the names of all instances of the class and its subclasses.
	    		    for (; e.hasMoreElements(); System.out.println(e.nextElement()));
	    		        System.out.println("+++++");
 
				    // Do a deep enumeration of the instances of the class, which
				    // returns the actual instance data, not just the instance
				    // name. (localOnly is true).
	    		    e = cc.enumInstances(cop, cc.DEEP);
 
	    		    // Prints the details of the instances of the class and its subclasses.
	    		    for (; e.hasMoreElements(); System.out.println(e.nextElement()));
	    		        System.out.println("+++++");
 
				    // Do a shallow enumeration of the instances of the class,
				    // which returns the names of the instances.
	    		    e = cc.enumInstances(cop, cc.SHALLOW);
 
				    // Prints the names of the instances of the class.
	    		    for (; e.hasMoreElements(); System.out.println(e.nextElement()));
	    			      System.out.println("+++++");
			      } catch (Exception e) {
	    		        System.out.println("Exception: "+e);
			     }
			    // close session.
			    if(cc != null) {
	    		    cc.close();
			    }
    }
}

Querying

The enumeration APIs return all instances in a class or class hierarchy. You can choose to return the instance names or the details of the instance. Querying allows you to narrow your search by specifying a query string. You can search for instances that match a specified query in a particular class or in all classes in a particular namespace. For example, you can search for all instances of the Solaris_DiskDrive class that have a particular value for the Storage_Capacity property.

The execQuery Method

The execQuery method retrieves an enumeration of CIM instances that match a query string. The query string must be formed using the WBEM Query Language (WQL).

Syntax

The syntax for the execQuery method is:

Enumeration execQuery(CIMObjectPath relNS, java.lang.String query, int ql)

The execQuery method takes the following parameters and returns an enumeration of CIM instances:

Parameter 

Data Type 

Description 

relNS 

CIMObjectPath 

The namespace relative to the namespace to which you are connected. For example, if you are connected to the root namespace and want to query classes in the root\cimv2 namespace, you would pass new CIMObjectPath("", "cimv2");.

query 

String 

The text of the query in WBEM Query Language 

ql 

Integer constant 

Identifies the query language. WQL level 1 is the only currently supported query language. 

Example

The following execQuery call returns an enumeration of all instances of the CIM_device class in the current namespace.

cc.execQuery(new CIMObjectPath(), SELECT * FROM CIM_device, cc.WQL)

Using the WBEM Query Language

The WBEM Query Language is a subset of standard American National Standards Institute Structured Query Language (ANSI SQL) with semantic changes to support WBEM on Solaris. Unlike SQL, in this release WQL is a retreval-only language. You cannot use WQL to modify, insert, or delete information.

SQL was written to query databases, in which data is stored in tables with a row-column structure. WQL has been adapted to query data that is stored using the CIM data model. In the CIM model, information about objects is stored in CIM classes and CIM instances. CIM instances can contain properties, which have a name, data type, and value. WQL maps the CIM object model to SQL tables.

Table 4–2 Mapping of SQL to WQL Data

SQL 

Is Represented in WQL as... 

Table 

CIM class 

Row 

CIM instance 

Column 

CIM property 

Supported WQL Key Words

The Sun WBEM SDK supports Level 1 WBEM SQL, which enables simple select operations without joins. The following table describes the WQL key words supported in the Sun WBEM SDK.

Table 4–3 Supported WQL Key Words

Key Word 

Description 

AND 

Combines two Boolean expressions and returns TRUE when both expressions are TRUE. 

FROM 

Specifies the classes that contain the properties listed in a SELECT statement. 

NOT 

Comparison operator used with NULL. 

OR 

Combines two conditions. When more than one logical operator is used in a statement, OR operators are evaluated after AND operators. 

SELECT 

Specifies the properties that will be used in a query. 

WHERE 

Narrows the scope of a query. 

WBEM Query Language Operators

The following table lists the standard WQL operators that can be used in the WHERE clause of a SELECT statement.

Table 4–4 WQL Operators

Operator 

Description 

Equal to 

Less than 

Greater than 

<= 

Less than or equal to 

>= 

Greater than or equal to 

<> 

Not equal to 

Making a Data Query

Data queries are statements that request instances of classes. To issue a data query, applications use the execQuery method to pass a WBEM Query Language string to the CIM Object Manager.

The SELECT Statement

The SELECT statement is the SQL statement for retrieving information, with a few restrictions and extensions specific to WQL. Although the SQL SELECT statement is typically used in the database environment to retrieve particular columns from tables, the WQL SELECT statement is used to retrieve instances of a single class. WQL does not support queries across multiple classes.

The SELECT statement specifies the properties to query in an object specified in the FROM clause.

The basic syntax for the SELECT statement is:

SELECT instance FROM class

The following tables shows examples of using arguments in the SELECT clause to refine a search.

Table 4–5 SELECT Statement

Example Query 

Description 

SELECT * FROM class

Selects all instances of the specified class and any of its subclasses. 

SELECT PropertyA FROM class 

Selects only instances of the specified class and any of its subclasses that contain PropertyA.

SELECT PropertyA, PropertyB FROM class

Selects only instances of the specified class and any of its subclasses that contain PropertyA or PropertyB.

The WHERE Clause

You can use the WHERE clause to narrow the scope of a query. The WHERE clause can contain a property or key word, an operator, and a constant. All WHERE clauses must specify one of the predefined WQL operators.

The basic syntax for appending the WHERE clause to the SELECT statement is:

SELECT instance FROM class WHERE expression

The expression is composed of a property or key word, an operator, and a constant. You can append the WHERE clause to the SELECT statement using one of the following forms:

SELECT instance FROM class [[WHERE property operator constant]]

SELECT instance FROM class [[WHERE constant operator property]]

Valid WHERE clauses follow these rules:

Multiple groups of properties, operators, and constants can be combined in a WHERE clause using logical operators and parenthetical expressions. Each group must be joined with the AND, OR, or NOT operators as shown in the following table.

Table 4–6 Queries Using Logical Operators

Example Query 

Description 

SELECT * FROM Solaris_FileSystem WHERE Name= "home" OR Name= "files" 

Retrieves all instances of the Solaris_FileSystem class with the Name property set to either home or files.

SELECT * FROM Solaris_FileSystem WHERE (Name = “home” OR Name = “files”) AND AvailableSpace > 2000000 AND FileSystem = “Solaris” 

Retrieves disks named home and files only if they have a certain amount of available space remaining and have Solaris file systems.

Associations

This section explains the CIM concept of associations and the CIMClient methods you can use to get information about associations.

About Associations

An association describes a relationship between two or more managed resources, for example a computer and the system disk it contains. This relationship is described in an association class, a special type of class that contains an association qualifier.

An association class also contains two or more references to the CIM instances representing its managed resources. A reference is a special property type that is declared with the REF keyword, indicating that it is a pointer to other instances. A reference defines the role each managed resource plays in an association.

The following figure shows two classes, Teacher and Student. Both classes are linked by the association, TeacherStudent. The TeacherStudent association has two references: Teaches, a property that refers to instances of the Teacher class and TaughtBy, a property that refers to instances of the Student class.

Figure 4–1 An Association Between Teacher and Student

Graphic

You must delete an association before deleting one of its references. You can add or change the association between two or more objects without affecting the objects.

The Association Methods

The following methods in the CIMClient class return information about associations (relationships) between classes and instances:

Table 4–7 The CIMClient Association Methods

Method 

Description 

associators

Gets the CIM classes or instances that are associated with the specified CIM class or instance. 

associatorNames

Gets the names of the CIM classes or instances that are associated with the specified CIM class or instance. 

references

Gets the associations that refer to the specified CIM class or instance. 

referenceNames

Gets the names of the associations that refer to the specified CIM class or instance. 

Specifying the Source Class or Instance

The association methods each take one required argument, CIMObjectPath, which is the name of a source CIM class or CIM instance whose associations or associated classes or instances you want to return. If the CIM Object Manager finds no associations or associated classes or instances, it returns nothing.

If the CIMObjectpath is a class, the association methods return the associated classes and the subclasses of each associated class. If the CIMObjectpath is an instance, the methods return the associated instances and the class from which each instance is derived.

Using the Model Path to Specify an Instance

To specify the name of an instance or class, you must specify its model path. The model path for a class includes the namespace and class name. The model path for an instance uniquely identifies a particular managed resource. The model path for an instance includes the namespace, class name, and keys. A key is a property or set of properties used to uniquely identify managed resource. Key properties are marked with the KEY qualifier.

The model path \\myserver\\Root\cimv2\Solaris_ComputerSystem.Name=mycomputer: CreationClassName=Solaris_ComputerSystem has three parts:

Using the APIs to Specify an Instance

In practice, you will usually use the enumInstances method to return all instances of a given class. Then, use a loop structure to iterate through the instances In the loop, you can pass each instance to an association method. The code segment in the following example does the following:

  1. Enumerates the instances in the current class (op) and the subclasses of the current class.

  2. Uses a While loop to cast each instance to a CIMObjectPath (op),

  3. Passes each instance as the first argument to the associators method.

This code example passes null or false values for all other parameters.


Example 4–16 Passing Instances to the associators Method

 {
    ...
    Enumeration e = cc.enumInstances(op, true);
    while (e.hasMoreElements()) {
        op = (CIMObjectPath)e.nextElement();
        Enumeration e1 = cc.associators(op, null, null, 
                null, null, false, false, null);
    ...
    }           

Using Optional Arguments to Filter Returned Classes and Instances

The association methods also take the following optional arguments, which filter the classes and instances that are returned. Each optional parameter value passes its results to the next parameter for filtering until all arguments have been processed.

You can pass values for any one or a combination of the optional arguments. You must enter a value for each parameter. The assocClass, resultClass, role, and resultRole arguments filter the classes and instances that are returned. Only the classes and instances that match the values specified for these parameters are returned. The includeQualifiers, includeClassOrigin, and propertyList arguments filter the information that is included in the classes and instances that are returned.

The following table lists the optional arguments to the association methods:

Table 4–8 Optional Arguments to the Association Methods

Argument 

Type 

Description 

Value 

assocClass

String 

Returns target objects that participate in this type of association with the source CIM class or instance. If Null, does not filter returned objects by association. 

Valid CIM association class name or Null. 

resultClass

String 

Returns target objects that are instances of the resultClass or one of its subclasses, or objects that match the resultClass or one of its subclasses.

Valid name of a CIM class or Null. 

role 

String 

Specifies the role played by the source CIM class or instance in the association. Returns the target objects of associations in which the source object plays this role. 

Valid property name or Null. 

resultRole 

String 

Returns target objects that play the specified role in the association. 

Valid property name or Null. 

includeQualifiers

Boolean 

If true, returns all qualifiers for each target object (qualifiers on the object and any returned properties). If false, returns no qualifiers. 

True or False. 

includeClassOrigin 

Boolean 

If true, includes the CLASSORIGIN attribute in all appropriate elements in each returned object. If false, excludes CLASSORIGIN attributes. 

True or False. 

propertyList 

String array 

Returns objects that include only elements for properties on this list. If an empty array, no properties are included in each returned object. If NULL, all properties are included in each returned object. Invalid property names are ignored.  

If you specify a property list, you must specify a non-Null value for resultClass.

An array of valid property names. an empty array, or Null. 

Examples — associators and associatorNames Methods

The examples in this section show how to use the associators and associatorNames methods to get information about the classes associated with the Teacher and Student classes shown in the following figure. Notice that the associatorNames method does not take the arguments includeQualifiers, includeClassOrigin, and propertyList because these arguments are irrelevant to a method that returns only the names of instances or classes, not their entire contents.

Figure 4–2 Teacher-Student Association Example

Graphic

Table 4–9 associators and associatorNames Methods

Example 

Output 

Description 

associators(Teacher, null, null, null, null, false, false, null)

Student class

Returns associated classes and their subclasses.Student is linked to Teacher by the TeacherStudent association.

associators(Student, null, null, null, null,false, false, null)

Teacher, MathTeacher, and ArtTeacher classes

Returns associated classes and their subclasses. Teacher is linked to Student by the TeacherStudent association. MathTeacher and ArtTeacher inherit the TeacherStudent association from Teacher.

associatorNames(Teacher, null, null, null, null)

Name of the Student class

Returns the names of the associated classes and their subclassesStudent is linked to Teacher by the TeacherStudent association.

associatorNames(Student, null, null, null, null)

Teacher, MatchTeacher, and ArtTeacher class names.

Returns the names of the associated classes and their subclasses. Teacher is linked to Student by the TeacherStudent association. MatchTeacher and ArtTeacher inherit the TeacherStudent association from Teacher.

Examples — references and referenceNames Methods

The examples in this section show how to use the references and referenceNames methods to get information about the associations between the Teacher and Student classes in Figure 4–2. Notice that the referenceNames method does not take the arguments includeQualifiers, includeClassOrigin, and propertyList because these arguments are irrelevant to a method that returns only the names of instances or classes, not their entire contents.

Table 4–10 references and referenceNames Methods

Example 

Output 

Comments 

references(Student, null, null. false, false, null)

TeacherStudent

Returns the associations in which Student participates.

references(Teacher, null, null. false, false, null)

TeacherStudent

Returns the associations in which Teacher participates.

referenceNames(Teacher, null, null)

The name of the TeacherStudent class.

Returns the names of the associations in which Teacher participates.

Calling Methods

Use the invokeMethod interface to call a method in a class supported by a provider. To retrieve the signature of a method, an application must first get the definition of the class to which the method belongs. The invokeMethod interface takes four arguments described in the following table:

Table 4–11 Parameters to the invokeMethodMethod

Parameter 

Data Type 

Description 

name

CIMObjectPath 

The name of the instance on which the method must be invoked. 

methodName

String 

The name of the method to call. 

inParams

Vector 

Input parameters to pass to the method. 

outParams

Vector 

Output parameters to get from the method. 

The invokeMethod method returns a CIMValue. The return value is null when the method you invoke does not define a return value.

Example — Calling a Method

The code segment in Example 4–17 gets the instances of the CIM_Service class (services that manage device or software features) and uses the invokeMethod method to stop each service.


Example 4–17 Calling a Method (invokeMethod)

{
    ...
    /* Pass the CIM Object Path of the CIM_Service class 
    to the CIM Object Manager. We want to invoke a method defined in
    this class. */ 
     
    CIMObjectPath op = new CIMObjectPath("CIM_Service"); 
     
    /* The CIM Object Manager returns an enumeration of instance
    object paths, the names of instances of the CIM_Service 
    class. */
     
    Enumeration e = cc.enumInstances(op, cc.DEEP); 
     
    /* Iterate through the enumeration of instance object paths.
    Use the CIM Client getInstance class to get 
    the instances referred to by each object path. */
     
    while(e.hasMoreElements()) {
		    // Get the instance
		    CIMInstance ci = cc.getInstance(e.nextElement(), true);
		    //Invoke the Stop Service method to stop the CIM services.
		    cc.invokeMethod(ci, "StopService", null, null);
		}
}
 


Retrieving Class Definitions

Use the getClass method to get a CIM class. When a class is created, it inherits the methods and properties of the class it is derived from and all parent classes in the class hierarchy. The getClass method takes the Boolean argument localOnly. If localOnlyis true, this method returns only non-inherited properties and methods. If localOnly is false, all properties in the class are returned.

Example — Retrieving a Class Definition

The code shown in Example 4–18, uses the following methods to retrieve a class definition:


Example 4–18 Retrieving a Class Definition (getClass)

import java.rmi.*;
import com.sun.wbem.client.CIMClient;
import com.sun.wbem.cim.CIMInstance;
import com.sun.wbem.cim.CIMValue;
import com.sun.wbem.cim.CIMProperty;
import com.sun.wbem.cim.CIMNameSpace;
import com.sun.wbem.cim.CIMObjectPath;
import com.sun.wbem.cim.CIMClass;
import com.sun.wbem.cim.CIMException;
import java.util.Enumeration;
/**
 * Gets the class specified in the command line. Works in the default
 * namespace root\cimv2.
 */
public class GetClass {
    public static void main(String args[]) throws CIMException {
        CIMClient cc = null;
        try {
            CIMNameSpace cns = new CIMNameSpace(args[0]);
            cc = new CIMClient(cns);
            CIMObjectPath cop = new CIMObjectPath(args[1]);
						// Returns only the methods and properties that 
						// are local to the specified class (localOnly is true).
            cc.getClass(cop, cc.DEEP);
        } catch (Exception e) {
            System.out.println("Exception: "+e);
        }
        if(cc != null) {
            cc.close();
        }
    }
}


Handling Exceptions

Each interface has a throws clause that defines a CIM Exception. An exception is an error condition. The CIM Object Manager uses Java exception handling and creates a hierarchy of WBEM-specific exceptions. The CIMException class is the base class for CIM exceptions. All other CIM exception classes extend from the CIMException class.

Each class of CIM exceptions defines a particular type of error condition that API code handles. See Table 3–2 for a description of the CIM exception APIs.

Using the Try/Catch Clauses

The Client API uses standard Java try/catch clauses to handle exceptions. Generally, an application catches exceptions and either takes some corrective action or passes some information about the error to the user.

The CIM rules are not explicitly identified in the CIM specification. In many cases, they are implied by example. In many cases, the error code refers to a general problem, for example, a data type mismatch, but the programmer must figure out what the correct data type is for the data.

Syntactic and Semantic Error Checking

The MOF Compiler (mofc) compiles .mof text files into Java classes (bytecode). The MOF Compiler does syntactical checking of the MOF files. The CIM Object Manager does semantic and syntactical checking because it can be accessed by many different applications.

The MOF file in Example 4–19 defines two classes, A and B. If you compiled this example file, the CIM Object Manager would return a semantic error because only a key can override another key.


Example 4–19 Semantic Error Checking

Class A         \\Define Class A
 {     [Key]
int a;  
}  
Class B:A       \\Class B extends A 
{  [overrides ("c", key (false)) ]
int b;   
} 


Advanced Programming Topics

This section describes advanced programming operations and operations that you would use less frequently.

Creating a Namespace

The installation compiles the standard CIM MOF files into the default namespaces, root\cimv2 and root\security. If you create a new namespace, you must compile the appropriate CIM MOF files into the new namespace before creating objects in it. For example, if you plan to create classes that use the standard CIM elements, compile the CIM Core Schema into the namespace. If you plan to create classes that extend the CIM Application Schema, compile the CIM Application into the namespace.

Example — Creating a Namespace

The code segment in Example 4–20 uses a two-step process to create a namespace within an existing namespace.


Example 4–20 Creating a Namespace (CIMNameSpace)

{
    ...
    /* Creates a namespace object on the client, which stores parameters 
    passed to it from the command line. args[0] contains the host 
    name (for example, myhost); args[1] contains the 
    parent namespace (for example, the toplevel directory.) */
     
    CIMNameSpace cns = new CIMNameSpace (args[0], args[1]); 
     
    /* Connects to the CIM Object Manager and passes it three parameters:
    the namespace object (cns), which contains the host name (args[0]) and
    parent namespace name (args[1]), a user name string (args[3]), and a
    password string (args[4]). */
     
    CIMClient cc = new CIMClient (cns, "root", "secret");	
     
    /* Passes to the CIM Object Manager another namespace object that 
    contains a null string (host name) and args[2], the name of a 
    child namespace (for example, secondlevel). */
     
    CIMNameSpace cop = new CIMNameSpace("", args[2]);
    
    /* Creates a new namespace called secondlevel under the
    toplevel namespace on myhost./*
     
    cc.createNameSpace(cop);
    ...
} 


Deleting a Namespace

Use the deleteNameSpace method to delete a namespace.

Example — Deleting a Namespace

The sample program in Example 4–21, deletes the specified namespace on the specified host. The program takes five required string arguments (host name, parent namespace, child namespace, username, and password). The user running this program must specify the username and password for an account that has write permission to the namespace to be deleted.


Example 4–21 Deleting a Namespace (deleteNameSpace)

{
import java.rmi.*;
import com.sun.wbem.client.CIMClient;
import com.sun.wbem.cim.CIMInstance;
import com.sun.wbem.cim.CIMValue;
import com.sun.wbem.cim.CIMProperty;
import com.sun.wbem.cim.CIMNameSpace;
import com.sun.wbem.cim.CIMObjectPath;
import com.sun.wbem.cim.CIMClass;
import com.sun.wbem.cim.CIMException;
import java.util.Enumeration;
 /**
 * This example program deletes the specified namespace on the
 * specified host. The user running this program must specify 
 * the username and password for a user account that has write
 * permission for the specified namespace.
 */
 public class DeleteNameSpace {
    public static void main(String args[]) throws CIMException {
        // Initialize an instance of the CIM Client class
				CIMClient cc = null;
        // Requires 5 command-line arguments. If not all entered,
        // prints command string.
				if(args.length != 5) {
	    		    System.out.println("Usage: DeleteNameSpace host parentNS 
					          childNS username password"); 
	    			  System.exit(1);
				}
				try {
		         /**
						 * Creates a namespace object (cns), which stores the host 
						 * name and parent namespace.
						 */ 
	      			 CIMNameSpace cns = new CIMNameSpace(args[0], args[1]);
	     			/** 
						 * Connects to the CIM Object Manager, and passes it the
						 * namespace object (cns) and the username and password
	     			 * command line arguments. 
	     			 */
	     			 cc = new CIMClient(cns, args[3], args[4]);
	   			  /**
						 * Creates another namespace object (cop), which stores the
						 * a null string for the host name and a string for the
						 * child namespace (from the command line arguments).
						 */
		   			 CIMNameSpace cop = new CIMNameSpace("",args[2]);
	 					/**
						 * Deletes the child name space under the parent namespace.
	     		   */ 
	    			   cc.deleteNameSpace(cop);
				} catch (Exception e) {
	    		    System.out.println("Exception: "+e);
				}
 				// Close the session
				if(cc != null) {
	   		    cc.close();
				}
   	 }
}


Creating a Base Class

Applications can create classes using either the MOF language or the client APIs. If you are familiar with MOF syntax, use a text editor to create a MOF file and then use the MOF Compiler to compile it into Java classes. This section describes how to use the client APIs to create a base class.

Use the CIMClass class to create a Java class representing a CIM class. To declare the most basic class, you need only specify the class name. Most classes include properties that describe the data of the class. To declare a property, include the property's data type, name, and an optional default value. The property data type must be an instance of CIMDataType (one of the predefined CIM data types).

A property can have a key qualifier, which identifies it as a key property. A key property uniquely defines the instances of the class. Only keyed classes can have instances. Therefore, if you do not define a key property in a class, the class can only be used as an abstract class.

If you define a key property in a class in a new namespace, you must first compile the core MOF files into the namespace. The core MOF files contain the declarations of the standard CIM qualifiers, such as the key qualifier.

Class definitions can be more complicated, including such MOF features as aliases, qualifiers, and qualifier flavors.

Example — Creating a CIM Class

The example in Example 4–22 creates a new CIM class in the default namespace (root\cimv2) on the local host. This class has two properties, one of which is the key property for the class. The example then uses the newInstance method to create an instance of the new class.


Example 4–22 Creating a CIM Class (CIMClass)

{
...
    /* Connect to the root\cimv2 namespace 
    on the local host and create a new class called myclass */

    // Connect to the default namespace on local host. 
    CIMClient cc = new CIMClient();
 
    // Construct a new CIMClass object 
    CIMClass cimclass = new CIMClass();

    // Set CIM class name to myclass. 
    cimclass.setName("myclass"); 

    // Construct a new CIM property object
    CIMProperty cp = new CIMProperty(); 

    // Set property name
    cp.setName("keyprop"); 
     
    // Set property type to one of the predefined CIM data types.
    cp.setType(CIMDatatype.getPredefinedType(CIMDataType.STRING)); 
     
    // Construct a new CIM Qualifier object
    CIMQualifier cq = new CIMQualifier(); 
     
    // Set the qualifier name
    cq.setName("key"); 
     
    // Add the new key qualifier to the property
    cp.addQualfier(cq); 
     
    /* Create an integer property initialized to 10 */
     
    // Construct a new CIM property object
    CIMProperty mp = new CIMProperty();
     
    // Set property name to myprop
    mp.setName("myprop"); 
     
    // Set property type to one of the predefined CIM data types.
    mp.setType(CIMDatatype.getPredefinedType(CIMDataType.SINT16)); 
     
    // Initialize mp to a CIMValue that is a new Integer object 
    // with the value 10. The CIM Object Manager converts this 
    // CIMValue to the CIM Data Type (SINT16) specified for the 
    // property in the mp.setType statement in the line above. 
    // If the CIMValue (Integer 10) does not fall within the range 
    // of values allowed for the CIM Data Type of the property
    // (SINT16), the CIM Object Manager throws an exception.  
    mp.setValue(new CIMValue(new Integer(10)));
     
    /* Add the new properties to myclass and call 
    the CIM Object Manager to create the class. */
     
    // Add the key property to class object
    cimclass.addProperty(cp); 
     
    // Add the integer property to class object
    cimclass.addProperty(mp); 
     
    /* Connect to the CIM Object Manager and pass the new class */
    cc.createClass(new CIMObjectPath(),cimclass);
     
    // Create a new CIM instance of myclass
    ci = cc.newInstance(); 
     
    // If the client connection is open, close it.
		if(cc != null) {
        cc.close();
    }
}


Deleting a Class

Use the CIMClient deleteClass method to delete a class. Deleting a class removes the class, its subclasses, and all instances of the class; it does not delete any associations that refer to the deleted class.

Example — Deleting a Class

The example in Example 4–23 uses the deleteClass method to delete a class in the default namespace root\cimv2. This program takes four required string arguments (host name, class name, username, and password). The user running this program must specify the username and password for an account that has write permission to the root\cimv2namespace.


Example 4–23 Deleting a Class (deleteClass)

 
		import java.rmi.*;
		import com.sun.wbem.client.CIMClient;
		import com.sun.wbem.cim.CIMInstance;
		import com.sun.wbem.cim.CIMValue;
		import com.sun.wbem.cim.CIMProperty;
		import com.sun.wbem.cim.CIMNameSpace;
		import com.sun.wbem.cim.CIMObjectPath;
		import com.sun.wbem.cim.CIMClass;
		import com.sun.wbem.cim.CIMException;
		import java.util.Enumeration;
	 /**
		* Deletes the class specified in the command line. Works in the default
		* namespace root\cimv2.
		*/
		public class DeleteClass {
	      public static void main(String args[]) throws CIMException {
			      CIMClient cc = null;
			      if(args.length != 4) {
	   		 	      System.out.println("Usage: 
                        DeleteClass host className username password"); 
	   		 	      System.exit(1);
				    }
				    try {
	   			      /**
	     		       * Creates a namespace object (cns), which stores the host 
	     		       * name.
					       */ 
						    CIMNameSpace cns = new CIMNameSpace(args[0]);
 
	   			     /** 
						    * Connects to the CIM Object Manager, and passes it the
						    * namespace object (cns) and the username and password
	     		      * command line arguments. 
	     		      */
						    cc = new CIMClient(cns, args[2], args[3]);
 
					      /** 
						     * Create an object (CIMObjectPath) that 
						     * contains the name of the class specified in args[1].
						     */
						    CIMObjectPath cop = new CIMObjectPath(args[1]);
 
						    /**
						     * Delete the class referenced by the CIM object path.
						     */
	  		  			    cc.deleteClass(cop);
					   } catch (Exception e) {
	 		  			    System.out.println("Exception: "+e);
					   }
					   if(cc != null) {
	    				    cc.close();
				     }
  	    }
}

Working with Qualifier Types and Qualifiers

A CIM qualifier is an element that characterizes a CIM class, instance, property, method, or parameter. Qualifiers have the following attributes:

In Managed Object Format syntax, each CIM qualifier must have a CIM qualifier type declared in the same MOF file. Qualifiers do not have a scope attribute. Scope indicates which CIM elements can use the qualifier. Scope can only be defined in the qualifier type declaration; it cannot be changed in a qualifier.

The following sample code shows the MOF syntax for a CIM qualifier type declaration. This statement defines a qualifier type named key, with a Boolean data type (default value false), which can describe only a property and a reference to an object. The DisableOverride flavor means that key qualifiers cannot change their value.

Qualifier Key : boolean = false, Scope(property, reference), 
								Flavor(DisableOverride);

The following sample code shows the MOF syntax for a CIM qualifier. In this sample MOF file, key and description are qualifiers for the property test. The property data type is an integer with the value a.

{
[key, Description("test")]
int a
}

Example — Getting CIM Qualifiers

The code segment in Example 4–24 uses the CIMQualifier class to identify the CIM qualifiers in a vector of CIM elements. The example returns the property name, value, and type for each CIM Qualifier.

A qualifier flavor is a flag that governs the use of a qualifier. Flavors describe rules that specify whether a qualifier can be propagated to derived classes and instances and whether or not a derived class or instance can override the qualifier's original value.


Example 4–24 Getting CIM Qualifiers (CIMQualifier)

	{
    ...
    } else if (tableType == QUALIFIER_TABLE) {
		     CIMQualifier prop = (CIMQualifier)cimElements.elementAt(row);
		     if (prop != null) {
		         if (col == nameColumn) {
			       return prop.getName();
		      } else if (col == typeColumn) {
			        CIMValue cv = prop.getValue();
			    if (cv != null) {
			        return cv.getType().toString();
			    } else {
			        return "NULL";			
          }
	} 
... 


Example — Setting CIM Qualifiers

Example 4–25 is a code segment that sets a list of CIM qualifiers for a new class to the qualifiers in its superclass.


Example 4–25 Set Qualifiers (setQualifiers)

{   
    ...
	   try {
	       cimSuperClass = cimClient.getClass(new CIMObjectPath(scName));
	    	    Vector v = new Vector();
	    	    for (Enumeration e = cimSuperClass.getQualifiers().elements();
					        e.hasMoreElements();) { 
					    CIMQualifier qual = (CIMQualifier)((CIMQualifier)e.nextElement()).clone();
					    v.addElement(qual);
	    	    }
	    	    cimClass.setQualifiers(v); 
          } catch (CIMException exc) {
	    	        return;
		      }
    }
}
...


Sample Programs

The examples directory contains sample programs that use the client API to perform a function. You can use these examples to start writing your own applications more quickly. The sample programs are described in Chapter 7, Using Sun WBEM SDK Examples.

To run a sample program, type the command:

java program_name

For example, java createNameSpace.