0% found this document useful (0 votes)
4 views86 pages

reference

The document provides reference information for IBM Developer for z/OS, focusing on its accessibility features, application programming interfaces (APIs), and the architecture of the Common Access Repository Manager (CARMA). It outlines how to extend the CARMA plug-in, contribute actions, and create CARMA connections programmatically. The document is intended for developers looking to utilize and customize the capabilities of IBM Developer for z/OS.

Uploaded by

Catalin TOLEA
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views86 pages

reference

The document provides reference information for IBM Developer for z/OS, focusing on its accessibility features, application programming interfaces (APIs), and the architecture of the Common Access Repository Manager (CARMA). It outlines how to extend the CARMA plug-in, contribute actions, and create CARMA connections programmatically. The document is intended for developers looking to utilize and customize the capabilities of IBM Developer for z/OS.

Uploaded by

Catalin TOLEA
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 86

IBM Developer for z/OS

IBM Developer for z/OS Enterprise Edition


16.0

Reference
Last updated 2024-10-16

IBM
About this PDF
© International Business Machines Corporation 1992, 2024.

This PDF was generated from the content of the IBM® Developer for z/OS® online documentation. It is
provided for reference only. Many of the links in this PDF do not lead to a target location on the IBM
Developer for z/OS IBM Documentation site. For the most recent content, go to https://www.ibm.com/
docs/en/developer-for-zos/latest.
Some of the content in the IBM Developer for z/OS IBM Documentation site is embedded from other
IBM product documentation sites. Because of this content reuse, the embedded content might not be
included in the generated PDFs.
Reference

Reference
Review reference information for the product.

Product accessibility features


The IBM Developer for z/OS accessibility features are built on top of the client operating system and
Eclipse workbench features.
macOS
For information about accessibility support on the macOS operating system, see the macOS User
Guide, Change Keyboard settings for accessibility on Mac.
Eclipse workbench
The Eclipse workbench accessibility features help people with a physical disability, such as restricted
mobility or limited vision, or those with special needs to use software products successfully. For more
information about accessibility features, see Accessibility features in Eclipse.

Application programming interfaces


The following APIs are available with Developer for z/OS.

Extending the CARMA plug-in


The CARMA plug-in has been designed for extensibility so you can easily add custom actions. By
extending the CARMA plug-in, you can use many of the built-in features of CARMA. Alternatively, you
can make use of only the core API functionality to develop your own user interface for accessing a CARMA
host.

For most purposes, extending the CARMA plug-in should be sufficient, which has the following
advantages over creating your own user interface:
• Dialogs automatically prompt the user for return values, custom parameters, and login information as
necessary.
• It features a built-in CARMA hierarchy navigator.
• You can easily provide access to custom RAM actions through menus with minimal effort.
If you would like to extend the CARMA plug-in and are new to Developer for z/OS plug-in development,
you may want to refer to the Eclipse Platform Plug-in Developer Guide. If you would instead like to create
your own user interface for CARMA using the core API, refer to the CARMA plug-in API specification.
Tip:
Eclipse plug-in development requires the Plug-in Development perspective. This perspective is not
enabled by default in Developer for z/OS. To enable it:
1. Open the Preferences window.
2. Navigate to General > Capabilities.
3. On the Capabilities page, expand Development and select Plug-in Development.
4. Click Apply and Close.
To open the perspective, click Window (on Windows) or IBM Developer for z/OS (on macOS) >
Perspective > Open Perspective > Other, and then select Plug-in Development and click Open.

© Copyright IBM Corp. 1992, 2024 1


Before you begin development, you should understand the architecture of CARMA. For additional
information, see “CARMA architecture” on page 2.
Related concepts
“CARMA architecture” on page 2
A CARMA system requires three components in order to function properly: a CARMA hierarchy, a CARMA
transport, and a CARMA host.

Client programmer's guide


The following topics provide information for the CARMA client programmer.
• “Concepts” on page 2
• “Tasks” on page 4
• “Reference” on page 6

Concepts
The following topics provide information about the Common Access Repository Manager (CARMA)
architecture and custom parameters.
• “CARMA architecture” on page 2
• “Dealing with custom parameters” on page 3

CARMA architecture
A CARMA system requires three components in order to function properly: a CARMA hierarchy, a CARMA
transport, and a CARMA host.
A CARMA hierarchy is a client-side data structure that provides support for CARMA content navigation
and the execution of CARMA operations. CARMA operation requests are sent via a CARMA transport to a
CARMA host. A CARMA transport is a client-side communication service between CARMA hierarchies and
CARMA hosts. CARMA hosts contain the host-side CARMA service, CARMA-390, which is responsible for
managing the available content.

Figure 1. Components of a CARMA system

CARMA hierarchy
A CARMA hierarchy is a special type of tree data structure that is used to manage CARMA content. Each
CARMA hierarchy is connected with exactly one CARMA transport and exactly one CARMA host (it uses its
CARMA transport to communicate with its CARMA host). The CARMA plug-in acts as a workstation client
and provides a graphical representation of CARMA hierarchies using the CARMA Repositories view. Each
top-level node in this view represents a CARMA hierarchy.

CARMA transport
The CARMA transport is a service plug-in forDeveloper for z/OS that manages the connection between a
CARMA hierarchy and its CARMA host. Thus, the CARMA transport packages send commands from the
CARMA hierarchy and returns responses from the CARMA host. The CARMA RSE transport is used for this
purpose by the CARMA plug-in.

2 Developer for z/OS: Reference


CARMA host
A CARMA host is a host system that provides the CARMA-390 service. Each CARMA host generally has a
set of repository access managers (RAMs), which CARMA-390 uses to manage access to content.
Related concepts
“Extending the CARMA plug-in” on page 1
The CARMA plug-in has been designed for extensibility so you can easily add custom actions. By
extending the CARMA plug-in, you can use many of the built-in features of CARMA. Alternatively, you
can make use of only the core API functionality to develop your own user interface for accessing a CARMA
host.

Dealing with custom parameters


RAM developers have the ability to either customize existing CARMA actions or to create entirely new
actions. These actions can have custom parameters or return values as defined by the configuration of the
CARMA host.

There are several helper classes available so that you can easily make use of these custom actions:
CustomActionParameterManager
Queries the default, which is stored, and link values (retrieved in the order that is specified in the
CARMA preferences) against the metadata.
CustomActionParameterDialog
A convenience dialog that simply asks users to enter values for custom parameters.
CustomActionUtil
A helper class providing various convenience methods.

Using the custom action helper classes


The simplest way to obtain values for a custom parameter is to use one of the methods in
CustomActionUtil; for example, getCustomParameters:

CustomActionUtil.getCustomParameters(resource, "101");

This retrieves the custom parameters for the action with an action ID of 101 for the given resource.
If you plan on using the same task repeatedly for different, but similar, resources, you can use
getCustomParametersForTask like so:

CARMAContent[] resources = getResources();


CarmaTaskMemento taskMemento = new CarmaTaskMemento();
for (int i = 0; i < resources.length; i++) {
CustomActionUtil.getCustomParametersForTask(taskMemento, resources[i], "101");
}

In this example, taskMemento is used to store information the user has entered for use between action
invocations. If taskMemento were not to be used here, the user would be queried with the same prompts
for every resource.
If you would rather use a different mechanism to fetch parameter values (such as a different user
interface), you could interact directly with the CustomActionParameterManager class, as illustrated in the
following example:

CustomActionParameterManager manager = CustomActionParameterManager.getManager();


Object[] paramsToPass = manager.getCustomParameters(resource, actionId); // parameters to pass
to the command
//this method will tell us whether or not the manager has all the information it needs
if (manager.isPromptNeeded(resource, actionId)) {
final Action action = resource.findActionFor(actionId);

Iterator parameters = action.getParameters().iterator();

//find the parameter you want to change this way, or look for it to be null in
paramsToPass

Reference 3
int index = 0;
while (it.hasNext()) {
Parameter param = (Parameter) it.next();
if (param.getName().equals(targetName))
break;
index++;
}

paramsToPass[index] = new Boolean(false);

//optionally store the parameter for later


Object[] paramsToStore = new Object[paramsToPass.length];
for (int i = 0; i < paramsToStore.length; i++) {
paramsToStore[i] = null;
if (i == index)
paramsToStore[i] = new Boolean(false);
}
manager.setUserStoredParamValues(resource.getRepository(), paramsToStore);
}

In this example, targetName is the name of the parameter as defined by the RAM developer.
Related tasks
“Contributing an action” on page 4
You can add an action to the CARMA Repositories view menu so that the action can be run on CARMA
resources.

Tasks
The following topics provide information about the contributing actions and creating CARMA connections.
• “Contributing an action” on page 4
• “Creating a CARMA connection programmatically ” on page 6

Contributing an action
You can add an action to the CARMA Repositories view menu so that the action can be run on CARMA
resources.

Before you can contribute a CARMA action, you must have the proper foundation for extending the
Developer for z/OS CARMA plug-in. Refer to the Eclipse Platform Plug-in Developer Guide for information
on how to begin developing a plug-in extension.
To contribute a CARMA action to the Developer for z/OS CARMA plug-in, follow these steps:
1. Update your plugin.xml file to use the org.eclipse.ui.popupMenus extension point to define an
object delegate class for resources that implement either the IResource or CARMAContent interface.
Two common resource interfaces you might specify are IFile (which extends the IResource
interface) and CARMAContent. Specifying IFile as the resource object class causes your menu item
to appear on the menu in the Navigator view, on local project content, while specifying CARMAContent
as the resource object class causes your menu item to appear on the menu in the CARMA Repositories
view.
Example markup to add a menu item to the Navigator view:
You could include the following markup in your plugin.xml file if you were to define a menu item to
appear for files that are managed by CARMA in the Navigator view:

<extension point="org.eclipse.ui.popupMenus">
<objectContribution
id="com.ibm.carma.action.disconnected.iFile"
objectClass="org.eclipse.core.resources.IFile"
adaptable="true">
<filter
name="projectPersistentProperty"
value="org.eclipse.team.core.repository=com.ibm.carma">
</filter>
<action
label="ABC Action"
class="com.xyz.ABCDelegate"

4 Developer for z/OS: Reference


id="com.xyz.abc">
</action>
</objectContribution>
</extension>

Notice that the objectClass attribute of the objectContribution tag is specified to be


org.eclipse.core.resources.IFile, indicating that this menu item should appear on the menu
for the Navigator view. The id attribute of the objectContribution tag is simply a unique identifier
for your action. The specified filter tag limits the menu item to appear only for those files in the
Navigator view that are managed by CARMA. You can also add extra filter tags if necessary. Finally,
the action tag specifies the object delegate class in its class attribute.
Example markup to add a menu item to the CARMA Repositories view:
You could include the following markup in your plugin.xml file if you were to define a menu item to
appear for resources in the CARMA Repositories view:

<extension point="org.eclipse.ui.popupMenus">
<objectContribution
id="com.ibm.carma.action.disconnected.carmaContent"
objectClass="com.ibm.carma.model.CARMAContent
adaptable="true">
<filter
name="repositoryManager"
value="My RAM">
</filter>
<action
label="ABC Action"
class="com.xyz.ABCDelegate"
id="com.xyz.abc">
</action>
</objectContribution>
</extension>

Here, the objectClass attribute of the objectContribution tag is instead specified to be


com.ibm.carma.model.CARMAContent, indicating that this menu item should appear on the menu
for the CARMA Repositories view. Notice that a different filter is used in this example: This filter limits
the menu item to appear only for resources under a RAM named "My RAM". The name attribute of
the filter tag is used to specify the type of filter being applied. Refer to CarmaActionFilter for other
relevant values for the name attribute. Finally, the action tag specifies the object delegate class in its
class attribute.
2. Define your object delegate class by either implementing the IObjectActionDelegate
interface or extending CarmaObjectActionDelegate (a convenience class that implements the
IObjectActionDelegate interface).
It is recommended that your object delegate class extend CarmaObjectActionDelegate, since this
class contains many useful helper functions.
Example code for ABCDelegate:
You can use the following code as a starting point for developing your own object delegate:

public class ABCDelegate extends CarmaObjectActionDelegate {

public void run(IAction action) {


CARMAContent[] members = (CARMAContent[])
getSelectedCarmaResources().toArray(new CARMAContent[0]);

//perform task, schedule job, etc.


}

public void selectionChanged(IAction action, ISelection selection) {


super.selectionChanged(action, selection);

//this is the ID assigned by the installation of the action


action.setEnabled(!isUnsupported("101"));
}
}

The first line in the run method above obtains an array of the selected CARMA resources, which you
can then use to perform your action. You might, for example, loop through all of the selected resources

Reference 5
and set certain metadata properties. Although you only really need to override the run method, you
may also find it useful to override the selectionChanged method to update the availability of your
action as shown in the example above.
As defined in the example, selectionChanged uses the isUnsupported helper function of
CarmaObjectActionDelegate to enable the action with an action ID of 101 if the new selection of
objects supports the action. Although a value of 101 is hardcoded into the example code, it is possible
to resolve the action ID dynamically if the name of the action is known. Simply use the getActions
method of the appropriate RepositoryManager object to retrieve a list of the actions available for that
RAM, search through the list to find the appropriate action that is based on the name the action, and
then use the getActionId method to retrieve the action ID from corresponding Action object. You
might resolve the ID using this more dynamic method if you are unsure what the action ID of your
action is.
Related concepts
“Dealing with custom parameters” on page 3
RAM developers have the ability to either customize existing CARMA actions or to create entirely new
actions. These actions can have custom parameters or return values as defined by the configuration of the
CARMA host.

Creating a CARMA connection programmatically


CARMA connections are established during the creation of the root node of a CARMA hierarchy.
The root node of a CARMA hierarchy is a CARMA object, which must be configured to use a CARMA
transport during creation. To create a root node for a CARMA hierarchy and configure its CARMA transport,
follow these steps:
1. Use the factory class com.ibm.carma.CARMASystemFactory to create a CARMA object with the
getInstance method as illustrated in the following example code:

String identifier = "ConnectionIdentifier";


Map connectionProperties = new TreeMap();
// insert your code to configure the connection properties here
CARMA carma = CARMASystemFactory.getInstance().getCARMAInstance(identifier,
connectionProperties);

The identifier string must be unique to your CARMA hierarchy. Currently, the only valid transport is
the RSE transport service, which is used by default (if you are using the alternative method call that
requires a backend ID to be specified, you can select the RSE transport service by passing a backend
ID value of "com.ibm.carma.client.rse.datastore").
The connection properties map stores key-value pairs for transport configuration options. If
the required parameters for the transport you are using are not specified in the map, the
getCARMAInstance method throws a CARMAException. The RSE transport service requires that
you specify a value for the key "aliasName" in the connection properties map. For the value of the
key "aliasName", provide a name for the RSE connection to use when communicating with the CARMA
host.
2. Store a reference to your CARMA hierarchy for later retrieval in the CARMA registry:

CarmaRegistry.getRegistry().addCarma(carma);

The singleton CarmaRegistry object is used by a CARMABrowser object to maintain a list of known
CARMA connections. Events are sent to registered listeners when objects are added or removed from
the CARMA hierarchy. You can retrieve a CARMA hierarchy from the CARMA registry by passing its
identifier into the getCARMA method of the CARMA registry.
You can now connect to your CARMA object's CARMA host by using the connect method.

Reference
The following topics provide CARMA reference information.
• Client API reference
• “Other reference information” on page 7

6 Developer for z/OS: Reference


Other reference information
The following topics provide information on CARMA API rules of engagement and a mapping of which API
packages are found in which plug-ins.
• “API rules of engagement” on page 7
• “Map of plugins” on page 8

API rules of engagement


• Only the APIs exposed in the Javadoc reference are supported for programming unless otherwise noted
in the API documentation. The APIs in the Javadoc are stable and will not be removed across version
boundaries. CARMA APIs can be deprecated in future releases but should continue to be available and
usable by programmers in the future as defined by the documentation. Other APIs might be found in the
CARMA plug-ins but should be considered unsupported and subject to change in future releases.
• The CARMA model APIs (com.ibm.carma.model package) are meant to be read-only from the
programmer’s point of view, e.g., the programmer should not attempt to create/add/move items
in the CARMA model manually. The objects in the hierarchy are meant to be updated through the
refreshXXX() and createXXX() methods. Model object creation outside of using API methods is
not supported. If model objects are created outside of using API methods, then inconsistencies can
arise.
• All repository resource lists in the model are associated with a filter string. The default filter string is “*”.
• Most CARMA model methods require the connection to the CARMA host to be active when the method
is run. If the connection is not active, then a com.ibm.carma.transport.NotConnected exception
is thrown.
• CARMA methods, which need to activate the CARMA host connection have an
org.eclipse.core.runtime.IProgressMonitor parameter in the method signature. In order to
cancel execution of the method, we respect the IProgressMonitor.isCancelled() method, which
is checked during long-running method execution.
• The CARMA model serves as a cache of data for the CARMA hierarchy. It is the responsibility of the
programmer to keep the cache fresh using the refreshXXX() methods on the model.
• The CARMA model cache must be initialized. If a portion of the CARMA hierarchy which is not cached
is accessed, then a com.ibm.carma.transport.NotSynchronizedException is thrown. To repair
the exception, run a refreshXXX() method on the object.
• The objects in the CARMA Model cache are available when disconnected from the CARMA host. The
CARMA host needs to be actively connected in order to run methods against the cache objects, which
access the CARMA host.
• Model changes are communicated out to listeners via notification. The notification goes out to any
adapter listening to the model object. Listeners should be added to the model using a class which
extends org.eclipse.emf.common.notify.Adapter. This is an Eclipse Modeling Framework
(EMF) notification method. Reference the EMF documentation for more information on adapter
notification.
• The default CARMA UI (including the externalized com.ibm.carma.ui.* APIs) use a combination
of actions and jobs to run methods on the CARMA model. The Action (extending
org.eclipse.ui.IAction or org.eclipse.ui.IActionDelegate) is responsible for gathering
the needed data to run the model method. The gathered data is handed off to a CARMA UI job, which is
scheduled to run in the background when resources are available. If the model method cause updates
to the CARMA hierarchy then notifications are sent from the model to listeners, which update the UI as
needed.

Reference 7
Map of plugins
The CARMA Plug-in API is divided into a series of plug-ins. The following table shows which API packages
are found in which plug-ins. This table is useful for determining which plug-ins a given plug-in should
include as prerequisites.

API Package Required plug-in Id Notes®


com.ibm.carma.core These are the main CARMA API
com.ibm.carma
packages that are used in talking
com.ibm.carma.model
to the CARMA host
com.ibm.carma.transport

com.ibm.carma.ui[.*] com.ibm.carma.ui These packages are useful for


working with CARMA objects in
an eclipse UI

Customizing CARMA using plug-in projects tutorial


CARMA can be customized by using Eclipse plug-in projects. The following modules provide you with a
starting point in developing your own CARMA customization.
Note: Module 1-5 and 9 are independent of each other and can be completed in any order. Modules 6-8
build off of Module 5 and each other, as a result they must be completed in order. Module 9 involves some
host configuration of the Sample PDS RAM, which might involve special permissions.

Learning objectives
After completing the modules in this module, you will have an understanding of the following concepts:
• Creating an Developer for z/OS Eclipse plug-in project
• Using the plug-in Manifest Editor to add dependencies and extensions
• Use the plugin.xml file to modify extensions and their attributes
• Create packages, classes, and folders within an Eclipse plug-in project
• Create and modify Java™ classes to add enhanced functionality to the plug-ins

Time required
The time that is required to complete these modules vary. Each module contains an approximate time
required.

Prerequisites
To successfully complete the modules, you should have:
• Developer for z/OS installed on your local workspace
• Access to a z/OS host system and any required authentication
• Basic understanding of Java coding and debugging
Tip:
Eclipse plug-in development requires the Plug-in Development perspective. This perspective is not
enabled by default in Developer for z/OS. To enable it:
1. Open the Preferences window.
2. Navigate to General > Capabilities.
3. On the Capabilities page, expand Development and select Plug-in Development.
4. Click Apply and Close.
To open the perspective, click Window (on Windows) or IBM Developer for z/OS (on macOS) >
Perspective > Open Perspective > Other, and then select Plug-in Development and click Open.

8 Developer for z/OS: Reference


Create an Eclipse plug-in project
Customizing CARMA is done by creating Eclipse plug-in projects that handle the particular enhancement.
This lesson guides you through creating an Eclipse plug-in project that is specialized for this CARMA
tutorial.
To create a new Eclipse plug-in project:
1. Start Developer for z/OS.
2. Select the Desired workspace.
3. If you are starting with a clean workspace, minimize the Welcome Screen, and Create the new
Developer for z/OS Eclipse plug-in Project from the current perspective by selecting File > New >
Project.
4. In the new project wizard, select Plug-in Development > Plug-in Project. Click Next.
5. Enter the appropriate name for the project in the Project Name text field. Click Next.
6. Ensure that the names in the Plug-in ID and the Plug-in Name text fields correlate with those
specified with the particular plug-in project.
7. Keep the default settings under Plug-in Options and Rich Client Application. Click Next.
8. Clear the checkbox, Create a plug-in using one of the templates, and click Finish.
9. If you are prompted to open the Plug-ins Perspective, select Yes to open that perspective now.
The wizard closes and you see your project in the Package Explorer view of the Plug-ins Perspective.

Run and debug the plug-in project


This lesson teaches you how to run and debug the plug-in you created in the previous exercise.
To run and debug the plug-in:
1. In the Package Explorer view, make sure that there are no errors in your Eclipse plug-in project. If
there are, follow the little, red X, error icon down through the directories to the source, and correct
these errors before proceeding.
2. In the main menu bar, select the drop-down arrow beside the Run button, and select Run
Configurations from the menu.

a) To debug, you would select the down button beside the Debug icon , select Debug
Configurations, and follow the rest of the steps.
3. From the left menu, double-click on the Eclipse Application option. A new run configuration opens,
this might take a little while to open.
4. Select the Configurations tab from the top tab menu.
5. Mark the checkbox, Clear the configuration area before launching. If this is not set, Developer for
z/OS does not know how to pick up the new plug-ins you developed.
6. Click Apply to save the changes.
7. You can select which plug-ins you have developed to run in the testing workbench. To do this, select
the Plug-ins tab from the top menu.
8. In the Launch With dropdown menu, select the option: plug-ins selected below only.
9. In the panel below the dropdown menu will be a list of the various plug-ins associated with Developer
for z/OS. Find the directory that is labeled Workspace. Check the plug-ins that you want included in
your build. Clear those you do not want to be included in the build.
10. Click Run. This launches a second instance of Developer for z/OS in a testing workspace.
Note: If you have already started Developer for z/OS in the testing workspace once before, be sure to
close it out before you start it again, else you get an error.
Return to the exercise summary for steps on how to determine if your CARMA plug-in ran successfully.

Reference 9
Module 1: Adding decorators to the user interface
This module takes you through the steps to add a decorator, or image overlay, to the CARMA members
shown in the CARMA Repositories view.
You add a lock decorator to display on members when they are locked and a question mark decorator to
display on members when members need their metadata synchronized.
Note: The sample RAMs that come with Developer for z/OS do not support the Lock function. You want to
use this exercise with a RAM that supports the Lock function.

Learning objectives
After completing the lessons in this exercise, you will be able to:
• Create a Developer for z/OS plug-in Project
• Import graphics to the plug-in project
• Modify the Java Activator class, so the plug-in is able to find the necessary graphics
• Create a Java Decorator class and write code to display the appropriate graphic
• Modify the plugin.xml file to provide the org.eclipse.ui.decorators extension point
• Run and debug the sample plug-in

Time required
This module takes approximately 30 minutes to complete.

Prerequisites
To successfully complete the lessons in this module, you should have:
• Created an Eclipse plug-in project
• An accessible directory containing a graphic of a lock and a question mark, or other representative
graphics, with dimensions of approximately 11 x 13 pixels

Lesson 1: Create an icons folder and import sample graphics


In this lesson, you create an icons folder and import the sample graphics to use as your decorators.
Note: Before you complete this lesson, you should create an Eclipse plug-in project with the following
attributes:
• Project Name: com.ibm.carma.plugin.decorators
• ID: com.ibm.carma.plugin.decorators
• Name: Decorators
To create the icons folder and import the graphics:
1. In the Package Explorer view, right-click on the com.ibm.carma.plugin.decorators plugin-
project you created, and select New > Folder.
2. In the New Folder dialog box that opens, select com.ibm.carma.plugin.decorators as the
parent folder.
3. Enter icons as the name of the folder, and click Finish. You should see the icons folder appear under
your com.ibm.carma.plugin.decorators project.
4. Right click the icons folder, and select Import.
5. In the Import dialog box that opens, select General > File System. Click Next.
6. In the From Directory text field, either enter in the path name of the directory containing your graphics
or click Browse and browse for the appropriate directory. Once a directory has been specified, it
should open in the panels below the text field.
7. Select either the complete directory from the left panel or just the individual files from the right panel
to be imported. When all files that you want to import have been marked with a check, click Finish.

10 Developer for z/OS: Reference


In the Package Explorer view, expand com.ibm.carma.plugin.decorators >icons, and you should
see the graphics that you imported.

Lesson 2: Modify the Java Activator class


The Activator class is created automatically with the creation of the Eclipse plug-in project. This lesson
guides you through the steps to modify the Activator class to display the appropriate graphics as
decorators.
To update the Java Activator class:
1. In the Package Explorer view, navigate to the Activator class by expanding
com.ibm.carma.plugin.decorators > src > com.ibm.carma.plugin.decorators, and
double-click on the Activator.java file to open it in the editor.
2. Scroll down, and below the getDefault method, add the following method to the Java Activator
class:

public static ImageDescriptor getImageDescriptor(String path)


{
return imageDescriptorFromPlugin(PLUGIN_ID, path);
}

This method provides a way for the Activator class to find the graphics you plan to use as
decorators.
3. Ensure that the following classes and packages are included in the import commands. An easy way of
doing this is by right-clicking within the editor, and selecting Source > Organize Imports and verifying
all the listed import statements were included. You can also manually enter the import commands at
the top of the class with any other import commands.

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;

4. Save the Activator.java file.

Lesson 3: Create a Java Decorator class


You create the Decorator class in this lesson, which will later be responsible for placing the graphics as
decorators on CARMA members.
To create the Java Decorator class:
1. Start by setting the appropriate dependencies for the Eclipse plug-in project. Right click the
com.ibm.carma.plugin.decorators Eclipse plug-in project, and select PDE Tools > Open
Manifest. This opens the Plug-in Editor in the main editor window.
2. From the bottom menu of tabs in the Plug-in Editor, select Dependencies. This opens the plug-in
dependency editor.
3. Ensure the following plug-ins are listed in the first panel:
• org.eclipse.ui
• org.eclipse.core.runtime
• com.ibm.carma.core(9.0.0)
4. If any of the plug-ins are missing, click the Add button. In the Plug-in Selection dialog box that
opens, enter the name of the missing plug-in in the filter text field. When it appears in the panel,
select it, and click OK.
5. Now, you create a new package to contain the Decorator class. Placing relevant
Java classes together in packages helps to keep your code organized. Right click the
com.ibm.carma.plugin.decorators plug-in project, and select New Package.
6. In the New Java Package dialog box that opens, enter decorator in the Name text field, and click
Finish. You should see the package you just created appear in the src directory.
7. Right click the decorator package you created, and select New > Class.
8. In the Name text field, enter Decorator.

Reference 11
9. Next, to the Superclass text field, click Browse to browse for the class that your Descriptor class
extends.
10. In the Superclass Selection dialog box that opens, enter LabelProvider in the text field. Select
the class that is part of the org.eclipse.jface.viewers package, and click OK.
11. Next, to the Interfaces panel, click Add. In the Implemented Interfaces Selection dialog box that
opens, enter ILightweightLabelDecorator, and select the matching item that appears. Click
OK.
12. Click Finish to close out of the New Java Class dialog box.
You should see the Decorator class appear under the decorator package and the source code for the
Decorator class open in the editor.

Lesson 4: Develop the code for the Java Decorator class


In this lesson, you develop code for the Decorator class that handles the decorating of the CARMA
resources in the CARMA Repositories view.
To add this functionality to theDecorator class:
1. Between the class declaration and the decorate method, add two static ImageDescriptor
variables that contain the ImageDescriptor path names for the lock decorator and the question
mark decorator. For example:

private static ImageDescriptor lock;


private static ImageDescriptor question;
static
{
lock = Activator.getImageDescriptor("icons/lock.jpg");
question = Activator.getImageDescriptor("icons/question_mark.jpg");
}

Tip: The file names you provide should correspond with the names of the icons you imported into the
icons folder.
2. Add the code to the body of the decorate() method that adds a locked suffix to the CARMA
members and containers when they are locked, or decorate them with question marks if the
MemberInfoMap has not been set. The following pseudocode demonstrates this:

if( resource is CARMA Container or CARMA Member){


if( Member Info Map Set){
if( Member Info Map Set contains the Key “locked”){
if( value for the key “locked” is not empty string){
decorate CARMA Member/Container with lock decorator
Add “locked” suffix to CARMA Member/Container }
} else {
decorate CARMA Member/Container with question decorator
}
}
}

Use the following example sample code to implement this functionality.

public void decorate(Object resource, IDecoration decoration)


{
if(resource instanceof CARMAContainer || resource instanceof CARMAMember)
{
CARMAResource myResource = (CARMAResource) resource;
if(myResource.isSetMemberInfoMap())
{
try
{
EMap myMap = myResource.getMemberInfoMap();
if(myMap.containsKey("locked"))
{
String value = myMap.get("locked").toString();
if( !value.equals(""))
{
decoration.addOverlay(lock);
if(myResource instanceof CARMAMember)
decoration.addSuffix(" - (Member Locked)");
else
decoration.addSuffix(" - (Container Locked)");

12 Developer for z/OS: Reference


}
}
}
catch(NotSynchronizedException e)
{
//TODO handle exception
}
}
else
{
decoration.addOverlay(question);
decoration.addSuffix(" - (Not Syncronized)");
}
}
}

3. Automatically import the classes and types.


Ensure that the following imports are included:

import com.ibm.carma.plugin.decorators.Activator;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IDecoration;
import org.eclipse.jface.viewers.ILightweightLabelDecorator;
import org.eclipse.jface.viewers.LabelProvider;
import com.ibm.carma.model.CARMAMember;
import com.ibm.carma.model.CARMAContainer;
import com.ibm.carma.model.CARMAResource;
import com.ibm.carma.transport.NotSynchronizedException;
import org.eclipse.emf.common.util.EMap;

4. If the com.ibm.carma.model part of your import packages statement is still underlined in red, then
right-click on it and select the quick fix, "Add com.ibm.carma.model to list of imported packages."
5. Save the source and debug any errors.

Lesson 5: Modify the plugin.xml file


In this lesson, you modify the plugin.xml file to provide the org.eclipse.ui.decorators extension
point and attributes.
To modify the plugin.xml file:
1. In the Package Explorer view, right-click on the CARMA Decorators plug-in project, and select PDE
Tools > Open manifest. The Plug-in Editor opens.
2. To extend the plugin.xml file, select the Extensions tab from the list of tabs at the bottom.
3. Click Add. In the New Extension dialog box that opens, enter org.eclipse.ui.decorators in the
Extension Point filter text field.
4. From the results that are found, select the one that matches the filter text exactly, and click Finish.
5. The Plug-in Editor should still be open. At the bottom, select the plugin.xml tab from the bottom
menu of items. You might have to select the >> button to make this option visible. The plugin.xml
file should open in the Plug-in Editor.
6. The following skeleton code is provided already:

<plugin>
<extension
point="org.eclipse.ui.decorators">
</extension>
</plugin>

Between the open and close extension tags, place the following code:

<description
adaptable="true"
class="decorator.Decorator"
id="com.ibm.carma.ui.ftt.sample"
label="Sample Decorator"
lightweight="true"
location="BOTTOM_RIGHT"
state="true">
</description>
<enablement>
<or>

Reference 13
<objectClass name="com.ibm.carma.model.CARMAMember"/>
<ObjectClass name="com.ibm.carma.model.CARMAContainer"/>
</or>
</enablement>

Note: The information that follows the class attribute tells the plug-in what class to use and where
it is located. This location should correspond with the pkg_you_created.class_name. If you
followed the names that are provided in this tutorial, then your package and class name should be
the same as those given.
7. Click save and resolve any errors.

Summary: Module1
This module has guided you through the steps to create an Eclipse plug-in project that adds decorators to
CARMA members and containers, which are locked or unsynchronized.

Results
You should run or debug your plug-in project now. Do the following while still in the testing workspace to
verify the functionality of your plug-in:
1. Make sure that you are connected to your host system. Create a new connection if needed.
2. Open the CARMA Repositories view by selecting from the file menu, Window (on Windows) or IBM
Developer for z/OS (on macOS) > Show View > CARMA Repositories View.
3. Expand a RAM that supports the Lock option.
4. Right click a CARMA member within that RAM, and select Lock.
5. The CARMA member should lock, and your lock icon appear in the lower-right hand corner of the
CARMA member icon. For example:

Module 2: Hide or disable CARMA actions with plug-in extension points


There are several ways to develop CARMA plug-ins. This module explores hiding and disabling CARMA
actions using plug-in extension points.

Learning objectives
After completing the lessons in this module, you will be able to:
• Create an Eclipse plug-in project
• Add dependencies to a plug-in project
• Add and modify extensions that are associated with a plug-in project
• Run and debug a plug-in project

Time required
This module takes approximately 30 minutes to complete.

Prerequisites
To successfully complete the lessons in this module, you should have:
• Created an Eclipse plug-in project

Lesson 1: Add the plug-in dependencies


This lesson teaches you how to add required dependencies to your plug-in project.
The plug-in dependencies are a list of any other plug-ins that contribute code to your plug-in project or
that must be on your project's classpath in order to compile.
Note: Before you complete this lesson, you should create an Eclipse plug-in project with the following
attributes:
• Project Name: com.ibm.carma.plugin.disable.options

14 Developer for z/OS: Reference


• Plug-in ID: com.ibm.carma.plugin.disable.options
• Plug-in Name: Disable Options
To add dependencies to your plug-in:
1. Make sure that you are in the Plug-in Development perspective.
2. In the Package Explorer view, right click your Eclipse plug-in project, and select PDE Tools > Open
Manifest. The Plug-in Editor opens.
3. From the tabs at the bottom of the Plug-in Editor, select Dependencies.
4. Check to see whether the dependency, com.ibm.carma.ui is listed in the left panel. If not, click the
Add button to the right of the left panel. In the text field of the Plug-in Selection dialog box, enter in
the name of the plug-in as filter text.
5. Select the first plug-in that appears matching the filter text, and click OK.
You have now added com.ibm.carma.ui to your list of dependencies. You should see it listed in the left
panel with any other default dependencies.

Lesson 2: Use the plug-in editor to add and modify extensions


Plug-in project extensions can be used to modify actions that are associated with CARMA. The extension
that you will create in this lesson will be used to disable the Delete and Open With menu options.
You will also specify the particular RAM with which you would like to associate your plug-in project.
To create this extension:
1. From the Plug-in Editor, click the Extensions tab from the bottom menu of options.
2. Click the Add button to the right of the panel. In the New Extension dialog box that opens, enter
com.ibm.carma.ui.ramBrowserActions in the text field.
3. Select the extension matching your search query, and click Finish. You see the extension that is listed
in the panel under All Extensions. Beneath the extension listing, you should also see a (ram) listing
similar to:
4. Highlight the RAM. To the right, you should see two text fields appear, ramId and uniqueId.
5. If you know the particular ID for the RAM you would like to modify with your plug-in, you can enter
that in the ramId text field.
6. If you know which RAM you would like to modify with your plug-in, but do not know the particular ID
associated with it, use the uniqueId option.
a) Open the CARMA Repositories view by selecting from the file menu, Window (on Windows) or
IBM Developer for z/OS (on macOS) > Show View > CARMA Repositories. You can have to select
Other and browse for the particular view if it is not in the main menu.
b) If you do not have a connection to your host system already setup, you have to do that now. Open
the Remote Systems Explorer view and follow the instructions in Connecting to CARMA.
c) Expand the host system, and right-click on the particular RAM you want to modify with your
plug-in. For this tutorial, the examples use the sample PDS RAM. Select Properties.
d) In the dialog box that opens, take note of the Unique Identification value.
e) Return to the Plug-in Editor and in the uniqueId text field, enter the unique identification value
that you just found.
7. Below the ram is an action. Highlight the action, and you will see two drop-down menus appear on
the right-hand side, actionId and state.
a) The values available for actionId correspond to the five actions that can be performed in CARMA:
new, open, open with, remove, and refresh.
b) The values available for state correspond to the three states that these actions can be in:
enabled, disabled, and hidden.
8. With the first action item under the RAM highlighted, use the dropdown actionId menu to
select: com.ibm.carma.action.remove. Use the dropdown state menu to select: disable. This
disables the Delete option in the RAM's pop-up menu.

Reference 15
9. Next, you want to create a second action. In the left panel of the Plugin Editor, click the Add button.
10. In the New Extension dialog box that appears, enter the filter
com.ibm.carma.action.ramBrowserAction. Select the matching extension, and click Finish.
11. Expand the extension, and update the ramId or uniqueId to the appropriate value for your RAM.
12. Select the action below the ram. On the right-hand side, in the actionID dropdown menu, select
com.ibm.carma.action.openWith. In the state dropdown menu, select disabled. This allows
for the option Open With to be seen by the user, but will not allow it to be selected.
13. Save the changes that you made in the Plug-in Editor and resolve any errors.

Summary: Module 2
This module has guided you through the steps to create a plug-in project to disable the Delete and Open
With menu options on CARMA Members.

Results
You should run or debug your plug-in project now. Do the following while still in the testing workspace to
verify the functionality of your plug-in:
1. Make sure that you are connected to your host system.
2. Open the CARMA Repositories view.
3. Expand the RAM that you developed your plug-in to modify down to an individual member within the
RAM and right-click it.
4. Right click any member within that RAM. The menu that appears should not allow you to select the
Delete or Open With options.

Module 3: Disable CARMA actions programmatically


This module guides you through how to hide or disable CARMA actions programmatically. The result of
this module is the same as Module 2.

Learning objectives
After completing this module you should know how to:
• Create an Eclipse plug-in project
• Define the plug-in extensions and dependencies
• Modify the Activator class
• Run or Debug the Eclipse plug-in project

Time required
This module should take approximately 30 minutes to complete.

Prerequisites
To successfully complete the lessons in this module, you should have:
• Created an Eclipse plug-in project

Lesson 1: Define the extensions and dependencies for the plug-in project
This lesson guides you through defining extension points, including dependencies, creating an extension
to the plug-in, and modifying the Activator class to customize the menu options.
Note: Before you complete this lesson, you should create an Eclipse plug-in project with the following
attributes:
• Project Name: com.ibm.carma.plugin.disable.programatically
• ID: com.ibm.carma.plugin.disable.programatically
• Name: CARMA_Modify_Actions Plug-in

16 Developer for z/OS: Reference


To define the extensions and dependencies for your plug-in project:
1. Make sure that you are in the Plug-in Development perspective.
2. In the Package Explorer view, right click com.ibm.carma.plugin.disable.programatically,
your plug-in project, and select PDE Tools > Open Manifest. The Plug-in Editor opens.
3. From the list of tabs at the bottom of the Plug-in Editor, select Extensions.
4. Click the Add button on the Extensions page.
5. In the New Extension dialog box that opens, type the extension name, org.eclipse.ui.startup
in the Extension Point filter text field.
6. When this extension appears in the panel below, select it, and click Finish. You will see the extension
appear in the panel of the Extension page of the Plug-in Editor.
7. You do not need to specify any attributes to this extension. Adding this extension just tells Eclipse to
run your plug-in when the workbench starts up.
8. While you are still in the Plug-in Editor, you should also add the dependencies that the plug-in needs.
To do this, select the Dependencies tab from the bottom menu of tabs.
9. In the left panel, Required Plug-ins, make sure com.ibm.carma.ui is listed. If it is not, click Add,
and filter for the particular plug-in. Select it, and click Finish.

Lesson 2: Modify the Java Activator class


To reflect the modifications of the states and actions available to the CARMA member or container, you
need to modify the Activator class.
To modify the Java Activator class:
1. Open the Java Activator class. In the Package Editor
view, expand com.ibm.carma.plugin.disable.programatically > src >
com.ibm.carma.plugin.disable.programatically. Double-click on the Activator.java
class to open it.
2. Scroll down in the Activator class and find the start method declaration.
You want to provide code that modifies the RAMActionRegistry, where the available actions and
their states are stored, to disable the Open With option. You will also must identify the particular RAM
to which you want the modifications to be applied. This can be done with either the RAM's uniqueId
or the ramId. The following example assumes that you will use the RAM's uniqueId.
Sample code:

public void start(BundleContext context) throws Exception


{
RAMActionRegistry myRegistry = RAMActionRegistry.getRegistry();
myRegistry.setUniqueRAMActionState("com.ibm.carma.sample.PDSRAM",
"com.ibm.carma.action.remove",
RAMActionState.DISABLED);
}

Note: If you choose to use the ramId as the RAM identification, then change the fourth line of code to:

myRegistry.setRAMActionState("ramId",
"com.ibm.carma.action.openWith",
RAMActionState.DISABLED);

And provide the appropriate ramId.


3. Import the needed classes and packages which tells the Activator class where to find the other
types you mentioned in your code. Right click in the editor and select Source > Organize Imports, and
verify the packages to import.
Ensure that the following packages were imported, add any to the import commands at the top of the
Activator class if necessary:

import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import com.ibm.carma.ui.view.*;

Reference 17
4. Save the source and resolve any errors.

Summary: Module 3
This module has guided you through the steps to create a plug-in project and modify the actions available
in the menu when you right-click on CARMA members in the CARMA Repositories view.

Results:
You should run or debug your plug-in project now. Do the following while still in the testing workspace to
verify the functionality of your plug-in:
1. Make sure that you are connected to your host system
2. Open the CARMA Repositories view
3. Expand the RAM that you developed your plug-in to modify down to the individual CARMA members.
4. Right click any member within that particular RAM.
5. Attempt to select the Delete option. You should be unable to select this option.

Module 4: Adding an action to CARMA menu using plug-in extension points


In this module, you create a Browse Member Action, and add it to the CARMA menu using an extension
point. This new action allows for a CARMAMember to be selected and opened in a read-only mode.
Note: This module involves more Java coding and debugging than the previous modules.

Learning objectives
After completing this module, you should be able to:
• Create an Eclipse plug-in project
• Create Java classes to add items to the menu
• Add the action to an extension point
• Run and debug the plug-in project

Time required
This module should take approximately 45 minutes to complete.

Prerequisites
To successfully complete this module, you should have:
• Created an Eclipse plug-in project

Lesson 1: Create the BrowseMemberAction class


In this lesson, you create the Java class responsible for handling the actions that are associated with
browsing a CARMA member.
Note: Before you complete this lesson, you should create an Eclipse plug-in project with the following
attributes:
• Project Name: com.ibm.carma.plugin.browse
• ID: com.ibm.carma.plugin.browse
• Name: Browse Menu
To create the BrowseMemberAction Java class:
1. First, you want to set up the dependencies that are associated with this plug-in project. In the
Package Explorer view, right click com.ibm.carma.plugin.browse, your plug-in project, and
select PDE Tools > Open Manifest.
2. In the Plug-in Editor that opens, select Dependencies tab from the bottom menu of options.
3. In the left panel, check to seewhet the following dependencies are listed:

18 Developer for z/OS: Reference


• org.eclipse.ui.ide
• org.eclipse.core.resources
• com.ibm.carma.core
• com.ibm.carma.ui
If these dependencies are not listed, then click Add button, filter for each, and add them.
4. Save your changes.
5. Now, you create the BrowseMemberAction class. In the Package Explorer view, right click your
plug-in project and select New > Package.
6. In the New Java Package dialog box that opens, enter in browse as the package name. Expand
com.ibm.carma.plugin.browse > src, and you should see the package that is listed.
7. Right click the browse package you created, and select New > Class. The New Java Class dialog box
opens.
8. In the Name text field, enter BrowseMemberAction.
9. To the right of the Interfaces panel, select the Add button. The Implemented Interfaces Selection
dialog box opens.
10. In the text field, enter in IViewActionDelegate to filter for the appropriate interface. Select it
when it appears in the Matching items panel below the text field, and click OK.
11. Click Finish to close the New Java Class dialog box and create the Java class, which opens in the
editor.

Lesson 2: Develop code for the BrowseMemberAction class


This lesson guides you through the steps to develop the needed code for the BrowseMemberAction
class.
To develop the code for the BrowseMemberAction class:
1. Open the BrowseMemberAction class in the editor if it is not already open. In the Package
Explorer expand com.ibm.carma.plugin.browse > src > browse, and double-click on the
BrowseMemberAction class.
2. The first method that you will write is selectionChanged.
This method is used to control the items for which the browse action is enabled. In the following
example code, the browse member action is enabled only on CARMA members and only for one
member at a time. Because of this, checks must be performed before enabling the browser action. The
following pseudocode demonstrates this:

if (more than one item is selected)


disable action;

if (item selected is CARMA member)


enable action
else
disable action

Use the following sample code to implement this method:

public void selectionChanged(IAction action, ISelection selection) {


Iterator i = ((IStructuredSelection) selection).iterator();

// by default assume false


action.setEnabled(false);

if( ((IStructuredSelection) selection).size() != 1){


return;
}

while (i.hasNext()) {
Object next = i.next();
if (next instanceof CARMAMember) { // the element is a member
//remember the item selected so if the action is run it knows
//which item to run the action against
this.itemSelected = (CARMAMember) next;
} else {

Reference 19
this.itemSelected = null;
return;
}
}

// if we passed the test...then enable the action


action.setEnabled(true);
}

3. The second method that you write is the run method.


This method is called when you want to invoke the BrowserMemberAction. To open the
CARMAMember in browse-only mode, the workbench needs to download the contents of the file from
the RAM into the IFile, a type of file in Eclipse, set the IFile properties to read-only, and then open
the IFile. The following pseudocode demonstrates this:

Get the CARMAMember the user wants to browse;


Create an IFile that represents the CARMAMember;
Download contents of the CARMAMember into the IFile;
Set the properties of the IFile to read-only;
Call Eclipse to open the IFile;

Use the following sample code to implement this method:

public void run(IAction action) {


//if itemSelected is null then the browse action was run
//on something that is not a CARMA Member, this should never happen
if (this.itemSelected != null) {
//Get the name of the CARMA Member
String memberName = itemSelected.getFileName();

//Create a temporary location on the workstation to hold the


//local cache of the file
IWorkspace myWorkspace = ResourcesPlugin.getWorkspace();
IWorkspaceRoot myRoot = myWorkspace.getRoot();

IProject myResource = myRoot.getProject("/BootCampTemp");

//If the temporary directory that holds the temporary files


//does not exist create it
if( !myResource.exists() ){
try{
myResource.create(new NullProgressMonitor());
} catch(Exception e){
e.printStackTrace();
}
}

//If the temp location which is a project is not open


//open it
if( !myResource.isOpen()){
try{
myResource.open(new NullProgressMonitor());
} catch(Exception e){
e.printStackTrace();
}
}

//Make sure the temporary space is of the right type and exists
if (myResource instanceof IContainer && myResource.exists()) {
IContainer myContainer = (IContainer) myResource;

//Create the IFile in the temporary location


final IFile myFile = myContainer.getFile(new Path(memberName));

//Create the job that will get the contents of the file
GetContentsJob myJob = new GetContentsJob("CRAJOB1", itemSelected);

//Run the Job


myJob.schedule();

try{
InputStream myStream = null;
while( (myStream = myJob.getStream()) == null){
}

//Copy the contents into the IFile


if(!myFile.exists())
myFile.create(myStream, true, new NullProgressMonitor());

20 Developer for z/OS: Reference


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

//Set the file's attributes to read-only and open the file


Display display = Display.getDefault();
display.syncExec(new Runnable() {
public void run() {
IWorkbenchPage page =
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();

try {
ResourceAttributes myAttributes = myFile.getResourceAttributes();
if(myAttributes == null){
myAttributes = new ResourceAttributes();
}
//setting the attributes to readonly
myAttributes.setReadOnly(true);
try{
myFile.setResourceAttributes(myAttributes);
} catch(Exception e){
e.printStackTrace();
}
//opening the file in browse mode
IDE.openEditor(page, myFile, true);
} catch (PartInitException e) {
//TODO handle exception
System.out.println(e);
}
}
});
}
}
}

4. Verify that all the packages the class needs are imported. Add any that are listed below but are not
already included in the import statements:

import java.io.InputStream;
import java.util.Iterator;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourceAttributes;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IViewActionDelegate;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;

import com.ibm.carma.model.CARMAMember;
import com.ibm.carma.ui.job.GetContentsJob;

5. Save the source and debug any errors.

Lesson 3: Add the action to an extension point


Adding extension points to the BrowserMemberAction lets Developer for z/OS know where to
incorporate your plug-in into the rest of the system.
To add the action to an extension point:
1. In the Plug-in Development perspective, right click your Eclipse plug-in project in the Package
Explorer view and select PDE Tools > Open Manifest to open the Plug-in Editor.
2. From the bottom menu of tabs, select Extensions. Click the Add button.

Reference 21
3. In the New Extension dialog box that opens, type the filter text, org.eclipse.ui.popupMenus in
the Extension Point filter text field.
4. Highlight the extension point that matches your filter, and click Finish. You should see the extension
that you selected added to the list of extensions in the left panel on the Extensions page.
5. Now, select the plugin.xml tab from the menu options at the bottom of the Plug-in Editor.
6. Replace the existing code with the following:

<plugin>
<extension
id="carma.bootcamp.ui.actions"
point="org.eclipse.ui.popupMenus">
<objectContribution
id="CARMA.Bootcamp.browse"
objectClass="com.ibm.carma.model.CARMAMember">
<action
class="browse.BrowseMemberAction"
id="BootCamp.browse"
label="Browse Member"
menubarPath="open">
</action>
</objectContribution>
</extension>
</plugin>

Summary: Module 4
In this module, you have created a plug-in that would allow you to open a particular CARMAMember in a
read-only environment.

Results
You should run or debug your plug-in project now. Do the following while still in the testing workspace to
verify the functionality of your plug-in:
1. Make sure that you are connected to your host system.
2. Open the CARMA Repositories view.
3. Expand a RAM on your host system down until you see the individual members.

Module 5: Creating a new CARMA view using the existing CARMA context provider
This module will take you through the steps of creating a new CARMA view using the default CARMA
context provider.

Learning objectives
After completing this module, you should be able to:
• Create an Eclipse plug-in project
• Import images into the plug-in project
• Create Java classes to implement the enhanced functionality offered by the plug-in
• Run and debug the plug-in project

Time required
This module should take approximately 30 minutes to complete.

Prerequisites
To successfully complete the lessons in this module, you should have:
• Created an Eclipse plug-in project
• A image with dimensions of 16 x 16 pixels to use as the icon for your view

22 Developer for z/OS: Reference


Lesson 1: Set up dependencies, import images, and create the Java class
This lesson shows you how to add the dependencies, import images, and to create a Java class to handle
the view.
Note: Before you complete this lesson, you should create an Eclipse plug-in project with the following
attributes:
• Project Name: com.ibm.carma.plugin.view
• Plug-in ID: com.ibm.carma.plugin.view
• Plug-in Name: New View
To perform the setup for this plug-in:
1. In the Plug-in Development perspective, right-click on the com.ibm.carma.plugin.view plug-in
project and select, PDE Tools > Open Manifest. Find the Dependencies tab at the bottom of the
Plug-in Editor.
2. Select the Dependencies tab, and click the Add button. In the dialog box that opens, filter for each of
the following if they are not already listed:
• org.eclipse.ui.ide
• com.ibm.carma.ui
For each dependency, as it appears in the list, highlight it, and click OK.
3. Next, you want to import your files from the local source to the project. In the Package Explorer
view, right click com.ibm.carma.plugin.view, and select New > Folder. In the New Folder dialog
box that appears, select CARMA Developer View as the parent folder, and enter icons as the
name. Click Finish.
You should see the icons directory appear under the com.ibm.carma.plugin.view plug-in
project.
4. To import the icons, right-click on the icons directory and select Import. In the Import dialog box
that opens, select General > File System. Click Next.
5. Browse for the particular directory where your images are stored. Once you have selected the
directory, the directory structure is shown in the left panel below, and the individual files are shown
in the right. Mark the files or directories you want to import with a check mark, and click Finish to
import the files.
Back in the Package Explorer view, if you expand the icons directory, you should see your selected
files now within the directory.
6. Finally, you want to set up the Java class that handles the view. Start by creating a package to contain
the file; right-click on com.ibm.carma.plugin.view, and select New > Package.
7. In the New Java Package dialog box that opens, enter view as the package name.
You should see the package appear under the src directory of the plug-in project.
8. To add the Java class, right-click on the view package you just created, and select New > Class.
The New Java Class dialog box opens.
9. In the Name text field, enter the class name as CARMADeveloperView.
10. To the left of the Superclass text field, click Browse. The Superclass Selection dialog box opens.
11. In the text field, enter BaseCarmaBrowser. Select the class that matches your filter, and click OK.
12. Back in the New Java Class view, click Finish to create the Java class. The dialog box closes and the
class opens in the editor.

Lesson 2: Write the Java code to handle the CARMADeveloperView


You need to implement two methods to control the CARMA view, createFramelist and
createViewer.
To implement this code, you use the FrameList and Viewer class. The FrameList is a list of frames
that allow navigation through the view. The Viewer contains the structure that you see in the view.

Reference 23
For the frame list, you create a frame list for a tree viewer, which looks similar to the default CARMA
Repositories view. For the viewer, you set the content provider to the default CARMA Content Provider.
To implement the Java methods:
1. Open the CARMADeveloperView class by expanding, in the Package Explorer view,
com.ibm.carma.plugin.view > view, and double-clicking CARMADeveloperView.
2. In the editor, you want to add the createFrameList method.
This method first creates the TreeViewerFrameSource, then create a new FrameList, and then
set the source to the TreeViewerFrameSource. Use the following sample code to implement this
functionality:

protected FrameList createFrameList()


{
/*
* This code manages the front-back buttons in the view
* Will take the default tree frame listener from eclipse.
*/
TreeViewerFrameSource source = new TreeViewerFrameSource((TreeViewer)getViewer());

/* This is a TreeViewer.
* Create the frame list.
*/
FrameList frameList = new FrameList(source);
source.connectTo(frameList);

return frameList;
}

3. Next, you want to overwrite the createViewer so that it creates the CARMATreeViewer with the
default CARMAContentProvider. Use the following sample code to implement this functionality:

protected StructuredViewer createViewer(Composite parent)


{
/*
* Create the structure that you want to be present in the view here.
* The example uses the CARMA tree model like the CARMA Repositories view.
*/
CARMATreeViewer viewer = new CARMATreeViewer(parent);
return viewer;
}

4. Ensure that all classes and packages that are mentioned in the source are included in the import
commands at the beginning of the class. The easiest way to do this is to right click in the editor and
select Source > Organize Imports.
Be sure to verify that the following classes were all imported:

import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreeViewer;

import org.eclipse.swt.widgets.Composite;

import org.eclipse.ui.views.framelist.FrameList;
import org.eclipse.ui.views.framelist.TreeViewerFrameSource;

import com.ibm.carma.ui.view.BaseCarmaBrowser;
import com.ibm.carma.ui.widget.CARMATreeViewer;

5. Save your changes and debug any errors.


6. Finally, you must add the appropriate extension and configure it. In the Plug-in Editor,
select the Extensions tab at the bottom of the editor. Click Add. Filter for the extension:
org.eclipse.ui.views. When it appears, select it, and click OK. You should see the extension
that is listed in the left panel.
7. Open the plugin.xml tab from the bottom menu of tabs. Configure the plugin.xml file as follows:

<plugin>
<extension
point="org.eclipse.ui.views">
<category
name="BootCamp"

24 Developer for z/OS: Reference


id="carma.bootcamp.ui">
</category>
<view
name="CARMA Developer View"
icon="icons/sample.gif"
category="carma.bootcamp.ui"
class="view.CARMADeveloperView"
id="view.CARMADeveloperView">
</view>
</extension>
</plugin>

Note: The attributes that are used in the plugin.xml file are described in more detail below:
• Category: the attributes that are used with this markup correspond to the labeling and view of the
Show View dialog box
– Name: the name that appears as the enclosing category in the Show View dialog box
– Id: the id of the category that the view should display under when searching for it in the Show
View dialog box
• View: the attributes that are used with this markup correspond to the labeling, appearance, and
location of the source for the actual view you created
– Name: the label that is given to the view, this name appears in the tab that is associated with the
view, and also in the Show View dialog box
– Icon: the image to associate with the view, this is shown in the tab associated with the view, and
also next to its label in the Show View dialog box
– Category: the id of the category that the view should display under when searching for it in the
Show View dialog box
– Class: the Java class you wrote that controls the view, you should provide the enclosing package
as well
– Id: the unique identifier for the view

Summary: Module 5
This module has guided you through the steps to create a plug-in project that creates the CARMA
Developer View.

Results
You should run or debug your plug-in project now. Do the following while still in the testing workspace to
verify the functionality of your plug-in:
1. Open the CARMA Developer View by selecting from the main file menu, Window (on Windows) or
IBM Developer for z/OS (on macOS) > Show View > Other.
2. In the Show View dialog box that opens, enter the filter text: CARMA Developer View. You should
see this view appear.
3. Select it, and click OK.
4. Your CARMA Developer View opens. If you followed the tutorial exactly, it looks almost exactly like
the CARMA Repository View except the icon in the tab is different.

Module 6: Creating and using a custom label provider to customize a view


This module guides you through the steps of creating and using a custom label provider to customize the
CARMA view you created in Module 5.
The Label Provider controls how each item in a view is displayed. It controls the string and icon that is
displayed to identify the item. This module adds text to the CARMA Repository Manager that displays
when CARMA is connected to that RAM. It also changes the icon that is displayed for COBOL CARMA
Members.

Reference 25
Learning objectives
After completing the lessons in this module you should be able to:
• Build extra functionality on top of an existing Eclipse plug-in project
• Develop Java code to control the labels in the CARMA Developer View
• Run or debug the modified plug-in project

Time required
This module should take approximately 45 minutes to complete.

Prerequisites
To successfully complete the lessons in this module, you should have:
• Completed Exercise 5: Creating a new CARMA view using the existing CARMA context provider
• An image to use as an icon for COBOL members

Lesson 1: Set up the plug-in project from Exercise 5


This exercise builds onto of the plug-in project that you created in Exercise 5. If you have not completed
Exercise 5, do so before beginning this lesson. This lesson guides you through the steps in modifying the
plug-in that is created in Exercise 5 for Exercise 6.
To modify the plug-in project from Exercise 5:
1. Star Developer for z/OS in the Plug-in Development perspective. In the Package Explorer view, right-
click the com.ibm.carma.plugin.view plug-in project, and select PDE Tools > Open Manifest.
This opens the Plugin Manifest Editor
2. From the bottom list of tabs, select Dependencies.
3. Make sure the dependency, com.ibm.carma.ui is listed in the left panel of dependencies. If it is not,
click the Add button and use the text field to filter for the dependency. When it appears, highlight it,
and click OK.
You should see the dependency added to the list of dependencies that are listed on the left panel.

Lesson 2: Create the CustomLabelProvider class


In this lesson, you create a CustomLabelProvider class that handles how each item in the CARMA
Developer View is displayed.
To create the CustomLabelProvider class:
1. To start, add the getImageDecorator() method to the Activator class. Expand
com.ibm.carma.plugin.view > src > com.ibm.carma.plugin.view, and double-click on the
Activator class. It should open in the editor
2. Add the following method to the Activator class:

public static ImageDescriptor getImageDescriptor(String path)


{
return imageDescriptorFromPlugin(PLUGIN_ID, path);
}

This static method allows the image descriptor or decorator to be retrieved from the appropriate
location in the plug-in project.
3. Add the following import at the top of the Activator class: import
org.eclipse.jface.resource.ImageDescriptor;. Save and debug any errors in the source.
4. Next, you want to create the CustomLabelProvider class. In the Package Explorer view, expand
the com.ibm.carma.plugin.view plug-in project. Right click the view package you created in
Exercise 5, and select New > Class. The New Java Class dialog box opens.
5. In the Name text field, enter CustomLabelProvider.

26 Developer for z/OS: Reference


6. Select the Browse button to the right of the Superclass text field. In the Superclass Selection
dialog box that opens, type CARMALabelProvider as the filter text, select the class from the list of
matching items, and click OK.
7. Mark the Constructors from superclass and Inherited abstract methods checkboxes. Click Finish to
close the New Java Class dialog box and create the Java class.

Lesson 3: Develop the code for the CustomLabelProvider class


In this lesson, you develop the code for the CustomLabelProvider class, which controls how the items
in the CARMA Developer View are displayed.
To develop this code:
1. Open the ContextLabelProvider class. From the Package Explorer view, navigate
com.ibm.carma.plugin.view > src > view, and double-click on the CustomLabelProvider
class.
2. First, you want to override the getText() method. This method should check to see if a repository
manager is connected and add a label to the repository manager that shows the connected/
disconnected state.
The following is example pseudocode for the getText() method:

if(the element passed to getText is a repository manager)


{
if(the repository manager is connected)
{
add connected label to the repository manager;
}
else
{
add disconnected label to the repository manager;
}
}

Use the following example source to override the getText() method:

public String getText(Object element)


{
String textLabel = super.getText(element);
if(element instanceof RepositoryManager)
{
if( ((RepositoryManager)element).isConnected())
{
textLabel += " - (Connected)";
}
else
{
textLabel += " - (Disconnected)";
}
}

return textLabel;
}

3. The next method that you will want to override is the getImage() method. This method should
change the icon display for COBOL members.
The following is pseudocode for the getImage() method:

if( the element passed getImage is a CARMA Member)


{
if( the CARMA Member's extension is "cbl" )
{
decorate the CARMA Member;
}
}

The following is example source code for the getImage() method:

public Image getImage(Object element)


{
if(element instanceof CARMAMember)

Reference 27
{
if(((CARMAMember) element).getLocalExtension().equalsIgnoreCase("cbl"))
{
//replace the parameter of getImageDescriptor() with the path to your particular
icon
ImageDescriptor myDescriptor = Activator.getImageDescriptor("icons/cobol.gif");
return myDescriptor.createImage();
}
}
return super.getImage(element);
}

Note: The path name passed as a parameter to the getImageDescriptor method should match
your directory and image name.
4. Finally, make sure that you have the following packages that are listed in your import statements at the
top of your Java class. Add any that are missing:

import com.ibm.carma.plugin.view.Activator;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Image;

import com.ibm.carma.model.*;
import com.ibm.carma.ui.view.*;

5. Save the source and debug any errors.

Lesson 4: Edit the CARMADeveloperView class to use the CustomLabelProvider


Now that you have created the CustomLabelProvider, you want the CARMADeveloperView class to
use it. You have to edit the createViewer method to add the CustomLabelProvider object to the
viewer.
To edit the CARMADeveloperView:
1. Open the CARMADeveloperView, by double-clicking on the class in the view package of the
com.ibm.carma.plugin.view Eclipse plug-in project. It opens in the editor.
2. You want to modify the createViewer method so that it creates the view from the content provider
and then adds the CustomLabelProvider to the viewer.
Ensure that your method looks the same as the source code below.

protected StructuredViewer createViewer(Composite parent)


{
/*
* Create the structure you want to be present in the view here.
* For this tutorial, the CARMA tree model will be used, similar to what is used in the
CARMA Repositories view.
*/
CARMATreeViewer viewer = new CARMATreeViewer(parent);
viewer.setLabelProvider(new CustomLabelProvider());
return viewer;
}

3. Save the source and debug any errors.

Summary: Module 6
In this module, you have modified the Eclipse plug-in project from Module 5 to customize the view of
COBOL container members with a decorator, and label each RAM with either Connected or Disconnected
tags.

Results
You can run or debug your plug-in project now. Do the following while still in the testing workspace to
verify the functionality of your plug-in:
1. Open the z/OS Projects perspective.
2. Open the CARMA Developer view by selecting from the main file menu, Window (on Windows) or IBM
Developer for z/OS (on macOS) > Show View > CARMA Developer. The view should open.

28 Developer for z/OS: Reference


3. Expand the host system. You should see each of the RAMs on the host system marked with a label " -
(Disconnected)."
4. Right click one of the RAMs containing .cbl files and select Connect. When CARMA has connected to
the RAM, you should see the label change to " - (Connected)."
5. Lastly, expand the RAM until you see the individual COBOL members within the RAM. The icon for
these members should be the particular image that you specified.

Module 7: Creating a new view using a custom context provider


This module takes you through the steps of creating and using a custom context provider to customize a
CARMA view. The ContextProvider, which you create, controls how the context of the CARMA model
is displayed in the view. This module demonstrates how to customize the context provider to filter out
repository instances that are PDS part of the build process (that is, the listing, object, and load PDS). It
will also only show PDS that are associated with CARMA, the PDS that have a CARMA token in the name.

Learning objectives
After completing the lessons that make up this module, you should be able to:
• Modify an existing Eclipse plug-in project
• Create and modify a Java class to perform the enhancements that are offered by the plug-in
• Run or debug the plug-in project

Time required
This module should take approximately 30 minutes to complete.

Prerequisites
To successfully complete the lessons in this module, you should have:
• Successfully completed Exercise 5 and Exercise 6

Lesson 1: Create the CustomContextProvider class


This lesson builds on top of the plug-in project you created in Exercise 5, and modified in Exercise
6. In this lesson, you create the CustomContextProvider class, which can be customized to fit
any viewer you want. For example, if you want the field viewer, the context provider can extend the
CarmaFieldsContentProvider.
To create the CARMAContextProvider class:
1. Make sure that you are in the Plug-in Development perspective. In the Package Explorer view,
expand the com.ibm.carma.plugin.view plug-in project that you used for Exercises 5 and 6.
2. Right click the view package containing the CARMADeveloperView and CustomLabelProvider
classes, and select New > Class.
3. In the New Java Class dialog box that opens, enter CustomContextProvider in the Name text
field.
4. Click the Browse button to the right of the Superclass text field. In the Superclass Selection dialog
box that opens, enter the filter text, CARMATreeContentProvider. Select the matching class, and
click OK.
5. Mark the checkbox, Constructors from superclass, and click Finish. The New Java Class dialog
closes and the CustomContentProvider class is created.
6. Start by ensuring the following imports are included in the Java class. Add any that are missing.

import java.util.Vector;

import com.ibm.carma.model.RepositoryInstance;
import com.ibm.carma.ui.view.CarmaTreeContentProvider;

7. You want to modify the getChildren method to change the content that is provided to the viewer.
This method is where the provider can control which items are sent to the viewer when expanding the

Reference 29
RAM. For this tutorial, you implement the getChildren method to return only repository instances
that have a CARMA token in the name and are not a listing, object, or load repository instance.
The following pseudocode demonstrates what the getChildren method should do:

get the children of the object that would normally be returned;


for each child
{
if(the child is a repository instance)
{
if(the repository instance has a CARMA token and is not a listing, object, or load
repository instance)
add the child to the list of displayable children;
}
}

Use the following is sample code for the getChildren method:

public Object[] getChildren(Object parent)


{
Object[] children = super.getChildren(parent);

//Do not parse non-existant children


if(children == null)
{
return children;
}

Vector<Object> displayChildren = new Vector<Object>();


for(int i = 0; i < children.length; i++)
{
if(children[i] instanceof RepositoryInstance)
{
RepositoryInstance myContainer = (RepositoryInstance) children[i];
if (myContainer.getName().contains("CARMA"))
{
displayChildren.add(children[i]);
}
}
else
{
displayChildren.add(children[i]);
}
}
return displayChildren.toArray();
}

8. Save the source and debug any errors.

Lesson 2: Include the CustomContextProvider in the CARMADeveloperView class


In this lesson, you rewrite the createViewer method to include the CustomContentProvider.
To modify the CARMADeveloperView class:
1. Open the CARMADeveloperView class by double-clicking it in its package. The source should open in
the editor.
2. Scroll down to the createViewer method and change it so that it uses the
CustomContextProvider. It is helpful to note that the CARMATreeViewer constructor allows for a
context provider to be specified to the viewer.
The following is example sample code:

protected StructuredViewer createViewer(Composite parent)


{
/* Create the structure that you want to be present in the view here.
* For this tutorial, you will use the CARMA tree model, like the repositories view.
*/
CARMATreeViewer viewer = new CARMATreeViewer(parent, new CustomContextProvider());
viewer.setLabelProvider(new CustomLabelProvider());
return viewer;
}

3. Save the source and debug any errors.

30 Developer for z/OS: Reference


Summary: Module 7
In this module, you have modified the Eclipse plug-in project from Modules 5 and 6 to only show those
PDS that are not object, listing, or load repository instances, and those that have to do with CARMA.

Results
You should run or debug your plug-in project now. Do the following while still in the testing workspace to
verify the functionality of your plug-in:
1. Open the z/OS Projects perspective
2. Open the CARMA Developer view by selecting from the main file menu, (on Windows) or IBM
Developer for z/OS (on macOS) > Show View > CARMA Developer. The view should open.
3. In the CARMA Developer view, expand the host system. You should see each of the RAMs on the host
system marked with a label.
4. Right click a particular RAM, select Connect, and expand the RAM once it is connected.
5. When you expand the RAM, you should only see PDS that contain CARMA in their name.

Module 8: Creating a custom menu for a custom view


This module teaches you how to create a custom menu for a custom view.
Note: This module assumes that you have completed Modules 5-7. You are using the Eclipse plug-in
project that you created in those exercises as the foundation for this module.

Learning objectives
After completing the lessons in this module, you should be able to:
• Modify an existing Eclipse plug-in project
• Create and modify Java classes that handle the plug-in enhancement
• Run or debug the plug-in project

Time required
This module should take approximately 30 minutes to complete.

Prerequisites
To successfully complete the lessons in this Module, you should have:
• Successfully completed Exercise 5, Exercise 6, and Exercise 7

Lesson 1: Create the CustomOpenActionGroup Java class


This lesson guides you through the steps of creating the Java class that is needed to handle the
customized open menu.
The menu you will create is a collection of actions, separators, and action groups that contain a smaller
collection of actions. For this exercise, you will create a class, MainActionGroup that makes up the
menu. You will also create another class, OpenActionGroup that overrides the default open group
option.
To create these classes:
1. You start with the OpenActionGroup class, since the MainActionGroup class needs a custom
open group. In the Package Explorer view, right-click on thecom.ibm.carma.plugin.view Eclipse
plug-in project that you have modified from Exercise 5, and select New > Package.
2. In the New Java Package dialog box that opens enter, menu, as the name of the package, and click
Finish.
3. Now, create the Java class. Right click the menu package, and select New > Class. The New Java
Class dialog box opens.
4. Enter CustomOpenActionGroup as the name of the class.

Reference 31
5. Click the Browse button to the right of the Superclass text field. In the Superclass Selection
dialog box that opens, enter the filter text, OpenActionGroup. Select the class that is part of the
com.ibm.carma.ui.view package, and click OK.
6. Click Finish to close the New Java Class dialog box and create the class.
7. You want to override the fillContextMenu method to provide the custom content of the open
section of the menu. For the open section of the menu, you need to display everything but the
Open and Open With menu selections. The easiest way to do this is to get the default from
OpenActionGroup section and remove the Open and Open With menu selections.
The following pseudocode demonstrates this:

get the default items;


for each item
{
if(item is open or open with)
{
remove it from the list;
}
}

Use the following sample code to implement this functionality:

public void fillContextMenu(IMenuManager menu)


{
super.fillContextMenu(menu);
IContributionItem[] myItems = menu.getItems();
for(int i = 0; i < myItems.length; i++)
{
IContributionItem item = myItems[i];
if(item.getId() != null)
{
if(item.getId().equals(OpenAction.ID) ||
item.getId().equals("com.ibm.carma.ui.openWithSubMenu"))
{
menu.remove(item);
}
}
}
}

8. Automatically import any needed packages and classes. Ensure that all of the following are imported:

import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IMenuManager;

import com.ibm.carma.ui.action.OpenAction;
import com.ibm.carma.ui.view.OpenActionGroup;

9. Save the source and debug any errors.

Lesson 2: Create the CustomMainActionGroup Java class


This lesson guides you through the steps to create a CustomMainActionGroup class. This class
emulates the functionality of the CARMA default MainActionGroup class. However, instead of
using the default OpenActionGroup, the CustomMainActionGroup class that you create uses the
CustomOpenActionGroup class that you created .
To create the CustomMainActionGroup class:
1. Create a new class by right-clicking on the menu package in the Package Explorer view, and selecting
New > Class.
2. In the New Java Class dialog box that opens, enter CustomMainActionGroup as the name. Click the
Browse button to the right of the Superclass text field. In the Superclass Selection dialog box that
appears, enter the filter, CarmaBrowserActionGroup. Select the matching class that is contained in
the com.ibm.carma.ui.view package, and click OK.
3. Select the Constructors from superclass check box.
4. Click Finish to close the New Java Class dialog and create the class.

32 Developer for z/OS: Reference


5. The first thing that you will want to do is create global variables for a NewMenuActionGroup,
a NavigationActionGroup, a OpenActionGroup, a ConnectionActionGroup, a
DisplayActionGroup, and a PropertyDialogAction, similar to the following sample code:

private NewMenuActionGroup _newMenuActionGroup;


private NavigationActionGroup _navigationActionMenu;
private OpenActionGroup _openActionGroup;
private ConnectionActionGroup _connectionActionGroup;
private DisplayActionGroup _displayActionGroup;
private PropertyDialogAction _propertyAction;

Tip: These variables should be declared at the top of the class before any method declarations.
6. Now you want to override the makeActions method to instantiate the groups and actions
that are needed to fill the menu. With the OpenActionGroup, be sure to instantiate your
CustomOpenActionGroup class instead of the default. Use the following source code:

protected void makeActions()


{
_newMenuActionGroup = new NewMenuActionGroup();
_navigationActionMenu = new NavigationActionGroup(getBrowser());
_openActionGroup = new CustomOpenActionGroup();
_connectionActionGroup = new ConnectionActionGroup(getBrowser());
_displayActionGroup = new DisplayActionGroup(getBrowser());
_propertyAction = new PropertyDialogAction(getBrowser().getViewSite(), getViewer());
}

7. Override the fillContextMenu() method with the updated list of groups, actions, and separators.
To make it look like a pop-up menu, use the same order for adding items to the menu using the
following example code:

public void fillContextMenu(IMenuManager menu)


{
ActionContext myContext = new ActionContext(getViewer().getSelection());
_newMenuActionGroup.getContext();

_newMenuActionGroup.setContext(myContext);
_newMenuActionGroup.fillContextMenu(menu);

_navigationActionMenu.setContext(myContext);
_navigationActionMenu.fillContextMenu(menu);

menu.add(new Separator("open"));
_openActionGroup.setContext(myContext);
_openActionGroup.fillContextMenu(menu);

menu.add(new Separator("refractor"));

menu.add(new Separator("connect"));

_connectionActionGroup.setContext(myContext);
_connectionActionGroup.fillContextMenu(menu);
_connectionActionGroup.updateActionBars();

menu.add(new Separator("display"));

_displayActionGroup.setContext(myContext);
_displayActionGroup.fillContextMenu(menu);

menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
menu.add(new Separator("project"));
menu.add(new Separator("properties"));
menu.add(_propertyAction);
}

8. Import all needed classes and packages. Ensure that all of the following are included in the import
statements:

import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.actions.ActionContext;
import org.eclipse.ui.dialogs.PropertyDialogAction;

import com.ibm.carma.ui.view.BaseCarmaBrowser;
import com.ibm.carma.ui.view.CarmaBrowserActionGroup;

Reference 33
import com.ibm.carma.ui.view.ConnectionActionGroup;
import com.ibm.carma.ui.view.DisplayActionGroup;
import com.ibm.carma.ui.view.NavigationActionGroup;
import com.ibm.carma.ui.view.NewMenuActionGroup;
import com.ibm.carma.ui.view.OpenActionGroup;

9. Save the source and debug any errors.

Lesson 3: Adding the custom menu to the CARMADeveloperView


This brief lesson walks you through adding the custom menu you created, to the CARMADeveloperView.
You do this by overriding the createAction method.
To add the custom menu to the CARMADeveloperView:
1. Open the CARMADeveloperView class by opening the view package and double-clicking on the
source file. It opens in the editor.
2. Scroll down and create the following method

protected void createActions()


{
setActionGroup(new CustomMainActionGroup(this));
}

This code sets the default action group to the CustomMainActionGroup you created.
3. Add import menu.CustomMainActionGroup; to your list of import statements at the top of the
CARMADeveloperView class.
4. Save the source and debug any errors.

Summary: Module 8
You have modified the Eclipse plug-in project from Module 5-7 to add a custom menu.

Results
You should run or debug your plug-in project now. Do the following while still in the testing workspace to
verify the functionality of your plug-in:
1. Open the CARMA Developer and CARMA Repositories view
2. In one of the views, connect to a particular RAM.
3. Expand the RAM until you can see each of the particular members.
4. Right click any CARMA member in the CARMA Repositories view and in the menu that appears there
should be options to both Open and Delete.
5. Right click the same CARMA member in the CARMA Developer view, and in the menu that appears
there should be no option to Open or Delete.

Module 9: Introduction to parameter and action extension points


This module explores the capabilities of CARMA extension points in providing customization to
parameters and actions that are associated with a custom action on a particular RAM.
This module updates and uses the Sample PDS RAM to create a HowTo custom action and associate four
parameters to it.

Learning objectives
After completing the lessons in this module you should be able to:
• Create an Eclipse plug-in project
• Create and define actionValidators, parameterValidators, and customParameterControl
extension points
• Create and develop the necessary classes to add the enhanced functionality to the custom actions
• Run and debug the plug-in project
• Understand the end-result in the plug-in project of using each of the extension points

34 Developer for z/OS: Reference


Time required
This module should take approximately 60 minutes to complete.

Prerequisites
To successfully complete the lessons in this module, you should have:
• Access to modify the Sample PDS RAM on your host system or a systems administrator who can do this
for you
• Basic understanding of RAM Development, found in the CARMA Developer's Guide
• Basic understanding of C coding and debugging is recommended
• Experience submitting JCL jobs to REPRO files

Lesson 1.0: Configure the Sample PDS RAM on the host


The extension points used in this sample ensures that the input is in the permitted format, ensures that
the input will not cause errors, and modifies the view of the custom actions pertaining to a particular RAM.
For this sample, you use the PDS RAM. However, because there are no custom actions that are already
integrated into the Sample PDS RAM, you have to configure the RAM with a new custom action and its four
parameters.
Tip: The lessons pertaining to modifying the Sample PDS RAM might require special permissions on your
host system to access and modify some of the files.

Learning objectives
Though this is not a focal point of the exercise, you should be able to configure a RAM to add custom
actions and parameters.

Time required
This portion of lessons should take approximately 30 minutes to complete.

Prerequisites
A basic understanding of the content in the CARMA Developers Guide is recommended.

Lesson 1.1: Customize the PDS RAM by adding a custom action and parameters to the model
This lesson will briefly step you through adding the HowTo custom action and its four parameters: value,
string1, string2, and option, to the PDS RAM.
These parameters and actions are added to the PDS RAM by supplying the appropriate information to
the CRA0VDEF file. For more information on the steps in this lesson, see the CARMA Developer's Guide,
Chapter 4. Customizing a RAM API using the CAF.
1. Start by listing the action or actions that you want to extend to the RAM's API. For this sample, you will
add a custom action, HowTo, with the following attributes:
• Name: HowTo
• Description: Provides an example of implementing plug-in projects with extension points
• ActionID: 100
• RAM ID: 00
• Parameter list: value, string1, string2, option
• Return Value list:
Tip: If you are using the shipped Sample PDS with no customization, then the following values for
action id and RAM id should be correct; however, if you have added or removed RAMs, custom actions,
or parameters check to make sure that the action id is the next available action id and the RAM id
corresponds to the Sample PDS RAM. .
2. In the description of the HowTo custom action above, there are parameters and return values listed.
Each of these must be defined within the RAM as well. The descriptions of each are as follows:

Reference 35
• Name: value
• Description: a one-digit numerical value
• Parameter ID: 000
• Ram ID: 00
• Type: string
• Length: 1
• Constant: no
• Default value: none
• Prompt: Enter a one-digit value:
• Name: string1
• Description: a string of text
• Parameter ID: 001
• RAM ID: 00
• Type: string
• Length: 10
• Constant: no
• Default value: none
• Prompt: Enter a short string of text:
• Name: string2
• Description: a string of text
• Parameter ID: 002
• RAM ID: 00
• Type: string
• Length: 10
• Constant: no
• Default value: none
• Prompt: Enter a short string of text:
• Name: option
• Description: yes or no option
• Parameter ID: 003
• RAM ID: 00
• Type: string
• Length: 1
• Constant: no
• Default value: none
• Prompt: Yes or No?
3. Knowing the actions, parameters, and descriptions of each helps you create the declarations to include
into the configurations file. Each action and parameter is defined on its own line and its particular
metadata is specified within a predefined byte length.
Tip: You can also define the actions and parameters without using the predefined byte sizes for
metadata by using tabs as a delimiter. Be sure to consult the CARMA Developer's Guide, Chapter 4.
Customizing a RAM API using the CAF for the details of this alternative format.
For this sample, using the predefined byte sizes, the custom HowTo action is declared as:
A00100 000,001,002,003|

36 Developer for z/OS: Reference


For each of the respective parameters, the declaration is:
P00000 STRING 1 N
P00001 STRING 10 N
P00002 STRING 10 N
P00003 STRING 1 N

Note: For both actions and parameters, the first 8 bytes of the record is called the record key.
4. Make sure that there are no active connections between the Sample PDS RAM, CARMA, and the host
system before continuing.
5. You should add this information to FEL.SFELVSM2(CRA0DEF) and ensure that all record keys are
in alphanumeric order. Use the JCL script that is located at FEL.#CUST.JCL(CRA$VDEF) to REPRO
FEL.SFELVSM2(CRA0DEF).
6. Next, for each action and parameter you define in the CRA0VDEF file you must define a corresponding
definition in the CRA0VSTR file containing any language-dependent information about the action or
parameter.
For this sample, the custom action would be defined in the CRA0VSTR like the following:
EN_US 00037A00100 HowTo For demonstration. Does nothing.

For each respective parameter in the sample, the definitions are:


EN_US 00037P00000 value Enter a one-digit numerical value.
EN_US 00037P00001 string1 Enter a short string of text.
EN_US 00037P00002 string2 Enter a short string of text.
EN_US 00037P00003 option Y/N?

Note: For both actions and parameters, the first twenty-one bytes of the record is called the record
key.
7. You should add this information to the FEL.SFELVSM2(CRA0VSTR) file and ensure that all records
are in alphanumeric order. Use the JCL script that is located at FEL.#CUST.JCL(CRA$VSTR) to
REPRO FEL.SFELVSM2(CRA0VSTR).

Lesson 1.2: Add the performAction function to the PDS RAM to correspond with the custom HowTo action
In the last lesson, you configured the Sample PDS RAM with a HowTo custom action and its four
parameters. In this lesson, you create or modify the function on the host that handles the HowTo action.
The HowTo action was created for demonstrational purposes to display the dialog box to which you
will later apply the actionValidators, parameterValidators, and customParameterControl
extension points. However, for the purposes of this sample, you do not need this action to perform any
action on the host. Therefore, the function that is provided for the HowTo action id on the Sample PDS
RAM does nothing.
1. Open the C file on the host containing the Sample PDS RAM source; it should be
FEL.SFELSAMP(CRASPDS). You can open this file directly in Developer for z/OS.
2. If you have custom actions that are already implemented on the Sample PDS RAM, you want to modify
the performAction function to do nothing if it is passed the HowTo action id and return successful.
Use the following sample code snippet to add this to your performAction function:

if(actionID == 100)
{
return 0;
}

If the HowTo custom action calls the performAction function it will now return successful without
performing any action on the host. Skip steps 3 and 4.
Note: If you have already implemented the performAction function, you should check and make
sure that the actionId 100 has not already been set to another custom action.
3. If you have not implemented any custom actions for the Sample PDS RAM, you will want to implement
the performAction function and have it do the same thing as the snippet of code above does.
Start by adding the following export statement to the preprocessor directives at the top of the C
source: #pragma export(performAction).

Reference 37
4. Next, add the following method to the PDS RAM:

int performAction(int actionID,


char instanceID[256],
char memberID[256],
void** params,
void** customReturn,
char error[256])
{
/*Accept any actionID and return successfully*/
return 0;
}

Note: If you add more custom actions to the PDS RAM later, you will want to specify for each custom
action id what action should be performed, similar to the snippet of code in step 2.
5. Save the source and debug any errors.

Lesson 1.3: Recompile the PDS RAM and verify the HowTo custom action
This lesson guides you through the final steps in adding the custom action and parameters to the Sample
PDS RAM.
1. Be sure that there are no active connections between the Sample PDS RAM, CARMA, and the host
system. Any active connections could cause CARMA or the RAM to act abnormally.
2. Recompile the FEL.SFELSAMP(CRASPDS) member.
3. Restart the server.
4. In the client, reconnect to CARMA and to the Sample PDS RAM.
5. Now, expand the Sample PDS RAM down to a particular CARMA member.
6. When you right-click on the CARMA member, you should be able to select Custom > HowTo.
7. The HowTo action dialog box opens and should have empty text fields and prompts for the four
parameters you defined on the Sample PDS.

Lesson 2: Define the dependency and extensions for the plug-in project
In this lesson, you define the dependencies and the three extension points: actionValidators,
parameterValidators, and customParameterControl.
Note: Before you complete this lesson, you should create an Eclipse plug-in project with the following
attributes:
• Project Name: com.ibm.carma.plugin.howto
• ID: com.ibm.carma.plugin.howto
• Name: HowTo Action
1. Open the Plug-in Manifest Editor by right-clicking on the com.ibm.carma.plugin.howto plug-in
project, and selecting PDE Tools > Open Manifest.
2. Start by adding the dependency. Select the Dependencies tab at the bottom of the Plug-in Manifest
Editor.
3. Click the Add button under the Required Plug-ins panel. The Plug-in Selection dialog box opens.
4. Filter for the com.ibm.carma.ui plug-in, select it when it appears, and click OK.
5. Next, add the extensions to the plug-in project. Select the Extensions tab and filter for each of the
following:
• com.ibm.carma.ui.parameterValidators,
• com.ibm.carma.actionValidators,
• com.ibm.carma.customParameterControls
In the next three lessons, you configure each of the extensions to be associated with the HowTo custom
action and its parameters.

38 Developer for z/OS: Reference


Lesson 3: Configure the com.ibm.carma.ui.parameterValidators Extension
In this lesson, you configure the parameterValidator extension that you defined in the previous
lesson for the plug-in project.
The parameterValidator extension point allows for contributing extensions to validate the value of a
particular parameter as it is being entered by the user. For this sample, the value parameter accepts a
single digit numeric character less than four. You will use the different possible values that the user can
input into the value parameter to display different informational messages to the user and to ensure that
the user enters only numeric characters.
1. Start by first configuring the parameterValidators extension. In the Plug-in Development
perspective, right click the com.ibm.carma.plugin.howto plug-in project and select PDE Tools
> Open Manifest. The Plug-in Editor opens.
2. From the bottom list of tabs select Extensions. On this page, you should see the extensions that
are associated with your plug-in project. Select the (parameterValidator) option below the
com.ibm.carma.ui.parameterValidators extension point. To the right, the Extension Element
Details is listed.
3. Use the Sample PDS RAM for this sample, as this is the RAM you added the custom action to and the
appropriate parameters to in the configuration file you created in Lesson 1. In the uniqueId text field
enter, com.ibm.carma.sample.PDSRAM.
a) Open the CARMA Repositories view and connect to the remote system.
b) Expand the host system with the RAM you want to use, right-click on the particular RAM, and select
Properties.
c) In the Properties for RAM dialog box that opens, you should see the unique identification listed.
This is the uniqueId you use when configuring the extension points.
4. In the class text field, enter the name of the class that contains the code
that specifies the details of the parameter validation. Enter the class name,
com.ibm.carma.plugin.howto.action.ValueParamValidationAction. You create this class
later in this exercise.
5. In the parameterId text field, enter the parameter that is defined in the PDS RAM to which the
parameter validation applied. For this sample, use the value parameter, which you defined on the PDS
RAM with a parameterId of 000 in Lesson 1.
6. Finally, in the actionId text field, enter the action that is defined on the PDS RAM to which the
parameter validation should be applied. For this sample, use the HowTo custom action, which you
defined on the PDS RAM with an actionId of 100 in Lesson 1.
You have now configured a parameterValidator to validate the value parameter on the HowTo
custom action for the PDS RAM.

Lesson 4: Configure the com.ibm.carma.ui.actionValidators extension


In this lesson, you configure the actionValidator extension that you defined for this plug-in project.
The actionValidators extension point allows contributing extensions to validate the values and the
relationships between values of all parameters that are associated with an action. If invalid combinations
of parameters are detected, the OK button is disabled and the user is unable to submit the information.
For example, in this sample either the string1 or string2 fields are considered required but not both.
You use the actionValidator extension to check the valid combination of parameters.
1. You should be working in the Plug-in Development perspective and have the Plug-in Editor for your
com.ibm.carma.plugin.howto plug-in project open.
2. On the Extensions page, select the (actionValidator) option below the
com.ibm.carma.ui.actionValidators extension point. To the right you see the Extension
Element Details listed.
3. In the actionId text field, enter the action that is defined on the PDS RAM to associate this validator to.
For this sample, use the HowTo custom action on the PDS RAM, actionId 100.
4. In the uniqueId text field, enter the unique identification that is associated with the PDS RAM,
com.ibm.carma.sample.PDSRAM.

Reference 39
5. Finally, in the class text field, enter the class that contains the code to apply the
actionValidator to the parameters of the HowTo custom action. For this sample, the class is,
com.ibm.carma.plugin.howto.action.ActionValidationAction. You create this class later
on in this exercise.
You have now defined a parameterValidator extension for the PDS RAM on the HowTo action using
the ActionValidationAction Java class.

Lesson 5: Configure the com.ibm.carma.ui.customParameterControl extension point


In this lesson, you configure the customParameterControl extension that you defined for this plug-in
project.
The customParametercontrol extension point allows for the values of the parameter to be presented
to the user in a format other than a text field. For this sample, the option parameter is changed from a
single-character text field to a checkbox. You start working in the Plug-in Development perspective with
the Plug-in Editor for your com.ibm.carma.plugin.howto plug-in project open.
1. On the Extensions page, select the (customParameterControl) option below the
com.ibm.carma.ui.customParameterControl extension point. To the right you see the
Extension Element Details listed.
2. In the uniqueId text field, enter com.ibm.carma.sample.PDSRAM for the Sample PDS RAM.
3. In the class text field, enter com.ibm.carma.plugin.howto.action.CheckboxOptionControl.
You create this class later in this exercise.
4. In the parameterId text field, enter the parameter id for the option parameter. For the sample, this is
003.
5. Finally, in the actionId text field, enter 100 for the HowTo action.
6. Save the changes and debug any errors.
You have now defined a customParameterControl extension in the HowTo action on the PDS RAM.

Lesson 6: Create the appropriate Java classes to handle the verification and validation
In the previous lessons you configured the extension points; now you create the Java classes that are
needed to handle the validation of the parameters and actions.
Tip: As you create these Java classes, they will each have to implement or extend certain interfaces or
classes respectively. To determine what classes or interfaces need to be included, you can right-click on
the extension in the Plug-in Editor and select Show Description. The description of the extension will
open in the editor. If you scroll down to the API Information heading, you find the classes or interfaces
the class needs to use in conjunction with the extension point.
1. Start by creating the class that is used with the parameterValidator extension point. This class
is responsible for checking to make sure the value that is entered into the value parameter follows
the specifications that are outlined in this sample. In the Package Explorer view, right click the
com.ibm.carma.plugin.howto plug-in project, and select New > Package.
2. In the New Java Package dialog box that opens, enter com.ibm.carma.plugin.howto.action as
the name for the package. Click Finish. You should see the package that is created under your Eclipse
plug-in project.
3. Now, right click the com.ibm.carma.plugin.howto.action package you created, and select New
> Class. The New Java Class dialog box opens.
4. Enter ValueParamValidator in the Name text field.
5. To the right of the Interfaces click the Add button. In the Implemented Interfaces Selection dialog
box that opens, filter for the interface IParameterValidator. Click Finish to close the New Java
Class dialog box and open the class in the editor.
6. Now, you create the second Java class that is responsible for handling the verification of the HowTo
action. Right click the com.ibm.carma.plugin.howto.action package and select New > Java
Class.
7. In the New Java Class dialog box that opens enter the name of the class to be, ActionValidator
and add the interface IActionValidator. Click Finish to close the dialog box and create the class.

40 Developer for z/OS: Reference


8. Finally, create the last Java class following the above steps and by defining a name
of CheckboxOptionControl. Click the Browse button to the right of the Superclass
text field. The Superclass Selection Dialog Box should open. Filter for the class,
AbstractCustomParameterControl, select it, and click OK.
9. Click Finish to close the New Java Class dialog box and open the class in the editor.
You have now created the classes that handle the verification features offered by the extension points.

Lesson 7: Create the code for the ValueParamValidator class


The ValueParamValidator class handles the verification of the Value parameter in the HowTo action.
This lesson describes in detail how to create the code to demonstrate the parameter verification and
validation features of the com.ibm.carma.ui.parameterValidators extension point.
For this sample, the following are a list of possible inputs from the user and the informational messages
that are displayed.
• When the user enters a 0, an informational message is displayed
• When the user enters a 1, a warning message is displayed
• When the user enters a value of 2 or greater, an error message is displayed
• When the user enters a non-numeric character, the input will not be allowed
1. In the Package Explorer view, open the ValueParamValidator class by navigating
com.ibm.carma.plugin.howto > src > com.ibm.carma.plugin.howto.action and double-
clicking on the class to open it in the editor.
2. You will first implement the verifyInput method. This method checks for any invalid characters
in the input text. For this sample, this method will only accept numeric characters. The following
pseudocode demonstrates this:

if the length of input is greater than 0


then allow input if the input characters are 0-9
else
do not allow input

Use the following example sample code to implement the verifyInput method:

/*Accept only numeric characters as valid. */


public void verifyInput(ParameterValidationEvent event)
{
if(event.text.length() > 0)
event.allowInput = (event.text.matches("[0-9]"));
}

3. Next, you will override the validateParameter method to display the appropriate methods
depending on the values entered, as described above.
The following pseudo code demonstrates this:

if input = 0
return an informational message
else if input = 1
return a warning message
else
return an error message

Use the following example sample code to override this method:

/* Returns an informational message if 0 is entered,


* Returns a warning message if 1 is entered,
* Returns an error message if a numeric value greater than 1 is entered
*/
public ValidationResult validateParameter(ParameterValidationevent event)
{
ValidationResult result = new ValidationResult();
if(event.text.contains("0"))
{
//Display informational message.
result.severity = ValidationResult.INFO;
result.message = "You entered a 0!";

Reference 41
}
else if(event.text.contains("1"))
{
//Display a warning message
result.severity = ValidationResult.WARNING;
result.message = "Values greater than 1 will result in an error!";
}
else
{
//Display an error message.
result.severity = ValidationResult.ERROR;
result.message = "Value is too great, enter a lower value.";
}

return result;
}

4. Save the source and debug any errors.

Lesson 8: Create the code for the ActionValidator class


The ActionValidator class verifies that at least one of the string parameters has a value, but not both.
You will also make the Value parameter a required parameter, and codes the ActionValidator class to
mark the parameter with an asterisk.
1. In the Package Explorer view, open the ActionValidator class by navigating
com.ibm.carma.plugin.howto > src > com.ibm.carma.plugin.howto.action and double-
clicking on the class to open it in the editor.
2. You start by overriding the isParameterRequired method. For this sample, you will code for only
the Value parameter to be required. The following pseudo code demonstrates this:

if paramID = paramID of value parameter


return true
else
return false

Use the following example source code to override the isParameterRequired method:

/( Mark the value parameter as required.*/


public boolean isParameterRequired(Action action, Parameter param)
{
//The value parameterID is 000
if(param.getParameterID().equals("000"))
{
return true;
}

return false;
}

3. Next, you override the validateAction method to allow only one value in the input strings
parameter, but not both. The following pseudocode demonstrates this:

Collect all the Parameter objects associated with the action


Iterate through the Parameter objects and get the string1 and string2 Parameter objects
Retrieve the string value of string1, check to see if it's null or has a length of 0
Retrieve the string value of string2, check to see if it's null or has a length of 0
Determine if both the parameters have values
Return an error message
Determine if neither of the parameters have values
Return an informational message

Use the following example sample code to override this method:

public ValidationResult validateAction(ActionValidationEvent event)


{
Parameter string1Param = null;
Parameter string2Param = null;
ValidationResult result = new ValidationResult();

//Iterate through and retrieve the parameter objects


for (Object o : event.action.getParameters())
{
if (((Parameter) o).getParameterId().equals("001"))
{

42 Developer for z/OS: Reference


string1Param = (Parameter) o;
}
else if (((Parameter) o).getParameterId().equals("002"))
{
string2Param = (Parameter) o;
}
)

//Retrieve the parameter value for string1, and determine if there was input
String string1Val = (String) event.parameterValueMap.get(string1Param);
boolean string1IsThere = !(string1Val == null || string1Val.length() == 0);

//Retrieve the parameter value for string2, and determine if there was input
String string2Val = (String) event.parameterValueMap.get(string2Param);
boolean string2IsThere = !(string2Val == null || string2Val.length() == 0);

//Determine if both string1 and string2 are provided.


//Returns an error message.
if (string1IsThere && string2IsThere)
{
result.severity = ValidationResult.ERROR;
result.message = "Provide either String1 or String2.";
}

//Determine if neither string1 nor string2 is provided


//Returns an info message.
else if(!string1IsThere && !string2IsThere)
{
result.severity = ValidationResult.INFO;
result.message = "Enter a value for String1 or String2.";
}

return result;
}

4. Save the source and debug any errors.

Lesson 9: Create the code for the CheckboxOptionControl class


The CheckboxOptionControl class changes the CARMA default text field to a checkbox on the Option
parameter. Since this parameter is a yes or no parameter, a checkbox is more convenient for the user.
1. In the Package Explorer view, open the CheckboxOptionControl class you created by navigating
com.ibm.carma.plugin.howto > src > com.ibm.carma.plugin.howto.action and double-
clicking on the class.
2. You will first add the checkbox button object as instance data for the class. This allows the checkbox
button and all its metadata to be available to the CheckboxOptionControl class. Add the following
line of code: Button theButton;
3. Next, you override the createControl method to create the checkbox button and return it instead of
the default text field. The following pseudocode demonstrates what you want this method to do:

Create theButton with the checkbox style


Give the theButton some text
Return the theButton

Use the following sample code to override this method:

/* Create a checkbox for the yes/no option */


public Control createControl(Composite parent,
RepositoryManager repositoryManager,
Parameter param,
Action action,
CustomActionAccepter custActionAccepter,
Object defaultValue)
{
theButton = new Button(parent, SWT.CHECK);
theButton.setText("Check me!");
return theButton;
}

4. Now, you override the getValue method. This method returns the value of the parameters. Since
you are using a checkbox instead of a text field, the code you write will have to translate the check
or unchecked status of the checkbox into the expected string format. The following pseudocode
demonstrates this:

Reference 43
if the checkbox is checked
return "Y" for yes
else
return "N" for no

Use the following sample code to override this method:

public Object getValue() {


if(theButton.getSelection())
return "Y";
else
return "N";
}

5. The last method that you need to override is the isUsingDefaultLabel method. If set to false, this
method will not display the default label that you provided when you added the parameter to the RAM.
If set to true, then the label is displayed like normal. For this sample, the code will use the default
label.
Use the following sample code to override the method:

public boolean isUsingDefaultLabel()


{
return true;
}

6. Finally, you need to ensure that all required imports are listed. Add any of the following import
statements that are not listed in your class:

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.*;

import com.ibm.carma.model.*;

import com.ibm.carma.ui.action.custom.AbstractCustomParameterControl;

7. Save the source and debug any errors.


Your completed code for the CheckBoxOptionControl should look like:

package com.ibm.carma.plugin.howto.action;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.*;

import com.ibm.carma.model.*;

import com.ibm.carma.ui.action.custom.AbstractCustomParameterControl;

public class CheckboxOptionAction extends AbstractCustomParameterControl {


//Add the button to the instance data
Button theButton;

/* Create a checkbox for the yes/no option */


public Control createControl(Composite parent,
RepositoryManager repositoryManager,
Parameter param,
Action action,
CustomActionAccepter customActionAccepter,
Object defaultValue) {
theButton = new Button(parent, SWT.CHECK);
theButton.setText("Check me!");
return theButton;
}

@Override
public Object getValue() {
if(theButton.getSelection())
return "Y";
else
return "N";
}

@Override
public boolean isUsingDefaultLabel() {
return true;

44 Developer for z/OS: Reference


}
}

Summary: Module 9
In this module, you have created a plug-in project that demonstrates the use of the actionValidators,
parameterValidators, and customParameterControl extension points.

Results
You should run or debug your plug-in project now. Do the following while still in the testing workspace to
verify the functionality of your plug-in:
1. Be sure that you are in the zOS Projects perspective and are connected to your host system. Use the
port numbers that are associated with the updates you did on the PDS RAM in Lesson 1.
2. Open the CARMA Repositories view and connect to the PDS RAM you modified in Lesson 1.
3. Expand the RAM down to an individual CARMA Member. Right click this member, and select Custom >
HowTo. The HowTo dialog box opens.
Tip: If you have trouble getting this dialog box to open or for the custom option to be available, check
back through the steps you followed in Lesson 1 or consult the CARMA Developer's Guide.
4. The first thing that you will check for is that the parameterValidator extension is working correctly.
a. In the first text field, enter 0. An informational message should appear in the header of the dialog
box.
b. Now enter 1 in the text field. The message should change to a warning message.
c. Entering 2 or other numerical value should result in a displayed error message and the OK button
disabled.
d. The final test for the parameterValidator extension is attempting to enter a nonnumeric
character, such as a. The input should not be allowed and will not even appear within the text
field.
5. Next, you check the actionValidator extension.
a. The first test is to see if the appropriate parameter you coded to be required is marked with an
asterisk. For this sample, the first parameter should be marked with the asterisk, but no other
parameters.
b. The second test is to ensure that the form will not be accepted if both strings are provided. For
this sample, when you enter a value into both string fields, you should see an error message that is
displayed and the OK button should be disabled.
6. Finally, you will test the customParameterControl extension.
a. The first test is to check to see if a checkbox has replaced the default text field and that selecting
and clearing the checkbox does not cause any errors.
b. The second test is to see if the default label provided, Y/N? was kept.

CARMA RAM (host) Developer's Guide


The following topics provide information on CARMA API rules of engagement and a mapping of which API
packages are found in which plug-ins.
• “Defining criteria for CARMA compare” on page 46
• “Introduction to CARMA” on page 0

Reference 45
Defining criteria for CARMA compare
CARMA has the ability to compare (associated) resources in the Developer for z/OS workspace (for
example, local or remote projects) with resources in a CARMA RAM. This is useful for determining what
changes have been made to the workspace files before checking the changes into CARMA.
CARMA stores the current criteria values when it downloads a resource into the workspace. Based on
criteria value and workspace changes CARMA can determine what changes have been made to the
version in the RAM and indicate what direction changes should be moved. For example, CARMA can
determine whether a workspace file has been updated locally, in the RAM, or both. Based on the change
information CARMA can indicate what portions of the file that is changed and indicate where changes
should be uploaded to the RAM, copied from the RAM, or if a merge needs to occur because changes have
occurred in the workspace and the RAM.
In order to perform the compare in a flexible manner, CARMA has provided a Compare Criteria
configuration file – syncConfig.xml. This syncConfig file is placed in the RSE configuration directory*
and automatically picked up by CARMA when RSE starts**.
The compare configuration file allows the RAM developer to specify a variety of criteria for comparison on
a RAM-by-RAM basis. An example of a compare configuration file is:

<?xml version="1.0" encoding="UTF-8"?>


<CARMACompare xmlns="http://www.ibm.com/CARMA/SyncConfig">
<RAMCompare ramId="00">

<memberinfo key="Last Modified Date" type="date" format="MM/DD/YY"/>


<memberinfo key="Last Modified Time" type="date" format="HH:MM"/>
<memberinfo key="Last Modified Seconds" type="int" />
</RAMCompare>
<RAMCompare ramId="01">
<content />
</RAMCompare>
</CARMACompare>

The XML document must begin with a CARMACompare element. The CARMACompare element can contain
1 or more RAMCompare elements. Each RAMCompare element specifies the comparison criteria for a
single RAM. The RAM that the criteria apply to is denoted by the ramId attribute. The ramId value should
match up with the RAM id in the CARMA VSAM configuration and is a 2-digit number. 0 s are required to
be added to the beginning of the Id value if the Id is fewer than 2 digits.
Note: You can identify a RAM using either the ramId or uniqueId. If you know the particular ID for
the RAM, use the ramId. If you know the RAM, but do not know the ramID associated with it, use the
uniqueId.
The example above defines compare criteria for 2 RAMs, 01 and 02. Each RAMCompare element contains
the criteria for the RAM. Currently, the criteria available for checking include:
• Member information
• Member contents
Member information
The configuration can define 1 or more memberinfo elements for each RAMCompare. The member
information elements are concatenated together to form a comparison. The member information element
contains a key, type, and optional format attributes. Currently, the type and format attributes are
ignored but an explanation of usage is included. The keys are currently compared directly for string
equivalence.
Key attribute
The key attribute references a member information item that is found in the properties for a resource.
The key attribute should match the key that is returned by the RAM for the resource.
Type attribute
The type attribute specifies how the key value should be treated. The type attribute can be set to
one of the following:
• int

46 Developer for z/OS: Reference


• string
• float
• date
The type defines how the member information should be compared. For example, using the following
criteria

<memberinfo key="Last Modified Seconds" type="int" />

A member information value of 0001 would be equal to 1.


Format attribute
The format attribute is only required for elements that specify a type of “date”. The format attribute
allows the criteria to define how the date value should be parsed and compared. For example, using
the following criteria:

<memberinfo key="Last Modified Time" type="date" format="HH:MM"/>

A member information value of 1:10 PM would be equivalent to 13:10.


Member Contents
The configuration can define one content element for each RAMCompare. The contents element indicates
that CARMA should inspect the byte contents of the resource for changes.
Note: This requires that the entire file is downloaded to the workspace to perform the comparison.
The file contents are downloaded to the workspace and a file hash (MD5) is performed on the file
contents. If the file contents hash differs from the workspace file hash, then a difference is indicated.
Default Compare Criteria
If a RAMCompare element is not defined for a RAM that CARMA is working with, a default compare
criteria set is used. The default compare criteria first looks to see whether a carma.version member
information key is defined for the resource being compared. If the carma.version key is available,
the single key value is used as the compare criteria. If a carma.version key is not available, then the
comparison is performed based on member contents.
Note: * Please refer to the IBM Developer for z/OS Host Configuration Guide (SC27-9933) for more
information on the RSE configuration directory.
Note: ** The compare configuration file is only picked up when RSE starts. In order for changes to be
detected disconnect RSE and reconnect.

COBOL APIs for Code Review reference


Learn to how to use the Custom Rules API for COBOL and the COBOL Application Model API to create
user-written rules for Code Review.

Working with the COBOL APIs for Code Review


The Custom Rules API for COBOL Code Review and the COBOL Application Model API are complementary.
Some knowledge of both is required to implement a user-written rule.
• The Custom Rules API for COBOL Code Review API provides the base class for user-written rules and
includes useful classes for manipulating the objects in the COBOL Application Model (CAM).
• The COBOL Application Model (CAM) API provides interfaces for accessing the elements of a COBOL
source code program when the program is analyzed by the COBOL Code Review component.
Tip: The Javadoc information for this API includes a guide to using the API. To find
the guide, open the Javadoc information, look at the first topic, which is titled "Package
com.ibm.etools.cobol.application.model.cobol", and read the "Description" section at the end of the
topic.
For a guide to implementing the code analysis of a COBOL user-written rule, see the related links.

Reference 47
Related information
Generated files: Implementation code
Custom Rules API for COBOL Code Review
COBOL Application Model API

PL/I APIs for Code Review reference


Learn to how to use the Custom Rules API for PL/I and the PL/I Application Model API to create user-
written rules for Code Review.

Working with the PL/I APIs for Code Review


The Custom Rules API for PL/I Code Review and the PL/I Application Model API are complementary.
Some knowledge of both is required to implement a user-written rule:
• The Custom Rules API for PL/I Code Review API provides the base class for user-written rules and
includes useful classes for manipulating the objects in the PL/I Application Model (PAM).
• The PL/I Application Model (PAM) API provides interfaces for accessing the elements of a PL/I source
code program when the program is analyzed by the PL/I Code Review component.
Tip: The Javadoc information for this API includes a guide to using the API. To find
the guide, open the Javadoc information, look at the first topic, which is titled "Package
com.ibm.etools.pli.application.model.pli", and read the "Description" section at the end of the topic.
For a guide to implementing the code analysis of a PL/I user-written rule, see the link at the end of the
topic.
Related information
Generated files: Implementation code
Custom Rules API for PL/I Code Review
PL/I Application Model API

Remote Resource Access API overview


The Remote Resource Access API enables customers and third-party vendors to extend the function of
IBM Developer for z/OS by programmatically accessing and manipulating remote resources.
With the Remote Resource Access API you can do the following actions on objects that represent remote
resources:
• Query and modify their characteristics and contents
• Create, copy, rename, and delete them
• Get notifications of specific events that affect them
This API component provides documentation and code samples for these operations and more.

Remote Resource Access API architecture


Learn how the Remote Resource Access API is structured.
The IBM Developer for z/OS Remote Resource Access API has a layered architecture. In the first layer, the
Remote Resource API provides an abstraction to remote artifacts. It contains classes that represent these
artifacts and allow the caller to retrieve information and operate on them.
In the second layer, the Project API provides an abstraction to remote projects that can be used to
structure, group, and organize remote artifacts. The Project API is built on top of the Remote Resource
API. Objects and classes that are defined by the Project API wrap and refer to the objects and classes
that are defined by the Remote Resource API. This additional level of indirection allows a single remote
artifact that is added to different projects to be treated independently in each instance. At the same time,
it allows reuse of function by deferring operation execution to the lower-level Remote Resource objects
where appropriate.

48 Developer for z/OS: Reference


Collectively, the Project and Remote Resource API enable users and third-party vendors to extend the
function of Developer for z/OS. It also simplifies and isolates the calling code from details of the transport
layer.
In Developer for z/OS, the transport layer implementation is provided by the Remote System Explorer
(RSE) framework.

Installing the API samples


The Remote Resource Access API includes samples that can serve as a starting point for using the API.
To import the Remote Resource Access API samples into your workspace:
1. Open the Plug-in Development perspective.
Tip:
Eclipse plug-in development requires the Plug-in Development perspective. This perspective is not
enabled by default in Developer for z/OS. To enable it:
a. Open the Preferences window.
b. Navigate to General > Capabilities.
c. On the Capabilities page, expand Development and select Plug-in Development.
d. Click Apply and Close.
To open the perspective, click Window (on Windows) or IBM Developer for z/OS (on macOS) >
Perspective > Open Perspective > Other, and then select Plug-in Development and click Open.
2. Click File > Import.
3. On the Import window, expand Plug-in Development, click Plug-ins and Fragments, and then click
Next.
4. In the Import From area of the Import Plug-ins and Fragments window, select Directory and click
Browse.

Reference 49
5. In the Plug-in Directory window, select the com.ibm.ftt.api.samples plug-in and click OK. This
plug-in is in the idz\samples\api-samples\eclipse\plugins folder of the Developer for z/OS
installation path.
6. In the Import As area of the Import Plug-ins and Fragments window, select the Projects with
source folders checkbox and click Next.
7. In the Selection window, select the plug-in name in the left pane and then click Add and Finish.
The samples plug-in is added to the Package Explorer.

8. To see how the samples integrate with Developer for z/OS, define and start a runtime configuration.
a) Select com.ibm.ftt.api.samples in the Package Explorer and then click Run > Run
Configurations.
The Create, manage, and run configurations wizard opens.
b) To open the new configuration page, double-click Eclipse Application from the list of
configurations.
c) In the Name field, type a name of your choice and in the Location field, type a location of your
choice.
To create a configuration in the current workspace, for example, you might type Resource
API configuration in the Name field and ${workspace_loc}/../Resource API
configuration in the Location field.
d) Click Run a product and then select com.ibm.rational.developer.systemz.product.ide from the
list.
e) To start the runtime configuration, click Run.
A runtime Developer for z/OS workbench opens with the z/OS Projects perspective. This runtime
workbench opens in a new workspace, separate from the originating workspace. The menu bar in the
new workspace contains an API Samples menu. Some of the menus contain API Sample Actions.
The results of some of these actions are displayed in the Console view of the originating workspace.
For more information about these samples, see the descriptions in the Remote Resource Access API
topics in Help Contents.

50 Developer for z/OS: Reference


Remote Resource Access API samples
The use of the Remote Resource Access API is illustrated by the sample plug-in
com.ibm.ftt.api.samples. It consists of a series of sample classes that illustrate a particular aspect
of the Remote Resource Access API and how the Developer for z/OS function can be extended.
Descriptions of the sample classes that are contained in the sample plug-in can be found in the following
topics:

Getting the list of systems


This sample demonstrates how you can programmatically obtain the list of system objects that are
currently defined. Through a system object, you can obtain basic properties such as the name, the IP
address, and the connection status of the system.

Sample scenario
To retrieve information about z/OS systems, select the API Samples > Systems Information. action.
For each system that is defined, the name, IP address, and connection status are displayed in the
standard output that is associated with the workbench. This information can be found in the Console view
of the workbench.
Note: The standard output for a workbench started with the standard Eclipse icon might not be visible
depending on the runtime settings for the workbench.

Reference 51
Retrieving the system list and obtaining system properties
The following code snippet from the ListSystemsAction class contains the core of the sample.

Object [] systemReferences = PhysicalSystemRegistryFactory.


getSingleton().getSystems(IPopulatorConstants.MVSFiles);

for (int i = 0; i < systemReferences.length; i++) {


if (systemReferences[i] instanceof IOSImage) {
IOSImage system = (IOSImage) systemReferences[i];
System.out.println("----------");
System.out.println("System " + i + ": " +
system.getName());
System.out.println("IP address = " +
system.getIpAddress());
if (system.isConnected()) {
System.out.println("System is currently connected.");
} else {
System.out.println(
"System is not currently connected.");
}
}
}

First, it uses the PhysicalSystemRegistry class, obtained from the getSingleton method of the
PhysicalSystemRegistryFactory class, to retrieve the IOSImage objects that represent the MVS
subsystems that are defined in the workspace. Then, it iterates through each of the subsystems and prints
the following information:
• Name of the connection (getName)
• IP address of the connection (getIpAddress)
• Connection status (isConnected)
The menu item is contributed to the workbench through an Eclipse action set:

<extension
id="com.ibm.ftt.api.samples.actionSets"
name="%apiSample.actionSets"
point="org.eclipse.ui.actionSets">
<actionSet label="com.ibm.ftt.api.samples.actionSet1"
description="Action set for the API samples"
visible="true"
id="com.ibm.ftt.api.samples.actionSet1">
<menu label="%apiMenu.title"
id="com.ibm.ftt.api.samples.apiMenu">
<separator name="com.ibm.ftt.api.samples.apiMenu.resourcesAPI"/>
</menu>
<action label="%apiMenu.samples.listSystems"
class="com.ibm.ftt.api.samples.resources.ListSystemsAction"
style="push" menubarPath=
"com.ibm.ftt.api.samples.apiMenu/com.ibm.ftt.api.samples.apiMenu.resourcesAPI"
id="com.ibm.ftt.api.samples.listSystemsAction"/>
......
</actionSet>
</extension>

52 Developer for z/OS: Reference


Getting the list of projects
This sample demonstrates how to obtain a list of remote projects that exist in the workspace. It also
demonstrates how to traverse the children added to the remote projects.

Sample scenario
To retrieve information about z/OS projects, select the API Samples > Projects Information action.
For each project that is defined, some basic information about the projects and a hierarchical list of data
sets and members are displayed. For each child under the project, the applicable COBOL compiler options
set for each of them are shown. The output is sent to the standard output associated with the workbench.
This information can be found in the Console view of the workbench.
Note: The standard output for a workbench started with the standard Eclipse icon might not be visible.

Iterating through all known subprojects


The process of getting the list of projects is similar to getting the list of systems.
The following code snippet iterates through the list of projects and subprojects that are defined in the
current workspace.

Object [] projectReferences =
LogicalProjectRegistryFactory.getSingleton().getProjects();

for (int i = 0; i < projectReferences.length; i++) {


ILogicalProject project =
(ILogicalProject) projectReferences[i];
System.out.println("----- Project[" + i + "]: " +
project.getName());
List subProjects = project.getChildren();

for (int j = 0; j < subProjects.size(); j++) {


ILogicalSubProject subProject =
(ILogicalSubProject)subProjects.get(j);
System.out.println(INITIAL_INDENT + "Subproject[" + j +
"]: " + subProject.getName());
printSubproject(subProject, INITIAL_INDENT +
INDENT_PREFIX);
}
}

The code starts by using the LogicalProjectRegistry class, obtained by the getSingleton method
of the LogicalProjectRegistryFactory class, to obtain the list of all ILogicalProject instances
that are defined in the workbench. It then iterates through the list of known projects, obtaining the
children of each project from the getChildren method. An ILogicalProject object can contain
only ILogicalSubProject objects as children. The ILogicalSubProject objects are in turn iterated
through and processed.
The getName method obtains the name of the project and the subproject.

Reference 53
Determining whether the associated system is connected
You can determine whether the system associated with an MVS subproject is connected. After you have
a reference to an ILogicalSubProject, retrieve the IOSImage object that represents the particular
system by using the method getSystems. Each MVS subproject corresponds to only one MVS file system.
After you have the IOSImage object, you can determine whether the system is connected by using the
(isConnected) method. The following code snippet is from the printSubproject sample method.

if (subProject.getSystems()[0].isConnected()) {
printMembers(subProject, indent);
} else {
......
}

Retrieving project or resource properties


The mechanism for retrieving and setting projects might be deprecated and changed.
The getPersistentProperty method can be used to retrieve project properties. The following code
snippet from the printSubproject sample method retrieves the COBOL compiler options for the
subproject.

String compileOptions = subProject.getPersistentProperty(


IPhysicalResourceCoreConstants.COBOL_COMPILE_OPTIONS);

Similarly, the printMember sample method uses it to retrieve the COPYLIB associated with the specified
resource.

String copyLibraries =
resource.getPersistentProperty(IPhysicalResourceCoreConstants.COBOL_COMPILE_COPYLIBRARIES);

Traversing the subproject tree structure


To obtain the artifacts added to a subproject, or any ILogicalContainer objects, use the
members method. The following code snippet is taken from the printMembers method. An
ILogicalSubProject class inherits from the ILogicalContainer class.

IAdaptable [] members = container.members();


for (int j = 0; j < members.length; j++) {
printMember((ILogicalResource) members[j], indent + INDENT_PREFIX);
}

The printMember method then prints the appropriate information for the current resource. If the current
resource is an ILogicalContainer, it co-recursively starts the printMembers method to descend into
the subtree.

if (resource instanceof ILogicalContainer) {


ILogicalContainer memberContainer = (ILogicalContainer) resource;
......
printMembers(memberContainer, indent);
} else {
System.out.println(indent + "member[" + index + "] " + resource.getName()
+ " having COBOL copy libraries: " + copyLibraries);
}

54 Developer for z/OS: Reference


Finding a resource given its qualified name
This sample demonstrates how to obtain the reference to a remote object, given its fully qualified name,
by using the Finder objects. The remote objects can then be used to manipulate the remote artifacts as
appropriate.

Sample Scenario
To retrieve information about the specified resource, make sure the fully qualified name, of the form
system.name datasetname(membername) is in the current selection, then select the API Samples >
Find Resource action.
The name, full path, modification time stamp, and compiler options of the resource are displayed in the
standard output that is associated with the workbench. This information can be found in the Console view
of the workbench.
Note: The standard output for a workbench started with the standard Eclipse icon might not be visible.

Finding a Resource Object Given its Name


The following code snippet from the sample method findResource in the FindResourceAction class
demonstrates how to obtain a resource object given its data set/member name.

ZOSResourceIdentifier identifier = ZosfactoryFactory.eINSTANCE.


createZOSResourceIdentifier();

identifier.setDataSetName(dataset);
identifier.setMemberName(member);
identifier.setSystem(systemName);
IPhysicalResource res = ZOSPhysicalResourceFinder.eINSTANCE.
findPhysicalResource(identifier);

The code starts by creating an ZOSResourceIdentifier object. A ZOSResourceIdentifier


encapsulates the name information that is needed to uniquely specify an MVS resource. After setting
the data set name, member name, and system name as appropriate, the code passes that information to
the findPhysicalResource method in ZOSPhysicalResourceFinder. This method is responsible
for retrieving and returning an IPhysicalResource object that represents the resource.

Obtaining information about the resource object


After you have the IPhysicalResource objects, you can do various operations on them. This sample
code retrieves information about the resource, such as the name, modification time stamp, and
system name, by using the getter methods getName, getFullPath, getModificationStamp, and
getSystem.

System.out.println("Name of the resource is " +


resource.getName());
System.out.println("Fullpath of the resource is "
+ resource.getFullPath());
System.out.println("Modification time stamp is "

Reference 55
+ resource.getModificationStamp() + " ("
+ new Date(resource.getModificationStamp()) + ")");
System.out.println("Name of the associated system is "
+ resource.getSystem().getName());

Responding to Eclipse selection events


This example also demonstrates how to react to selection change events in Eclipse.
The FindResourceAction class implements the ISelectionListener interface. Its
selectionChanged reacts to ITextSelection by extracting the text in the current selection by using
the getText method.

public void selectionChanged(IAction action, ISelection selection) {


fSelectedText = null;
if (selection instanceof ITextSelection) {
ITextSelection textSelection = (ITextSelection) selection;
fSelectedText = textSelection.getText();
}
}

Opening a file in the default editor


This sample demonstrates how to open a remote file in the default editor.

Sample scenario
To open a remote resource in the default editor, select a remote resource and then select the API Sample
Actions > Open File action.

Retrieving file content


This sample demonstrates how to retrieve the contents of a file (data set member or sequential data set)
on the MVS file system.

Sample scenario
To retrieve the content for the resource, make sure that the resource is selected in the navigator, then
select the API Samples > Get File Contents action.
The contents in the file are displayed in the standard output that is associated with the workbench. The
contents can be found in the Console view of the workbench.
Note: The standard output for a workbench started with the standard Eclipse icon might not be visible.

Sample code walk-through


The complete source code can be found at GetContentsAction.java.

56 Developer for z/OS: Reference


Reading from the remote artifact
The following code snippet from the run method of the class GetContentsAction demonstrates how
to obtain the content of an MVS file (PDS member or sequential data set). The snippet differentiates
between an IPhysicalFile and an ILogicalFile, but the overall flow is the same for both. The code
first starts the getContents method to obtain an InputStream. After you have an InputStream, the
standard Java methods such as read can be started to retrieve the content of the file.

InputStream is = null;
if (selectedItem instanceof ILogicalFile) {
// Project proxy for resource
ILogicalFile file = (ILogicalFile) selectedItem;
filename = file.getName();
is = file.getContents();
} else if (selectedItem instanceof IPhysicalFile) {
// Physical Resource
IPhysicalFile file = (IPhysicalFile) selectedItem;
filename = file.getName();
is = file.getContents();
}
int ch = is.read();
while (ch != -1) {
System.out.write(ch);
ch = is.read();
}

Handling selection changed events


This example also demonstrates how to react to selection change events in Eclipse. The
GetContentsAction class implements the ISelectionListener interface. Its selectionChanged
method implementation reacts to events that refer to an IStructuredSelection, typically caused by
a change in the current selection in a tree navigator. The sample code iterates through the items in the
current selection by using an iterator that is associated with it and adding each item to a list.

public void selectionChanged(IAction action, ISelection selection) {


fTargetList = null;
if (selection instanceof IStructuredSelection) {
fTargetList = new ArrayList();
IStructuredSelection selections = (IStructuredSelection)
selection;
for (Iterator e = selections.iterator(); e.hasNext();) {
Object next = e.next();
fTargetList.add(next);
}
}
}

Contribution of menu item


The menu item is contributed through a simple use of the Eclipse org.eclipse.ui.actionSets extension
point.

<extension
id=“com.ibm.ftt.api.samples.actionSets”
name=“
point=“org.eclipse.ui.actionSets”>
<actionSet
label=“com.ibm.ftt.api.samples.actionSet1”
description=“Action set for the API samples”
visible=“true”
id=“com.ibm.ftt.api.samples.actionSet1”>
<menu
label=“
id=“com.ibm.ftt.api.samples.apiMenu”>
<separator name=“com.ibm.ftt.api.samples.apiMenu.resourcesAPI”/>
</menu>
<action
label=“
class=“com.ibm.ftt.api.samples.resources.GetContentsAction”
style=“push”
menubarPath=“com.ibm.ftt.api.samples.apiMenu/

Reference 57
com.ibm.ftt.api.samples.apiMenu.resourcesAPI”
id=“com.ibm.ftt.api.samples.getContentAction”/>
......
</actionSet>
</extension>

A menu action is defined at the group that is associated with the samples
menu, which is specified with the menu path com.ibm.ftt.api.samples.apiMenu/
com.ibm.ftt.api.samples.apiMenu.resourcesAPI. Furthermore, the menu action is associated
with the GetContentsAction class. This class is started when you click the menu item.

Copying a physical resource


This sample demonstrates how to copy a physical resource.

Sample scenario
To copy a physical resource, select a remote resource and then select the API Sample Actions > Copy
Physical Resource action.

Creating a logical resource from a physical resource


This sample demonstrates how to create a logical resource from a physical resource.

Sample scenario
To create a logical resource from a physical resource, select a remote resource and then select the API
Sample Actions > Create Logical Resource action.

Allocating a partitioned data set


This sample demonstrates how to programmatically allocate a partitioned data set with a particular set of
data set characteristics.

Sample scenario
Right-click the MVS Files subsystem for the appropriate connection and then select the API Sample
Actions > Allocate PDS action.
A sample partitioned data set is allocated. The name of the allocated data set is hardcoded in the action
as the constant DATASET_NAME.
If the data set exists, it is deleted and then reallocated. The following messages are sent to system
output.

58 Developer for z/OS: Reference


Checking for the existence of a data set on the MVS file system
The run method of the sample starts by making sure that the data set it is about to create does not
exist. First, it obtains the ZOSCatalog for the MVS file system by calling getCatalog for the selected
ISystemReference.

ZOSCatalog catalog = getCatalog((ZOSSystemReference)selectedItem);

After the ZOSCatalog is obtained, its findMember method is started to see whether a partitioned
data set with the specified name exists. If the data set exists already, the sample attempts
to delete the existing data set by using the delete method. It is important to catch the
OperationFailedException in case something goes wrong during the delete.

ZOSPartitionedDataSet newPDS = null;


......
newPDS = (ZOSPartitionedDataSet)
catalog.findMember(DATASET_NAME);
if(newPDS != null){
try {
......
newPDS.delete(true, null);
} catch (OperationFailedException ofe) {
System.err.println("Allocate PDS Action - PDS ("
+ DATASET_NAME +
") already exists and could not be deleted.");
return;
}
}

Allocate the partitioned data set


IPhysicalResourceFactory physicalFactory =
PhysicalResourceFactoryFactory.getFactory(
ZOSCatalog.class, ZOSDataSet.class);
......
ZOSDataSet res =
(ZOSDataSet)physicalFactory.getPhysicalResource(catalog,ZOSPartitionedDataSet.class,DATASET_NAME
);
res.setCharacteristics(getCharacteristics());
try {
res.allocate(null);
} catch (OperationFailedException e) {
System.out.println("Allocate PDS Action - PDS allocation failed" + e.getMessage());
}

Creating a member in a partitioned data set


This sample demonstrates how to create a data set member under a partitioned data set. It also
demonstrates how to contribute a menu item in the menu for remote artifacts in the navigator views.

Sample scenario
To use this sample, right-click a partitioned data set in the Remote Systems Explorer View, and select the
API Sample Actions > Create Member action.
A member with the name TEMP is created in the selected data set.

Creating a data set member IPhysicalResource


The createPhysicalMember sample method starts by checking to make sure that the member to be
created does not exist, by using the method findMember. The findMember method returns null if the
resource is not found.

IPhysicalFile resource = (IPhysicalFile)


dataSet.findMember(MEMBER_NAME);
if (resource != null) {
System.err.println("Resource " + MEMBER_NAME +
" already exists");

Reference 59
return;
}

The member is then created as follows. An IPhysicalResource object that references the member
is created by using the getPhysicalResource method of the ZOSPhysicalResourceFactory class.
(The resource object that is returned by the getPhysicalResource method is not required to represent
an actual existing remote system resource.) After you have the IPhysicalResource, the actual member
can then be created on the remote system by starting create method.

ZOSPhysicalResourceFactory factory =
ZOSPhysicalResourceFactory.eINSTANCE;
resource = (IPhysicalFile) factory.getPhysicalResource(dataSet,
ZOSDataSetMember.class, MEMBER_NAME);
try {
resource.create(
new ByteArrayInputStream(MEMBER_CONTENT.getBytes()),
true, null);
} catch (OperationFailedException e) {
......
}

The create method expects an InputStream containing the content for the file to be created.

Creating a data set member ILogicalResource


The process of creating a data set member in an MVS subproject is similar. Consider the
createLogicalMember method in the CreateMemberAction sample class. It starts by obtaining
the IPhysicalResource object that is referred to by the selected ILogicalResource, by using the
getPhysicalResource method.

IPhysicalContainer container = null;


if (dataSet.getState().isOnline()) {
container = (IPhysicalContainer) dataSet.
getPhysicalResource();
} else {
System.err.println("DataSet " + dataSet.getName() +
" should not be offline.");
return;
}

Processing of offline resources by using the Remote Access API is not yet supported.
The code then proceeds to create a data set member IPhysicalResource as in “Creating a data set
member IPhysicalResource” on page 59.

IPhysicalFile resource = (IPhysicalFile) factory.getPhysicalResource(


container, ZOSDataSetMember.class, MEMBER_NAME);
try {
resource.create(
new ByteArrayInputStream(MEMBER_CONTENT.getBytes()),
true, null);
} catch (OperationFailedException e) {
......
}

The following code snippet then adds the resource to the appropriate subproject obtained
through the getSubProject method. The code snippet accomplishes this purpose by using the
LogicalResourceFactory class. This method can be used to add any physical resource to a project, by
using the Add to Subproject menu action.

ILogicalSubProject subProject = dataSet.getSubProject();


if (project != null && resource != null) {
LogicalResourceFactoryFactory.getSingleton().getLogicalResource(
subProject, resource);
}

60 Developer for z/OS: Reference


Responding to selection changed events
This example also demonstrates how to react to selection change events in
Eclipse. The CreateMemberAction class implements the ISelectionListener interface.
Its selectionChanged method implementation reacts to events that refer to an
IStructuredSelection, typically caused by a change in the current selection in a tree navigator. The
sample code iterates through the items that are contained in the current selection by using an iterator
that is associated with it. In this example, the first item that is selected is chosen.

selectedItem = null;
if (selection instanceof IStructuredSelection) {
IStructuredSelection currentSelection =
(IStructuredSelection) selection;
Iterator iterator = currentSelection.iterator();
while (iterator.hasNext()) {
Object item = iterator.next();
if (item instanceof LZOSPartitionedDataSet) {
selectedItem = item;
break;
} else if (item instanceof ZOSResourceReference) {
item = ((ZOSResourceReference) item).getReferent();
if (item instanceof ZOSPartitionedDataSet) {
selectedItem = item;
break;
}
}
}
}

An ILogicalResource object (LZOSPartitionedDataSet in this case) is returned in the selection


object, if an object in a z/OS project is selected. If an object in the MVS file system is selected on
the Remote Systems Explorer View, a ZOSResourceReference is returned. In the latter case, you can
retrieve the corresponding IPhysicalResource by using the getReferent method.

Contributing menu items to the menu


Menu items can be contributed to the menu by using the org.eclipse.ui.popupMenus extension
point. This sample defines two object contributions, one against LZOSPartitionedDataSet for the
z/OS Projects View, and another against ZOSResourceReference for the Remote Systems Explorer
View. In both cases, selecting the menu item causes CreateMemberAction to be started.

<extension
id="com.ibm.ftt.api.samples.popupMenus"
name="%apiSample.popupMenus"
point="org.eclipse.ui.popupMenus">
<objectContribution
adaptable="false"
objectClass= "com.ibm.ftt.resources.zos.zosphysical.ZOSResourceReference"
id="com.ibm.ftt.api.samples.physical.patitionedDataset">
......
<action
label="%apiMenu.samples.createMember"
class= "com.ibm.ftt.api.samples.resources.CreateMemberAction"
menubarPath="com.ibm.ftt.api.samples.PopupMenu/group1"
id="com.ibm.ftt.api.samples.physical.createMember"/>
</objectContribution>
......
<objectContribution
adaptable="false"
objectClass= "com.ibm.ftt.projects.zos.zoslogical.LZOSPartitionedDataSet"
id="com.ibm.ftt.api.samples.logical.patitionedDataset">
<menu
id="com.ibm.ftt.api.samples.PopupMenu"
label="
<separator name="group1"/>
</menu>
<action
label="%apiMenu.samples.createMember"
class= "com.ibm.ftt.api.samples.resources.CreateMemberAction"
menubarPath="com.ibm.ftt.api.samples.PopupMenu/group1"
id="com.ibm.ftt.api.samples.logical.createMember"/>
</objectContribution>

Reference 61
Subscribing to events related to remote resources
This sample demonstrates how to subscribe to events related to remote resources.

Sample scenario
To subscribe to events related to remote resources, select a remote resource and then select the API
Sample Actions > Subscribe to Events action.

Filtering actions and property pages by project nature


This sample demonstrates how to add a custom project nature to a subproject. The presence or absence
of the project nature can then be used to control the visibility of menu items.

Sample scenario
Create a z/OS project and MVS subproject according to the instructions in the following topics:
• Creating a z/OS project
• Creating an MVS subproject
To add the sample project nature to the subproject, right-click the subproject and select the API Sample
Actions > Add Project Nature action.

Subproject nature definition


Subproject natures in Developer for z/OS are similar in concept to IProjectNature in base Eclipse.
They provide a means to distinguish between remote subprojects based on the function that is to be
enabled for each subproject.
To define a custom project nature for a remote subproject, you must create a class that implements the
ILogicalSubProjectNature interface. Thus the SampleNature class contains the following code:

public class SampleNature implements ILogicalSubProjectNature {


......
}

The ILogicalSubProjectNature interface is relatively simple. In SampleNature, you add a private


field project for the project property.
The complete source code can be found in SampleNature.java.
To complete the definition of the project nature, declare the SampleNature class in the plug-in manifest
as follows:

<extension
id=“samplenature”
name=“
point=“com.ibm.ftt.projects.core.natures”>
<nature class=“com.ibm.ftt.api.samples.natures.SampleNature”/>
</extension>

This snippet defines a project nature with the ID com.ibm.ftt.api.samples.samplenature,


which is obtained by appending the extension ID samplenature to the ID of the defining plug-in
com.ibm.ftt.api.samples.

Adding a project nature


The Add Project Nature menu item is implemented by the AddSubProjectNatureAction class.
Its run(IAction) method adds the SampleNature by passing the ID of the nature to the
addNatureId(String) method of ILogicalSubProject.

try {
getSubProject().addNatureId("com.ibm.ftt.api.samples.samplenature");
} catch (CoreException e) {
// TODO: in production code exception should be handled for real

62 Developer for z/OS: Reference


e.printStackTrace();
}

The complete source code can be found in AddSubProjectNatureAction.java.


The action is contributed by using standard Eclipse contribution mechanisms.

<objectContribution
adaptable=“false”
objectClass=“com.ibm.ftt.projects.core.logical.ILogicalSubProject”
id=“com.ibm.ftt.api.samples.addnature”>
<action
label=“
class=“com.ibm.ftt.api.samples.natures.AddSubProjectNatureAction”
id=“com.ibm.ftt.api.samples.addnatureaction”/>
</objectContribution>

Removing a project nature and contributing menu items filtered by project natures
The Remove Project Nature menu item is implemented by the RemoveSubProjectNatureAction
class. Its run(IAction) method removes the SampleNature by passing the ID of the nature to the
removeNatureId(String) method of ILogicalSubProject.

try {
getSubProject().removeNatureId(“com.ibm.ftt.api.samples.samplenature”);
} catch (CoreException e) {
// TODO: in production code exception should be handled for real
e.printStackTrace();
}

The complete source code can be found at RemoveSubProjectAction.java.


The action is contributed by using standard Eclipse contribution mechanisms, similar to the Add Project
Nature menu item, with the additional use of action filters. This contribution causes the Remove Project
Nature action to be displayed only if the SampleNature is added to the project in question.

<objectContribution
adaptable=“false”
objectClass=“com.ibm.ftt.projects.core.logical.ILogicalSubProject”
id=“com.ibm.ftt.api.samples.removenature”>
<filter
value=“com.ibm.ftt.api.samples.samplenature”
name=“projectNature”/>
<action
label=“
class=“com.ibm.ftt.api.samples.natures.RemoveSubProjectNatureAction”
id=“com.ibm.ftt.api.samples.removenatureaction”/>
</objectContribution>

Creating a property group


This sample demonstrates how to programmatically create a property group that has values for
predefined properties and properties that are registered with Developer for z/OS.

Sample scenario
To create a property group, select the API Sample Actions -> Create Property Group action from the
menu of an MVS Files node in the Remote Systems view.
Statements are displayed when the property group is created and the property values are set. Also, if any
error conditions are detected, error messages are displayed as well. They are displayed in the standard
output that is associated with the workbench. This information can be found in the Console view of the
workbench.
Note: The standard output for a workbench started with the standard Eclipse icon might not be visible
depending on the runtime settings for the workbench.
The following illustration shows the results of successfully creating the property group and setting the
values:

Reference 63
Retrieving the property group container for the system
The following code snippet from the CreatePropertyGroupAction class demonstrates how to retrieve
the property group container for the selected system:

if (selectedItem == null) {
System.err.println("Create Property Group Action - Selected resource must be an MVS File
subsystem.");
return;
}
if (selectedItem instanceof ZOSSystemReference) {
System.out.println("");
System.out.println("-----------------------");
System.out.println("Beginning Create Property Group Action...");
ZOSSystemReference reference = (ZOSSystemReference) selectedItem;
ZOSSystemImage system = (ZOSSystemImage) reference.getReferent();
// Get the property group container for this system.
ZOSPropertyGroupManager manager = ZOSPropertyGroupManager.getZOSPropertyGroupManager();
IPropertyGroupContainer container = manager.getPropertyGroupContainer(system.getName());
if (container == null) {
System.err.println("Create Property Group Action - No container for system: " +
system.getName());
return;
}

It starts by verifying that the selectedItem is an instance of the ZOSSystemReference class. If so, it
retrieves the ZOSSystemImage from the ZOSSystemReference by using the getReferent method.
For each system connection, there is a property group container. The property group container
for a system name can be retrieved by using the getPropertyGroupContainer method of the
ZOSPropertyGroupManager class.

Creating a property group


This sample from the CreatePropertyGroupAction class demonstrates how to create a property
group that contains a category instance from a user-defined category and a category instance from a
predefined category.

IPropertyGroup group = null;


try {
group = container.createPropertyGroup(PROPERTY_GROUP_NAME, "");
System.out.println(PROPERTY_GROUP_NAME + " created.");
} catch (DuplicatePropertyGroupException e1) {
System.err.println("Create Property Group Action - Property group already exists.");
return;
}

The property group is created by using the createPropertyGroup method. If the property group exists,
a DuplicatePropertyGroupException is thrown and an error message is printed.

64 Developer for z/OS: Reference


Adding a user-defined category to a property group
The following code snippet demonstrates how to create a category instance for a user-defined category
and add it to a property group:

// Create an instance of the user-defined category, set properties,


// and add the instance to the property group. These properties will not appear
// in the UI, but they are available through the API.
try {
ICategory category = manager.getCategory("SAMPLE_CATEGORY");
if (category == null) {
System.err.println("Create Property Group Action - Could not find category
SAMPLE_CATEGORY.");
return;
}
ICategoryInstance instance = category.makeInstance();
instance.setValue("PROPERTY_1", "value1");
System.out.println("PROPERTY_1 set to value1");
instance.setValue("PROPERTY_2", "value2");
System.out.println("PROPERTY_2 set to value2");
group.addCategoryInstance(instance);
} catch (UnregisteredPropertyException e) {
System.err.println("Create Property Group Action - Unregistered property: " + e.getName());
return;
} catch (DuplicateInstanceException e) {
System.err.println("Create Property Group Action - Duplicate instance of category: " +
e.getCategoryInstance().getCategory().getName());
return;
}

An instance of the SAMPLE_CATEGORY category is created by the previous code snippet. This category is
registered with Developer for z/OS using the following Eclipse extension point:

<extension point="com.ibm.ftt.properties.api.category">
<category name="SAMPLE_CATEGORY">
<property name="PROPERTY_1" />
<property name="PROPERTY_2" />
</category>
</extension>

These property values are not displayed in the Developer for z/OS user interface because the user
interface is not extensible, but they are available through the API.

Adding a predefined category to a property group


The following code snippet demonstrates how to create a category instance for a predefined category and
add it to a property group.

// Create an instance of a pre-defined category, set properties,


// and add the instance to the property group. The values are not
// realistic values, this is just an example of how to work with
// pre-defined properties.
try {
ICategory category = manager.getCategory(IPropertyGroupConstants.JCL_OPTIONS);
if (category == null) {
System.err.println("Create Property Group Action - Could not find category " +
IPropertyGroupConstants.COBOL_SETTINGS);
return;
}
ICategoryInstance instance = category.makeInstance();
instance.setValue(IPropertyGroupConstants.JOBCARD, "//sample jobcard");
System.out.println(IPropertyGroupConstants.JOBCARD + " set to //sample jobcard");
instance.setValue(IPropertyGroupConstants.GENERATED_JCL_DATASET, "sample.test.jcl");
System.out.println(IPropertyGroupConstants.GENERATED_JCL_DATASET + " set to sample.test.jcl");
group.addCategoryInstance(instance);
} catch (UnregisteredPropertyException e) {
System.err.println("Create Property Group Action - Unregistered property: " + e.getName());
return;
} catch (DuplicateInstanceException e) {
System.err.println("Create Property Group Action - Duplicate instance of category: " +
e.getCategoryInstance().getCategory().getName());
}

(IPropertyGroupConstants) contains the names of the predefined categories and properties.

Reference 65
Getting the lists of categories, properties, and category instances
This sample demonstrates how to programmatically obtain the list of registered categories and
properties. Currently, the names of the registered categories and properties can be obtained. For each
category, the instances of that category can be obtained, and the property values in each instance can be
obtained.

Sample scenario
To retrieve information about the categories, properties, and instances, select the API Samples >
Properties Information action.
For each registered category, the name, the properties, and any instances of the category are displayed in
the standard output that is associated with the workbench. This information can be found in the Console
view of the workbench.
Note: The standard output for a workbench started with the standard Eclipse icon might not be visible
depending on the runtime settings for the workbench.

Retrieving registered categories


The following code snippet from the ListPropertiesAction class demonstrates how to retrieve the
registered categories:

ZOSPropertyGroupManager manager = ZOSPropertyGroupManager.getZOSPropertyGroupManager();


// Retrieve registered categories
List<ICategory> categories = manager.getCategories();

It starts by using the ZOSPropertyGroupManager class, obtained by using the


getZOSPropertyGroupManager method of the ZOSPropertyGroupManager class, to retrieve the
ICategory objects that represent the registered categories. The registered categories can also be
obtained by using the ( LocalPropertyGroupManager) class, since both managers share the Eclipse
extension point to register properties.

Retrieving properties by using category objects


The following code snippet from the ListPropertiesAction class demonstrates how to use
ICategory objects:

for (ICategory category : categories) {


System.out.println("---------------");
System.out.println("Category: " + category.getName());

66 Developer for z/OS: Reference


// Retrieve registered properties for this category.
List<IPropertyInfo> infos = category.getPropertyInformation();
for (IPropertyInfo info : infos) {
System.out.println(" Property: " + info.getName());
}
// Retrieve category instances for each registered category, and print
// the properties and values for each instance.
List<ICategoryInstance> instances = category.getInstances();
for (ICategoryInstance instance : instances) {
System.out.println(" Instance: ");
List<IProperty> properties = instance.getProperties();
for (IProperty property : properties) {
System.out.println(" ----");
System.out.println(" Property name: " + property.getName());
System.out.println(" Property value: " + property.getValue());
}
}

Each category has a name and retrieves IPropertyInfo objects, which have the names of the
registered properties for that category.
Each category retrieves ICategoryInstance objects, which hold property values. Finally, the
IProperty objects that are retrieved from a ICategoryInstance object have the name of the property
and the property value.
The menu item is contributed to the workbench through an Eclipse action set:

<extension
id="com.ibm.ftt.api.samples.actionSets"
name="%apiSample.actionSets"
point="org.eclipse.ui.actionSets">
<actionSet label="com.ibm.ftt.api.samples.actionSet1"
description="Action set for the API samples"
visible="true"
id="com.ibm.ftt.api.samples.actionSet1">
<menu label="%apiMenu.title"
id="com.ibm.ftt.api.samples.apiMenu">
<separator name="com.ibm.ftt.api.samples.apiMenu.resourcesAPI"/>
</menu>
<action label="%apiMenu.samples.listProperties"
class="com.ibm.ftt.api.samples.resources.ListPropertiesAction"
style="push" menubarPath=
"com.ibm.ftt.api.samples.apiMenu/com.ibm.ftt.api.samples.apiMenu.resourcesAPI"
id="com.ibm.ftt.api.samples.listPropertiesAction"/>
......
</actionSet>
</extension>

Specifying a different builder for an MVS subproject


This sample demonstrates how to replace the default builder of an MVS subproject with a new builder.
The new builder can be used to change the way that the subproject is built when a build action is
requested.

Sample scenario
Create a z/OS project and MVS subproject according to the instructions in the following topics:
• Creating a z/OS project
• Creating an MVS subproject
The act of creating a subproject causes an XML file to be created in which various characteristics and
properties of the subproject are maintained. The following illustration shows a portion of this XML file
after creation of the subproject:

Reference 67
To replace the default subproject builder with a different (user-defined) builder, right-click the subproject
and select the API Sample Actions > Replace Default Builder action.
This action causes the information in the XML file to be updated. The file might not be updated
immediately, but the builder information changes the next time that the file is written. The file looks
similar to the following illustration:

68 Developer for z/OS: Reference


If you want to restore the original (default) subproject builder, select the API Sample Actions > Restore
Default Builder action.

Subproject builder definition


Subproject builders in Developer for z/OS are similar in concept to an incremental project builder in base
Eclipse. They provide a means to build the contents of a subproject, creating new or updated build results.
For example, all of the COBOL source files in the subproject can be processed by a COBOL compiler. The
resulting files (object, listing, executable file) can be added to the subproject.
To define a custom project builder for a remote subproject, you need to create a class that implements
the ILogicalSubProjectBuilder interface. Thus the SampleBuilder class contains the following
code:

public class SampleBuilder implements ILogicalSubProjectBuilder {


......
}

The ILogicalSubProjectBuilder interface is relatively simple. In SampleBuilder, add a private


field subproject for the subproject instance. This sample issues the println statement "Sample
Builder called for subProject:". It includes the subproject name.
The complete source code can be found in SampleBuilder.java.

Replacing the default subproject builder


The Replace Default Builder menu item is implemented by the AddSubProjectBuilderAction class.
Its run(IAction) method changes the buildSpec of the subproject to replace the name of the default
builder class with the name of the sample builder class SampleBuilder. It accomplishes this purpose by
using the getBuildSpec() method, finding the old builder in the IBuildCommand list, and updating the

Reference 69
BuildSpec by using the setBuildSpec(com.ibm.ftt.projects.core.logical.IBuildCommand
newCommands) method.

IBuildCommand[] buildCommands = subProject.getBuildSpec();

// look through the existing build commands for the "standard"


// RDz builder for MVS subprojects, and if found substitute the
// sample builder in its place
for (int i = 0; i < buildCommands.length; ++i) {
if (buildCommands[i].getBuilderName().equals(IProjectCoreConstants.ZOS_BUILDER_ID))
{
// copy the commands preceding the RDz builder
IBuildCommand[] newCommands = new IBuildCommand[buildCommands.length];
if (i > 0) {
System.arraycopy(buildCommands, 0, newCommands, 0, i - 1);
}
// create a new command for the sample builder
IBuildCommand buildCommand = getSubProject().newCommand();
buildCommand.setBuilderName("com.ibm.ftt.api.samples.samplebuilder");
// add the new command
newCommands[i] = buildCommand;
// copy the rest of the build commands
if (i < buildCommands.length) {
System.arraycopy(
buildCommands,
i + 1,
newCommands,
i,
buildCommands.length - i - 1);
}

// store the new set of build commands


subProject.setBuildSpec(newCommands);

System.out.println("Sample builder replaces RDz builder");


break;
}
}

The complete source code can be found in AddSubProjectBuilderAction.java.


The action is contributed by using standard Eclipse contribution mechanisms.

<objectContribution
adaptable=“false”
objectClass=“com.ibm.ftt.projects.core.logical.ILogicalSubProject”
id=“com.ibm.ftt.api.samples.addbuilder”>
<visibility>
<not>
<objectState
name=“projectBuilder”
value=“com.ibm.ftt.api.samples.samplebuilder”>
</objectState>
</not>
</visibility>
<action
label=“
class=“com.ibm.ftt.api.samples.builders.AddSubProjectBuilderAction”
menubarPath=“com.ibm.ftt.api.samples.PopupMenu/group1”
id=“com.ibm.ftt.api.samples.addbuilderaction”/>
</objectContribution>

Restoring the default subproject builder


The Restore Default Builder menu item is implemented by the RemoveSubProjectBuilderAction
class. Its run(IAction) method changes the buildSpec of the subproject to replace
the name of the sample builder class SampleBuilder with the name of the default
builder class. It accomplishes this purpose by using the getBuildSpec() method, finding
the old builder in the IBuildCommand list, and updating the BuildSpec by using
the setBuildSpec(com.ibm.ftt.projects.core.logical.IBuildCommand newCommands)
method.

IBuildCommand[] buildCommands = subProject.getBuildSpec();

70 Developer for z/OS: Reference


// look through the existing build commands for the sample
// builder, and if found substitute the "standard" RDz builder
// in its place
for (int i = 0; i < buildCommands.length; ++i) {
if
(buildCommands[i].getBuilderName().equals("com.ibm.ftt.api.samples.samplebuilder")) {
// copy the commands preceding the sample builder
IBuildCommand[] newCommands = new IBuildCommand[buildCommands.length];
if (i > 0) {
System.arraycopy(buildCommands, 0, newCommands, 0, i - 1);
}
// create a new command for the RDz builder
IBuildCommand buildCommand = getSubProject().newCommand();
buildCommand.setBuilderName(IProjectCoreConstants.ZOS_BUILDER_ID);
// add the new command
newCommands[i] = buildCommand;
// copy the rest of the build commands
if (i < buildCommands.length) {
System.arraycopy(
buildCommands,
i + 1,
newCommands,
i,
buildCommands.length - i - 1);
}

// store the new set of build commands


subProject.setBuildSpec(newCommands);

System.out.println("RDz builder replaces Sample builder");


break;
}
}

The complete source code can be found in RemoveSubProjectBuilderAction.java.


The action is contributed by using standard Eclipse contribution mechanisms.

<objectContribution
adaptable=“false”
objectClass=“com.ibm.ftt.projects.core.logical.ILogicalSubProject”
id=“com.ibm.ftt.api.samples.removebuilder”>
<filter
value=“com.ibm.ftt.api.samples.samplebuilder”
name=“projectBuilder”/>
<action
label=“
class=“com.ibm.ftt.api.samples.builders.RemoveSubProjectBuilderAction”
menubarPath=“com.ibm.ftt.api.samples.PopupMenu/group1”
id=“com.ibm.ftt.api.samples.removebuilderaction”/>
</objectContribution>

Submitting JCL and waiting for output


This sample demonstrates how to submit JCL and wait for the output.

Sample scenario
To submit JCL and wait for the output, select a JCL file from the z/OS Projects view and then select the
API Sample Actions > Submit and Wait action.

Remote System Explorer API Software Developer Toolkit (RSE API SDK)
IBM RSE API SDK overview
IBM Remote System Explorer API (RSE API) SDK is an extension from IBM Remote System Explorer API.
Same as RSE API, RSE API SDK allows clients to work with various components on the z/OS host system,
such as MVS data sets, z/OS UNIX files and commands, and JES jobs.
RSE API SDK provides easy-to-call methods while specifying the parameters that are required by the RSE
API itself. Therefore, Java clients can call the REST APIs without worrying about the backbone structure
of a request call and the type of response to accept. Use RSE API SDK in your Java project by importing

Reference 71
the IBM RSE API SDK Toolkit that contains the library of JAR files required to support the RSE API SDK
Toolkit APIs. For more information, see “Importing IBM RSE API SDK Toolkit” on page 72.
RSE API SDK also provides default code templates for you to call upon during development to easily
access its services. For example, the code templates that are provided for logging in to z/OS, logging out
of z/OS, and listing z/OS UNIX System Services files. For more information, see “Accessing IBM RSE API
SDK code templates” on page 72.

Importing IBM RSE API SDK Toolkit


To use the services of IBM Remote System Explorer API (RSE API) SDK in a Java project, import IBM RSE
API SDK Toolkit into the project.
1. Right-click the Java project, and then click one of the following menus:
• Click Build Path > Add Libraries, and then skip to Step “3” on page 72.
• Click Properties > Open Properties Dialog.
2. In the Properties window, click Java Build Path from the left pane, click Classpath on the Libraries
tab, and then click Add Library on the right pane.
3. In the Add Library window, complete the following steps to import the RSE API SDK Toolkit into the
Java project:
a) Click IBM RSE API SDK Toolkit Library, and then click Next.
b) Select the latest version, and then click Finish.
In the Package Explorer view, under the Java project, the library of IBM RSEAPI SDK Toolkit [version] is
added.

Accessing IBM RSE API SDK code templates


You can call upon the provided code templates during development to easily access the services of IBM
RSE API SDK.
Code templates are provided for logging in to z/OS, logging out of z/OS, listing z/OS UNIX System Services
files, and more. The code templates are only available when RSE API SDK is in the Classpath of the Java
project, and they are provided in the Java editor.
1. Click in the Eclipse code view, and then press Control+Space.

2. Press Control+Space until you get RSEAPI SDK Proposals.

72 Developer for z/OS: Reference


3. Select a template directly, or type keywords to search for the template.

The template is inserted into the editor:

Language Reference Documents


XL C/C++ for AIX® V13.1.3 Language Reference
XL C/C++ for z/OS V2.2 Language Reference
CICS® Transaction Server for z/OS 6.1
Db2® for z/OS SQL Reference Version 10
Enterprise COBOL for z/OS 6.4.0
Enterprise PL/I for z/OS 6.1
High Level Assembler for z/OS
High Level Assembler z Architecture Principles of Operation
IMS Application Programming API Version 14
Related information
Software Product Compatibility Reports

Reference 73
74 Developer for z/OS: Reference
Documentation notices
© International Business Machines Corporation 1992, 2024.

This information was developed for products and services offered in the US. This material might be
available from IBM in other languages. However, you may be required to own a copy of the product or
product version in that language in order to access it.
IBM may not offer the products, services, or features discussed in this document in other countries.
Consult your local IBM representative for information on the products and services currently available in
your area. Any reference to an IBM product, program, or service is not intended to state or imply that
only that IBM product, program, or service may be used. Any functionally equivalent product, program, or
service that does not infringe any IBM intellectual property right may be used instead. However, it is the
user's responsibility to evaluate and verify the operation of any non-IBM product, program, or service.
IBM may have patents or pending patent applications covering subject matter described in this
document. The furnishing of this document does not grant you any license to these patents. You can
send license inquiries, in writing, to ipemail@us.ibm.com.
INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS PUBLICATION "AS IS"
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
PARTICULAR PURPOSE. Some jurisdictions do not allow disclaimer of express or implied warranties in
certain transactions, therefore, this statement may not apply to you.
This information could include technical inaccuracies or typographical errors. Changes are periodically
made to the information herein; these changes will be incorporated in new editions of the publication.
IBM may make improvements and/or changes in the product(s) and/or the program(s) described in this
publication at any time without notice.
Any references in this information to non-IBM websites are provided for convenience only and do not in
any manner serve as an endorsement of those websites. The materials at those websites are not part of
the materials for this IBM product and use of those websites is at your own risk.
IBM may use or distribute any of the information you provide in any way it believes appropriate without
incurring any obligation to you.
Licensees of this program who wish to have information about it for the purpose of enabling: (i)
the exchange of information between independently created programs and other programs (including
this one) and (ii) the mutual use of the information which has been exchanged, should contact
ipemail@us.ibm.com.
Such information may be available, subject to appropriate terms and conditions, including in some cases,
payment of a fee.
The licensed program described in this document and all licensed material available for it are provided by
IBM under terms of the IBM Customer Agreement, IBM International Program License Agreement or any
equivalent agreement between us.
Any performance data and client examples cited are presented for illustrative purposes only. Actual
performance results may vary depending on specific configurations and operating conditions.
Information concerning non-IBM products was obtained from the suppliers of those products, their
published announcements or other publicly available sources. IBM has not tested those products and
cannot confirm the accuracy of performance, compatibility or any other claims related to non-IBM
products. Questions on the capabilities of non-IBM products should be addressed to the suppliers of
those products.
Statements regarding IBM's future direction or intent are subject to change or withdrawal without notice,
and represent goals and objectives only. Such statements should not be relied upon when making
purchasing decisions.

© Copyright IBM Corp. 1992, 2024 75


This information contains examples of data and reports used in daily business operations. To illustrate
them as completely as possible, the examples include the names of individuals, companies, brands, and
products. All of these names are fictitious and any similarity to the names and addresses used by actual
people or business enterprises is entirely coincidental.
COPYRIGHT LICENSE:
This information contains sample application programs in source language, which illustrate programming
techniques on various operating platforms. You may copy, modify, and distribute these sample programs
in any form without payment to IBM, for the purposes of developing, using, marketing or distributing
application programs conforming to the application programming interface for the operating platform
for which the sample programs are written. These examples have not been thoroughly tested under
all conditions. IBM, therefore, cannot guarantee or imply reliability, serviceability, or function of these
programs. The sample programs are provided "AS IS", without warranty of any kind. IBM shall not be
liable for any damages arising out of your use of the sample programs.
Each copy or any portion of these sample programs or any derivative work must include a copyright notice
as follows:

© (your company name) (year).


Portions of this code are derived from IBM Corp. Sample Programs.
© International Business Machines Corporation _enter the year or years_.

Trademarks
IBM, the IBM logo, and ibm.com are trademarks or registered trademarks of International Business
Machines Corporation, registered in many jurisdictions worldwide. Other product and service names
might be trademarks of IBM or other companies. A current list of IBM trademarks is available at
"Copyright and trademark information" at www.ibm.com/legal/copytrade.shtml.

Terms and conditions for product documentation


Permissions for the use of these publications are granted subject to the following terms and conditions.

Applicability
These terms and conditions are in addition to any terms of use for the IBM website.

Personal use
You may reproduce these publications for your personal, noncommercial use provided that all proprietary
notices are preserved. You may not distribute, display or make derivative work of these publications, or
any portion thereof, without the express consent of IBM.

Commercial use
You may reproduce, distribute and display these publications solely within your enterprise provided
that all proprietary notices are preserved. You may not make derivative works of these publications, or
reproduce, distribute or display these publications or any portion thereof outside your enterprise, without
the express consent of IBM.

Rights
Except as expressly granted in this permission, no other permissions, licenses or rights are granted, either
express or implied, to the publications or any information, data, software or other intellectual property
contained therein.

76 Developer for z/OS: Reference


IBM reserves the right to withdraw the permissions granted herein whenever, in its discretion, the use
of the publications is detrimental to its interest or, as determined by IBM, the above instructions are not
being properly followed.
You may not download, export or re-export this information except in full compliance with all applicable
laws and regulations, including all United States export laws and regulations.
IBM MAKES NO GUARANTEE ABOUT THE CONTENT OF THESE PUBLICATIONS. THE PUBLICATIONS
ARE PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,
AND FITNESS FOR A PARTICULAR PURPOSE.

Documentation notices 77
78 Developer for z/OS: Reference
Security considerations
This topic highlights some of the security limitations that you might encounter with this application. To
help ensure the security of your installation, customize your security settings and set up user access
controls.

Enabling security during the installation process


Security configuration for Developer for z/OS is addressed in Security definitions. More details on all
security aspects can be found in Security considerations.
Security considerations for Developer for z/OS:
• Installing Developer for z/OS results in a basic configuration with default settings for a basic, secure
setup. Extra configuration tasks, such as configuring SSL, allow for tighter controls. This information is
covered in detail in Security considerations.
Note: Security is not fully enabled during the installation process and must be enabled during
customization after installation is complete. The customization of some security-related aspects must
be completed for the product to work and for certain security features to be enabled. This limitation
applies to silent installations.
• Security for Developer for z/OS on the host is configured through a combination of Developer for z/OS
configuration files and RACF® commands (or other similar security products).
• Developer for z/OS does not provide a login option when the Developer for z/OS host is used as an LDAP
client that accesses a customer-specific LDAP server to get group membership information that is used
to enforce wanted client behavior. LDAP logon information can be provided in a configuration file when
the Developer for z/OS host is used as an LDAP client that accesses public certificate revocation lists
(CRLs).
• Security for Developer for z/OS database authentication is enabled through RACF commands.
• For information about setting up SSL and installing a custom certificate, see these topics in the IBM
Explorer for z/OS documentation: (Optional) ssl.properties, the RSE encrypted communication, RSE -
ssl.properties, and Setting up encrypted communication and X.509 authentication.
• For information about enabling security between the client and server or web client and server, see
Connection flow.
• To configure the security settings of other applications that communicate with Developer for z/OS (Db2
Connect, Debug Tool, Fault Analyzer, File Manager), use the security configuration options available in
those products.
• To verify that you correctly configured the security settings, see Verify the security settings.
• More information:
– With the host connection in Enterprise Service Tools, you can set up a terminal session with a remote
z/OS system. You can configure the session to use SSL, client authentication, and host authentication.
You can use the IBM Key Management tool iKeyman to create a key database file, to create or request
certificates, and to import and export certificates.
Note: Developer for z/OS also uses REXEC, or the more secure SSH, to compile UNIX System Services
projects. For more information, see z/OS UNIX subprojects.

Enabling secure communication between multiple applications


For integrated products, Developer for z/OS provides security for the communications between the
products through the Developer for z/OS communication configuration by using Developer for z/OS tools.
The communication is host only, so there is no encryption.

© Copyright IBM Corp. 1992, 2024 79


To handle user access controls between products in Developer for z/OS, the receiving application (for
example, JMON) requires authentication, which is done by the calling application (RSE) on the user’s
behalf. Where possible (for example, JMON or CARMA), Developer for z/OS binds to the loopback stack
only, which can be reached only from the same system.
For single-sign on, the user authenticates with RSE. RSE then does authentications on the user’s behalf
for other servers. While the user stays within Developer for z/OS, it all looks like one server, but this
situation is not true for other servers. Users must manually authenticate for other servers outside of
Developer for z/OS.

Ports, protocols, and services


Developer for z/OS internal processes, tasks, or services do not require a fixed user ID. You can create
your own user ID for these processes, tasks, or services, and associate the user ID with them by using
RACF commands. For more information about what ports, protocols, and services Developer for z/OS
uses, see Planning and TCP/IP considerations.
Before you can connect to a remote system from the Developer for z/OS client, you must define
a connection for the remote system and specify connection properties. For more information about
connecting to a remote system and the ports that are used for a connection, see Creating a connection to
a z/OS system.

Customizing your security settings


Customizing your security settings is covered in Security considerations. For more information about
setting and changing passwords, and client certificate authentication, see these topics:
• Connecting to a remote system
• Changing your password
• Creating a connection by using client certificate authentication
• Setting preferences for client certificate authentication
Note: Developer for z/OS uses generated PassTickets and does not store passwords on the host. The
Remote Connection Emulator (RCE) stores SSL-related passwords in the Eclipse Secure Storage. For more
information, see Secure storage in the Eclipse documentation. Clients mask password fields with ***, and
a password that is provided by a client during logon is always transmitted in a masked format, even for
SSL encrypted communication.
To enable multiple levels of security, and determine the implications of each, see the various chapters
about security in the host configuration documentation. Each chapter addresses a specific aspect of
security configuration.
Developer for z/OS relies on the options that are offered by TCP/IP to set up notifications of security
breaches or attempts.
Note: Information about login attempts is stored in the Developer for z/OS server logs, and in various
other places (for example, server log, user logs, audit log, syslog).

Multi-Factor Authentication
Developer for z/OS relies on IBM Explorer for z/OS for multi-factor authentication (MFA) support. For
information about configuring MFA in IBM Explorer for z/OS, see Using Multi-Factor Authentication.

Setting up user roles and access


RACF commands are used for the following purposes:
• Create and delete users and set their access levels.
• Create groups and assign them privileges.
• Establish password rules for users (such as no reuse, minimum length, or character requirements).

80 Developer for z/OS: Reference


• Setup superuser IDs or IDs with special security privileges.
For more information about RACF, see the Security Server RACF Security Administrator's Guide,
SA23-2289.

Privacy policy considerations


This software offering does not use cookies or other technologies to collect personally identifiable
information.

Security considerations 81
82 Developer for z/OS: Reference
IBM®

Product Number: 5755-A05


5724-T07

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy