eTrust Directory Developer Guide 8.1
eTrust Directory Developer Guide 8.1
Developer Guide
r8.1
Second Edition
This documentation (the “Documentation”) and related computer software program (the “Software”) (hereinafter
collectively referred to as the “Product”) is for the end user’s informational purposes only and is subject to change
or withdrawal by CA at any time.
This Product may not be copied, transferred, reproduced, disclosed, modified or duplicated, in whole or in part,
without the prior written consent of CA. This Product is proprietary information of CA and protected by the
copyright laws of the United States and international treaties.
Notwithstanding the foregoing, licensed users may print a reasonable number of copies of the Documentation for
their own internal use, and may make one copy of the Software as reasonably required for back-up and disaster
recovery purposes, provided that all CA copyright notices and legends are affixed to each reproduced copy. Only
authorized employees, consultants, or agents of the user who are bound by the provisions of the license for the
Software are permitted to have access to such copies.
The right to print copies of the Documentation and to make a copy of the Software is limited to the period during
which the license for the Product remains in full force and effect. Should the license terminate for any reason, it
shall be the user’s responsibility to certify in writing to CA that all copies and partial copies of the Product have
been returned to CA or destroyed.
EXCEPT AS OTHERWISE STATED IN THE APPLICABLE LICENSE AGREEMENT, TO THE EXTENT PERMITTED BY
APPLICABLE LAW, CA PROVIDES THIS PRODUCT “AS IS” WITHOUT WARRANTY OF ANY KIND, INCLUDING
WITHOUT LIMITATION, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
OR NONINFRINGEMENT. IN NO EVENT WILL CA BE LIABLE TO THE END USER OR ANY THIRD PARTY FOR ANY
LOSS OR DAMAGE, DIRECT OR INDIRECT, FROM THE USE OF THIS PRODUCT, INCLUDING WITHOUT LIMITATION,
LOST PROFITS, BUSINESS INTERRUPTION, GOODWILL, OR LOST DATA, EVEN IF CA IS EXPRESSLY ADVISED OF
SUCH LOSS OR DAMAGE.
The use of this Product and any product referenced in the Documentation is governed by the end user’s applicable
license agreement.
This Product is provided with “Restricted Rights.” Use, duplication or disclosure by the United States Government
is subject to the restrictions set forth in FAR Sections 12.212, 52.227-14, and 52.227-19(c)(1) - (2) and DFARS
Section 252.227-7013(c)(1)(ii), as applicable, or their successors.
All trademarks, trade names, service marks, and logos referenced herein belong to their respective companies.
Chapter 1: Introduction 1
Documentation ..................................................................................................................... 1
Formatting Conventions ......................................................................................................... 3
CA Product References........................................................................................................... 3
Contents iii
Chapter 1: Introduction
This guide describes how to extend some components of eTrust Directory.
eTrust Directory offers a number of APIs and other extension mechanisms for
programmers who want to customize eTrust Directory applications and
functions for their specific needs.
Documentation
eTrust Directory comes with documentation to help you get the most out of it.
Use this section to find out which documents are designed to help you in which
circumstances.
Release Information
Readme
Release Notes
The Release Notes list the issues that have been fixed in this release, with
the associated STAR or LabTrack numbers. Use the Release Notes to track
when the issues you are interested in are fixed.
The eTrust Directory Release Summary briefly describes new features and
enhancement sin this release. Use this guide to find out what's new. You
can then find out more in the eTrust Directory Administrator Guide.
Introduction 1
Documentation
PDF Guides
Administrator Guide
Reference Guide
The eTrust Directory Reference Guide is a PDF guide that includes lists of
commands, settings, files, and so on. This guide is useful if you already
understand a feature and just need to be reminded.
Getting Started
The eTrust Directory Getting Started is a PDF guide that includes a brief
description of how to install eTrust Directory, and some short tutorials on
how to use some of the components. This guide is useful for getting to
know eTrust Directory.
User Guide
The eTrust Directory User Guide gives instructions for implementing some
of the features described in the eTrust Directory Administrator Guide.
Developer Guide
Online Help
The JXplorer online help describes how to use JXplorer. Use the online help
when you want to know how to do a task. Use the eTrust Directory
Administrator Guide to find out how JXplorer works.
The JXweb online help describes how to use JXweb. Use the online help
when you want to know how to do a task. Use the eTrust Directory
Administrator Guide to find out how JXweb works.
2 Developer Guide
Formatting Conventions
Formatting Conventions
In this guide, commands are shown in a different font from the main text, as
in this example:
get dynamic-group;
If a command includes a variable that you must replace, that variable appears
in italic text. In this example, you must replace the text assoc-number with
the actual association number:
If you must enter only one of a list of options, the options are shown
separated by the pipe character |. In this example, you should choose either
true or false:
CA Product References
This document references the following Computer Associates International,
Inc. (CA) products:
Ingres
Introduction 3
Chapter 2: Customizing JXplorer
This section contains the following topics:
About JXplorer
JXplorer is an open source Java application that allows you to browse and
search any LDAP directory.
It displays the structure of the directory data as a tree view in the left panel,
and the data of any particular entry in the directory in the right hand pane.
JXplorer has advanced security integration and support for the more difficult
and obscure parts of the LDAP and DSML protocols.
Customizing JXplorer 5
About JXplorer
JXplorer has been tested and run on Windows, Solaris, Linux, OS390, and
Macintosh OSX.
Because JXplorer is a Java client, it can also be run on any platform that
supports Java. This is up to developers to test for themselves.
JXplorer uses Java 1.4.2. To check what version you are running, go to a
command prompt and type:
java -version
Supported Specifications
JXplorer also supports the DSML 2.0 specification: Directory Services Markup
Language v2.0.
You do not have to customize JXplorer if you do not want to. JXplorer already
works with any LDAP directory.
You can already use JXplorer to modify the structure of your directory with the
tree view (cut/copy/paste/delete of entries and sub-trees), and you can edit
individual entry attribute values using the table editor.
6 Developer Guide
Customize Tree Icons
The icons displayed in the JXplorer tree are stored in the icons sub-directory.
The browser reads the icons used in the directory display tree from the /icons
subdirectory of the JXplorer home directory. The icons are 16-pixel-square
images in the form:
object_class_name.gif
Customizing JXplorer 7
Customize Tree Icons
To make sure the browser recognizes the new icons, you must restart it.
2. Give the icon the same name as the naming attribute you want the icon to
appear next to.
For example, you could create an icon named [Link], which would appear
next to entries that use cn as their naming attribute.
The next time you start JXplorer, the new icon will be used.
The icons are linked with entries using the object class of the entry, or the
LDAP naming attribute in the lowest RDN of the entry.
8 Developer Guide
Create HTML Viewing Templates
[Link]
/templates/person
[Link]
[Link]
/templates/organizationalUnit
[Link]
You can add any number of new HTML templates, including templates for
newly defined object classes by creating (if necessary) the appropriate
subdirectory under the /templates directory and placing the new HTML files in
that subdirectory. After you add new files, you may need to restart the
browser to recognize them.
List of all attribute names and values to be set with a single tag
Customizing JXplorer 9
Create HTML Viewing Templates
HTML Forms
You can also use standard HTML forms; however, you must give each form
element a name value that corresponds to an attribute, for example, title.
JXplorer will display existing values and make updates to the directory when
you click Submit.
There are a number of reasons you might want to change the GUI, including:
Data Specific Display - you may want special icons for some types of data,
or special displays for specific entry types.
10 Developer Guide
Create HTML Viewing Templates
The following example shows JXplorer with custom icons (see page 7) and
corporate-specific graphics. These graphics were incorporated using a simple
extended version (see page 17) of HTML
Customizing JXplorer 11
Customize HTML Forms
The Java HTML component does not support any active scripting. It works with
plain HTML only.
Be careful not to include extra fields containing attributes that don't exist in
the directory. If you do this, and a user attempts to enter data into the field,
the directory will show an 'unknown attribute' error. This is not particularly
serious, but it will confuse your users.
Form elements that have a 'value=""' clause will (where possible) have this
value filled in by the existing entry value. This is not done for non-text
components however.
12 Developer Guide
Customize HTML Forms
<dxtemplate:get-attribute name="description"/>
<dxtemplate:get-all-attributes style="table"/>
Listing all available data in the entry, without needing to explicitly name the
various attributes:
Customizing JXplorer 13
Customize HTML Forms
Sample Templates
The above page for viewing 'person' data was saved under /templates/person/
. Look at the existing subdirectories under templates to see some examples.
If you have a template that you want to be available for all entries, regardless
of object class, place it at the base 'templates' subdirectory level, and it will
always appear as an option.
Anything with a 'name' tag is parsed as an attribute. This means that form
submission buttons and so on will be treated as attributes if they are given
names.
To avoid this, don't give your Submit buttons specific names, unless you have
a special reason to do this.
While you shouldn't give buttons a 'name' clause, you can certainly give them
a 'value' clause, to get the button to display something other than 'submit'.
The form elements must be named after the attribute they are to modify. For
example, to modify a description attribute, you could use the following form
HTML
This gives a normal text input field that modifies the description attribute
when the user clicks the Submit button.
14 Developer Guide
Customize HTML Forms
Any form component can be used, although the data returned may not always
be appropriate for a particular attribute type.
The organizationUnit example HTML file shows how to use the description field
above as well as a pull-down list:
You must use the normal HTML form syntax, including a submission URL.
However, the form does not get submitted to that URL - JXplorer intercepts
the submission event and parses the data itself.
Customizing JXplorer 15
Customize HTML Forms
The following code is the script used to generate the directory-enabled HTML
form shown above. It is a complete HTML page, including both an attribute tag
and a form.
<html>
<head><title>First Template</title></head>
<body bgcolor="#DDFFDD">
<h1>Organisational Unit Data Set</h1>
<h2><dxtemplate:get-attribute name="ou" style="list"/></h2>
<p>
<h1> Please Update Entry </h1>
<table width=200 border=3 bgcolor="#DDDDFF">
<tr>
<td>
<form name="temp" action="[Link] method=get>
<h3>Description</h3>
<input type="text" name="description" size=20 value="">
<h3>Business Category</h3>
<select name="businessCategory">
<option value="Quality Assurance">Quality Assurance
<option value="Documentation">Documentation
<option value="Marketing">Marketing
<option value="Software Development">Software
Development</select>
<p>
<input type="submit">
</form>
</td>
</tr>
</table>
</body>
</html>
16 Developer Guide
Add Custom HTML Pages
Within these HTML files, an 'extended' HTML tag is used to allow the display of
entry data. Within the HTML code, the following tag may be used:
[Attribute name] is the exact name of the attribute to display values of. The
optional
[display type] is one of either 'list', 'table', or 'plain', which sets how multiple
values will be displayed. To show a list of all available attributes. To display all
the attributes and their values a similar tag is used:
You can insert hyperlinks in your HTML pages. For example, you could link to
extended help, or further resources.
However, that the Java HTML component does not support Javascript or VB
script, and is not as robust as a commercial web browser.
Customizing JXplorer 17
Internationalize JXplorer
Internationalize JXplorer
It is easy to add new languages to JXplorer. You can choose what parts of
JXplorer you internationalize.
18 Developer Guide
Internationalize JXplorer
The online help system for JXplorer uses the JavaHelp 1.1.3 format. The online
help is supplied as a helpset.
3. Allow JXplorer to see the translated helpset. You can do either of the
following:
Make a ZIP file of the translated helpset, then place it in the /plugins
directory.
You can internationalize the Welcome page that appears when JXplorer starts.
Make sure that these new files are written in UTF8, Unicode, or the default
local encoding.
Customizing JXplorer 19
Internationalize JXplorer
JXplorer is written using English strings. It then uses resource files to map the
English strings to the translated strings. These resource files are located in the
/language subdirectory.
Each resource file is made up of lines of words and phrases. Each line has a
word or phrase on the left, an equals sign, and the translation on the right. For
example, a map file for German might contain the following two lines:
Help = Hilfe
Welcome to JXplorer = Wilkommen du JXplorer
Any symbol on the left of the equals sign (including another equals sign) may
be escaped with a backslash, but for most strings this is not necessary.
20 Developer Guide
Internationalize JXplorer
3. Run JXplorer
If you are on an English platform and you made changes to the right side
translations in the file [Link], you will see those changes the next
time JXplorer runs.
For more information, see the Sun documentation on Java resource bundles
([Link]
File Formats
Many products have very restrictive rules about what file formats they will
accept non-English text in. JXplorer prefers files to use UTF-8 or 16 bit
unicode, but local character encodings (such as Japanese 'Shift-JIS' or Chinese
'Big-5') will usually work as well.
If your file might be used outside your locale, or if you need to include multiple
languages, you should use Unicode (either UTF-8 or 16 bit). This is because
locale-specific formats will only work on computers that are set to that locale.
That is, 'Shift-JIS' only works on computers that are set to the Japanese
region setting.
Occasionally you may see text of the form '...\u30AF\u309A...'. This is Java-
escaped Unicode format. You can use this format, but most word processors
will not save to this format, and it is not recommended.
Fonts
While many fonts may exist on a system, Java does not automatically pick
them up.
If you need to install new fonts, use this Sun document for instructions:
[Link]
([Link]
Customizing JXplorer 21
Supply Customized Files
If you are writing your own Java plug-in, and you need to use external data
files, you can access them using normal java zip handling methods. In addition
a utility class '/com/cai/od/cbutil/[Link]' is available (see the API
documentation) and can be imported by your plug-in.
JXplorer automatically scans the plug-ins directory for .zip and .jar files when
JXplorer is started. It reads the indexes of the zip files, and afterwards treats
any HTML templates, icons, and plug-ins in a ZIP file as being part of the
normal class path.
If you have customized only a small number of files, you can send your end
users the files directly, with instructions or a batch file to place them in the
correct directory.
JXplorer automatically scans the plugins directory for .zip and .jar files when
JXplorer is started. It reads the indexes of the zip files, and afterwards treats
any HTML templates, icons, and plugins in a ZIP file as being part of the
normal class path.
22 Developer Guide
Supply Customized Files
If you use a ZIP file to supply the changed files to your users, the ZIP file must
have the same structure as the external directories.
That is, templates must be in the ZIP file under a /templates directory, icons
under a /icons directory, and so on. For example:
Customizing JXplorer 23
Chapter 3: Extending JXplorer
JXplorer can be extended to load small Java programs, similar to Web applets,
based on an entry's object class.
eTrust Directory can be used to store many types of non-string data types,
including graphics formats, audio formats, cryptography formats, and
application-specific data types.
The general-purpose JXplorer cannot be used to modify binary data, but you
can create your own binary editor for a particular data type.
The browser also supports custom binary editors (written in Java using a
provided minimal API) that dynamically loads at run time. You key such binary
editor extensions to a particular object class. This would let you write, for
example, an editor for a custom certificate object class.
These editors will only work for binary value data attributes and no other data
types.
Standard editors are provided for X.509 certificates, and a number of standard
image and audio formats.
Extending JXplorer 25
Pluggable Attribute Editors
To create a pluggable attribute editor takes time, and you may not need to do
it. JXplorer comes with two binary editors, or you can use a Windows editor.
However, if you do this, your application may not be able to run on a non-
Windows platform. A possible path out of this is to check the operating system
in the pluggable attribute editor, and issue an appropriate native command
depending on the OS.
To modify binary data, you can use the default binary editor to save the data
to disk, use your normal tool to manipulate the data, and load it back into the
default binary editor.
The binary editor is very limited. JXplorer lets you edit the attributes in the
odMultimedia schema, which lets you save and launch files of the following
formats:
.avi odMovieAVI
.doc odDocumentDOC
.mid odMusicMID
.wav odSoundWAV
.xls odSpreadSheetXLS
26 Developer Guide
Pluggable Attribute Editors
To use the attribute types in odMultimedia in the Table Editor, add the
odMultimedia object class to an entry.
You can then add binary files to that entry, and launch those files from the
Table Editor view of the entry.
For more information, see Launch Binary Files in the JXplorer online help.
You don't need to write a pluggable editor to use different languages with
JXplorer.
JXplorer has been successfully tested with European and Asian languages on
correctly installed localized platforms.
Extending JXplorer 27
Pluggable Attribute Editors
Writing a pluggable editor simply involves writing a Java class that does one of
the following:
The class must be given the name of the attribute type, in lower case, with the
suffix editor.
For example, if you create an editor for the attribute ocspRSAPrivateKey, you
must name the final class ocsprsaprivatekeyeditor.
Extending DefaultBinaryEditor
28 Developer Guide
Pluggable Attribute Editors
/**
* All pluggable editors must be in this package
*/
package [Link];
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
/**
* Password Editor.
* Allows user to enter a masked binary password. The dialog contains two
* password fields. The first is for displaying the password that is stored in
* the directory. The second is to confirm that the first has been entered
* correctly. To change the password the user needs to click on the change
* button. Both password fields are then cleared (we don't want the user to edit
* the encoded password). When the user clicks the save button a check is done.
* If the user hasn't changed the password, it gets stored. Otherwise if the user
* did change it, the two password fields must match before it is saved (a
* warning message is displayed if they don't match).
*
Extending JXplorer 29
Pluggable Attribute Editors
*/
public class userpasswordeditor extends JDialog
implements abstractbinaryeditor
{
protected JPasswordField oldPwd, newPwd;
protected CBButton btnOK, btnCancel, btnHelp;
protected EditableBinary editMe = null;
protected CBPanel display;
protected JLabel oldLabel, newLabel;
protected boolean firstClick = true;
/**
* Constructor - sets up the gui.
*/
setModal(true);
setTitle([Link]("User Password"));
30 Developer Guide
Pluggable Attribute Editors
{
public void actionPerformed(ActionEvent e)
{
load();
}
});
[Link]();
[Link](oldLabel);
[Link](oldPwd);
[Link](new JLabel(" "));
[Link](newLabel);
[Link](newPwd);
[Link]();
[Link](JComponent.WHEN_IN_FOCUSED_WINDOW).put([Link]
("ESCAPE"), "escape");
[Link]().put("enter", new MyAction([Link]));
[Link]().put("escape", new MyAction([Link]));
setSize(300, 170);
[Link](this, owner); //Centres the window.
setTitle([Link]("User Password Data"));
getContentPane().add(display);
}
Extending JXplorer 31
Pluggable Attribute Editors
/**
* Apparently it is better to use key bindings rather than adding a
* KeyListener... "for reacting in a special way to particular keys, you
* usually should use key bindings instead of a key listener".
* This class lets the user set the key as an int. If a key is pressed and
* it matches the assigned int, a check is done for if it is an escape or
* enter key.
* (27 or 10). If escape, the quit method is called. If enter, the apply
* method is called.
* Bug 4646.
*/
private class MyAction extends CBAction
{
/**
* Calls super constructor.
* @param key
*/
public MyAction(int key)
{
super(key);
}
/**
* quit is called if the Esc key pressed,
* load is called if Enter key is pressed.
* @param e never used.
*/
public void actionPerformed(ActionEvent e)
{
if (getKey() == ESCAPE)
quit();
else if (getKey() == ENTER)
load();
}
}
32 Developer Guide
Pluggable Attribute Editors
/**
* This is the abstractbinaryeditor interface method which is
* called when the user wants to edit the password
*/
public void setValue(editablebinary editMe)
{
[Link] = editMe;
[Link](stringEncode([Link]()));
}
/**
* converts between text and a byte array
*/
protected byte[] stringDecode(String s)
{
if (s == null)
return (new byte[0]);
else
try
{
return [Link]("UTF-8");
}
catch (UnsupportedEncodingException e)
{
[Link]("Unexpected error encoding password " + e);
[Link]();
return new byte[0];
}
}
/**
* converts between a byte array and text
*/
protected String stringEncode(byte[] b)
{
if (b == null || [Link] == 0)
return new String();
else
try
{
return new String(b, "UTF-8");
}
catch (UnsupportedEncodingException e)
{
[Link]("Unexpected error decoding password " + e);
[Link]();
return new String(b);
}
}
Extending JXplorer 33
Pluggable Attribute Editors
/**
* sets the value of the editablebinary object with whatever the
* user has entered into the password text field.
*/
protected void load()
{
if (passwordConfirm())
{
[Link](stringDecode(new String([Link]())));
quit();
}
}
/**
* Does some checks on the password.
* @return True - if the two password fields match.
* False - if the new password field is empty (an error message is
* displayed).
* False - if the password fields don't match (an error message is
* displayed).
*/
protected boolean passwordConfirm()
{
if (new String([Link]()).equals(new
String([Link]()))) //if the two password fields match carry on
saving the password.
{
return true;
}
else if (new String([Link]()).equals("")) //if the new
password field is empty display error message.
{
[Link](display, [Link]("Empty password
field, please fill in both fields"), [Link]("Warning message"),
JOptionPane.INFORMATION_MESSAGE);
[Link]("");
return false;
}
else //if the password fields don't match display error message.
{
[Link](display, [Link]("Password typed
incorrectly, please try again"), [Link]("Warning message"),
JOptionPane.INFORMATION_MESSAGE);
[Link]("");
return false;
}
}
34 Developer Guide
Pluggable Entry Editors
/**
* Shuts down the gui.
*/
protected void quit()
{
setVisible(false);
dispose();
}
}
There may be no need to write a pluggable editor. If all you need to do is give
a custom look-and-feel to your data, you may find it easier to use the HTML
templates and forms. But, if you need to do any complex client-side
processing such as wizards or form validation, it may be useful to write your
own editors.
The name of the editor must be the same as the object class of the type of
entry it is to be used for. So if the editor is to be used for 'people', the name of
the class is simply '[Link]'.
The classes made need to be packaged into the [Link] file in the
directory C:\Program Files\CA\eTrust Directory\jxplorer\jars and they need to
be added into the [Link] file with the correct path:
com\ca\directory\jxplorer\viewer.
Extending JXplorer 35
Pluggable Entry Editors
The Pluggable Editor interface defines a number of methods that let the
Pluggable Editor take control of the entirety of JXplorer. Most of the time you
will only want to use a handful of these. For more information, see the
JXplorer API Reference (../jxplorer/api/[Link]) that was installed with
JXplorer.
36 Developer Guide
Pluggable Entry Editors
Extending BasicPluggableEditor
package [Link];
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link];
import [Link];
import [Link];
/**
* The Constructor sets up the JEditorPane GUI
*/
public person()
{
basicDisplay = new JEditorPane("text/plain","");
scrollPane = new JScrollPane(basicDisplay);
}
/**
* This method is called by JXplorer when a new 'person' entry
* needs to be displayed.
*/
public void displayEntry(DXEntry entry, DataSource ds)
{
[Link]([Link]());
}
/**
* This method returns a GUI component to JXplorer to display
* in the right hand pane.
*/
public JComponent getDisplayComponent()
{
return scrollPane;
}
}
Extending JXplorer 37
Pluggable Entry Editors
This is all that is required for your own pluggable editor - a GUI and some
code to handle the 'displayEntry(..)' method. Check the API for the methods of
the DXEntry object - it is an extension of the standard JNDI 'Attributes' object
and supports all its methods, as well as a large number of utility extension
methods (such as the [Link]() method).
When your user has registered changes in your custom pluggable editor GUI,
you'll need to submit them to the directory. The core pluggable editor method
is public void displayEntry(DXEntry entry, DataSource ds). The entry
parameter is the data to display, while the DataSource parameter is a link to a
data source (usually a directory) that you can use to submit changes. The
simplest call in DataSource is modifyEntry(..), which takes the original entry
and the new entry, and makes the necessary calls to the directory to
efficiently convert the old entry to its new state.
There are a large number of other data related operations you might want to
make with the directory, ranging from reading more data, searching,
modifying the directory tree structure, and reading schema details.
38 Developer Guide
Plug-ins with Data Listeners
Problems arise when you need to write code that is conditional on the results
of a directory operation. For example, you may want to create a particular
entry if it doesn't exist, or modify it if it does. The way to do this in a
pluggable entry editor is to either use the 'DataListener' interface (for simple
operations), or to pass an extended 'DataQuery' object (for more complex
tasks).
This section shows you how to use the simpler DataListener interface, and the
Plug-ins with Threads (see page 43) section how to use the general purpose
'DataQuery' method to run arbitrary code.
Extending JXplorer 39
Plug-ins with Data Listeners
The DataListener only has one method returning one object - the original
DataQuery! However in this method you are guaranteed that the DataQuery
has finished, and is ready for reading. So within the DataListener method you
can use all the DataQuery methods such as hasException() or getResult().
This may seem a bit of effort to go to, but is in fact fairly straightforward.
40 Developer Guide
Plug-ins with Data Listeners
}
else
{
[Link]("read entry " + [Link]());
}
}
});
__ ...
}
...
}
Other DataListeners
Your pluggable editor isn't the only Data Listener. The JXplorer browser tree is
another, and it will respond to any data operations that occur, showing error
messages or changing the tree as appropriate.
Most of the time this is what you want. However, if you'd prefer to keep your
operations private (maybe you're handling your own exceptions, or you're
hiding a sub-level of the directory from the user) you can 'squelch()' the
query, preventing any other listeners from processing the query.
Extending JXplorer 41
Plug-ins with Data Listeners
Sometimes this still isn't enough - you need to make a directory request in
your pluggable editor, and then, depending on the result, you need to make
further requests.
There are a number of ways of doing this. One method is to use the
getBroker() DataQuery method. This gives you raw access to the directory
connection methods.
This method falls down if the initial directory action is non-standard, and may
also be a little clumsy if you have a single unit of work to do, that could be
nicely executed in one place. In this case, the best thing to do may be to
extend the DataQuery class itself, and pass an 'extended DataQuery' to the
DataSource, using DataSource's 'extendedRequest()' method. How to do this
is covered in the Plug-ins with Threads (see page 43) section.
42 Developer Guide
Plug-ins with Threads
This could be done using the previous technique by doing the first query (an
existence check) and then putting the rest of the code in the DataListener,
while using the DataQueries 'getBroker()' method.
Instead, you can bundle all the code up in one place, and use an 'extended
data query'. The method is simply to extend the DataQuery class by
implementing the 'doExtendedRequest()' method, and then pass the resulting
query to the connection thread using the broker's 'extendedQuery()' method.
Extending JXplorer 43
Plug-ins with Threads
The code in the Plug-ins with Data Listeners (see page 39) section, which read
an entry and printed it out, could be rewritten as:
44 Developer Guide
Plug-ins with Threads
Since the DataQuery is being run in the connection thread, it should use the
'unthreaded' broker methods to access the directory.
unthreadedExists
unthreadedReadEntry
unthreadedCopy
unthreadeList
unthreadedModify
unthreadedSearch
unthreadedGetAllOCs
unthreadedGetRecOCs
Extending JXplorer 45
Plug-ins with Threads
3. If it does exist, check that the subtree exists and create it if it doesn't.
46 Developer Guide
Plug-ins with Threads
Extending JXplorer 47
Localize JXplorer Plug-ins
[Link](null, DXEntry[i]);
}
}
boolean checkTree()
{
DXNamingEnumeration list =
[Link]("cn=top,o=CA");
return (list != null && [Link]() == 5);
}
}
...
// Create and run our extended query.
[Link](new ExtendedDataQuery())
...
}
}
This is easily done using a single method call. If your plug-in is extending from
BasicPluggableEditor, the call is:
addLanguageBundle("myBundleName");
If you are implementing the PluggableEditor interface, you can make the
equivalent call using the code:
[Link]("myBundleName", getClass().getClassLoader());
In both these instances, replace the string "myBundleName" with the name of
your particular plug-in's resource bundle.
If your plug-in needed to translate the word 'help' into German for display in
the German locale, you would create a file called myPlugin_de.properties, and
have in it the single line:
help = hilfe
Place the 'myPlugin_de.properties' file in your plugin zip file (at the top level),
and make the call 'addLanguageBundle("myPlugin");' in the constructor of
your plug-in, and a later call to '[Link]("help")' should return the string
"hilfe". You could use this in a label definition: JLabel myLabel = new
JLabel([Link]("help"));
48 Developer Guide
Add Help Files to Plug-ins
addHelpSet("myHelpSet");
If you are implementing the PluggableEditor interface, you can make the
equivalent call using the code:
[Link]("myHelpSet", getClass().getClassLoader());
In both these instances the string "myHelpSet" is replaced with the name of
your particular plug-in's help set.
Extending JXplorer 49
Chapter 4: The DUA Command Set
This section contains the following topics:
For large administration tasks, you can use the DUA to run batch operations
and tests on the DSA.
The commands described here fully implement every aspect of every X.500
service and form the basis for testing DXserver. You can consult the test
scripts released with DXserver for various examples of any given service.
This chapter briefly explains each X.500 service. See the X.500 standards
documentation for full details of the services. The X.500 service commands
covered are:
bind-req
unbind-req
abort-req
read-req
search-req
compare-req
abandon-req
list-req
add-entry-req
mod-entry-req
rem-entry-req
mod-dn-req
When you enter the bind command at the management console, the system
treats it as if it had come from a remote DUA. You can have a command as
simple as an anonymous login using the command:
bind-req;
After you enter the command, the dsa> prompt returns immediately, and a
short time later the BIND CONFIRM message appears. The console interface is
asynchronous (that is, you can enter commands at any time, and the
responses return whenever they complete).
When you enable authentication, you must also supply the user and password
fields as part of the command. For example:
bind-req
user = <countryName “AU”>
<organizationName “Democorp”>
<organizationalUnitName “Services”>
<organizationalUnitName “Networks”>
<commonName “Brendan RANDALL”>
password = “ “
The user field supplies the DN of the user initiating the bind. You cannot have
aliases in the DN (see the X.500 standard). Enter the password as a string.
The DSA checks both the name and password, so you must supply a password
when you supply a name.
52 Developer Guide
Connecting and Disconnecting
DXserver comes with a number of utilities, one of which is the scripting DUA.
The following file initializes the DUA and connects it to the DSA specified by
remote-addr in the bind request.
You can disconnect from the DSA using one of the following methods:
Unbind Request
You can issue an unbind request command at any time. The system discards
any unfinished operations on the association, and closes the connection.
unbind-req;
Abort Request
You can also issue an abort request; this drops all communication
immediately, regardless of what is in progress.
abort-req;
54 Developer Guide
Inquire Services
Inquire Services
The operations used for retrieving or comparing information are:
Read
Compare
List
Search
Abandon
You can use each of the inquire services (read, compare, list, and search) to
resolve aliases (see Aliases (see page 74)), and you can give each a time
limit.
All the examples have string values delimited by double quotes (whether
required or not) to help distinguish between attributes and their values.
Read Service
You can return all or selected information from a single entry using the read
service.
To read an entry:
read-req
entry = <c “AU”><organizationName “Democorp”>;
Entry:
<countryName “AU”>
<organizationName “Democorp”>
Contents:
(telephoneNumber “03 9727 9922”)
(facsimileTelephoneNumber “03 9726-5300”)
(postalAddress “PO Box 383, Mooroolbark”)
(postalCode “3138”)
You can use the attr-only option, the attrs = .... option, or both to return
selective information.
Compare Service
The DSA uses the compare service for password checks, but you can use them
for comparing any provided information with the contents of a directory entry.
compare-req
entry = <c “AU”><organizationName “Democorp”>
<organizationalUnitName “Corporate”>
assertion = telephoneNumber “03 9727 9942”;
When the DSA finds the attribute and value provided by the compare request
in the entry, the compare service returns an assertion TRUE. When it does not
find them, the compare service returns an assertion FALSE.
When the DSA does not find the entry or the attribute, a compare-refused
message is returned. See the test scripts for more examples.
56 Developer Guide
Inquire Services
List Service
You can use the list service to obtain a list of immediate subordinates for an
entry.
list-req
entry = <>;
list-req
entry = <countryName “AU”>
<organizationName “Democorp”>
<organizationalUnitName “Corporate”>;
The list result returns the relative distinguished names of the objects
immediately under the list object.
When the DSA has knowledge references to other DSAs, the list makes these
references visible. For example, when the domain of the DSA is AU/Democorp
and you define a remote DSA US/OpenDirectory, a list at the root returns both
AU and US and a list under US returns OpenDirectory. (See Knowledge
References in the chapter “Distribution and DSP” for more information.)
Search Service
The search service lets you locate entries of interest on a portion of the DIT.
The search (and list) services can return many objects, but if you reach a size
limit or time limit or if you receive an abandon request, you can interrupt the
services. In this case, they may return partial results (the objects they
collected before interruption).
A search is successful when it can find its base object (where to begin the
search). The system ignores invalid aliases or attributes, or other problems
encountered while filtering entries. A search returns no information when none
of the entries matches the given filter.
Simulate a read and retrieve all attributes and values of an entry using search:
search-req
base-object = <countryName “AU”>
<organizationName “Democorp”>;
Simulate a list and retrieve the names of all objects from one level under
Democorp using search:
search-req
base-object = <countryName “AU”>
<organizationName “Democorp”>
one-level-only
no-info-return;
58 Developer Guide
Inquire Services
Search all objects under (and including) Democorp, retrieving all objects that
contain an attribute surname with a value of Smith, and retrieve all
information contained in those entries:
search-req
base-object = <countryName “AU”>
<organizationName “Democorp”>
whole-subtree
filter = { attr = surname value = “Smith” };
Search the local directory tree, retrieving all objects that contain a surname
attribute with a value of Smith and a title attribute with a value of Manager
and a telephoneNumber attribute. You retrieve only the commonName,
surname, and telephoneNumber attributes of the objects matching the search
filter.
search-req
base-object = <>
whole-subtree
filter = { and {attr = surname value = “Smith”,
attr = title substrings [ any “Manager”],
attr = telephoneNumber present}
}
attrs = commonName, surname, telephoneNumber
common-args = { local-scope };
You can turn off the resolution of aliases during a search by setting the dont-
search-aliases flag in the search service.
You can receive selected information for each entry that matches the search
filter using attr-only and attrs = ...
LDAP-only examples
These commands are supported by the LDUA, which is the LDAP version of the
DUA. Because the LDUA uses the LDAP protocol, it has access to LDAP
controls, which permit operations to be modified. For example, the search
command can include server-side sorting and paged results.
Search all objects under Democorp, retrieving all objects with common name
beginning with H, and sort the objects in reverse order by description:
search-req
base-object=<o Democorp>
whole-subtree
filter = { attr = commonName substrings [ initial h ] }
attrs = commonName,description
controls = { server-side-sort description reverse critical };
Search all objects under Democorp, retrieving all objects that contain an
attribute common name beginning with H, and page the results:
These LDUA commands can be used together. The following example searches
all objects under Democorp, retrieves all objects that contain an attribute
common name beginning with H, and sorts and pages the results:
60 Developer Guide
Inquire Services
Abandon Service
You can stop an inquire service in process by using the abandon service.
Abandon stops the request having the specified invoke-id (or the last request
if no invoke-id is given) and returns any partial results up to the time of the
abandon request, for example:
abandon-req
invoke-id-to-abandon = 1234;
Update Services
Services that update the DIT are:
Add
Remove
Modify
Modify-DN
The DSA does not resolve aliases; the system ignores the dont-deref-
aliases common argument.
Size limit is not relevant because no results return; the system ignores the
size-limit common argument.
The remove service must occur at a leaf entry (the entry at the end of a
branch of the DIT).
62 Developer Guide
Update Services
Add Service
You can add entries under any existing entry (or root, if it is a first-level DSA).
The entry you add must obey the name-binding rules in force and the
attributes in the entry must obey the object-class rules of that entry.
To add an entry:
add-entry-req
entry = <countryName “AU”>
<organizationName “Democorp”>
<organizationalUnitName “Sales”>
contents = {
( objectClass organizationalUnit )
( postalAddress “222–268 Maroondah Highway”.
“Mooroolbark"."Victoria” )
( postalCode “3138” )
( telephoneNumber “(03) 9727-8900”.
“(03) 9727-8901” )
( facsimileTelephoneNumber “(03) 9727-3491” )
};
Multivalue attributes let you record more than one value in a single attribute.
The telephoneNumber attribute in the example contains two values.
You can define some attributes with schema as single-valued (for example,
postalCode).
In the next example, a multivalue attribute commonName has the value John
Smith used for naming. The commonName attribute must be present in the
contents of the add request so that you can add the value J SMITH.
add-entry-req
entry = <countryName “AU”>
<organizationName “Democorp”>
<commonName “John Smith”>
contents = {
( objectClass organizationalPerson )
( surname “Smith” )
( commonName “J SMITH” )
};
64 Developer Guide
Update Services
Remove Service
rem-entry-req
entry = <countryName “AU”>
<organizationName “Democorp”>
<organizationalUnitName “Sales”>;
rem-entry-req
entry = <organizationName “OpenDirectory”>;
Modify Service
The modify service lets you add or remove attributes and values.
mod-entry-req
entry = <countryName “AU”>
<organizationName “Democorp”>
<organizationalUnitName “Corporate” >
add-attr {facsimileTelephoneNumber “03-9727-9722” };
To add another phone number (value) for John Smith under organization
Democorp under country AU, while removing one of his common names (the
nondistinguished value—J SMITH):
mod-entry-req
entry = <countryName “AU”>
<organizationName “Democorp”>
<commonName “John Smith”>
rem-values { commonName “J SMITH” },
add-values { telephoneNumber “03 9727 9111” };
An attribute (in an entry) must have at least one value present. Removing the
last value automatically removes the attribute. You cannot remove mandatory
attributes.
When an attribute already exists, you cannot add the same attribute a second
time. You can add additional (multi-) values to an existing attribute. Thus, the
order in which you add or remove entries within one modify service is
important.
66 Developer Guide
Update Services
Modify-DN Service
The modify-DN service lets you rename an entry. Renaming a non-leaf entry
changes the distinguished name of all entries under it.
In the modify-DN service, the system supplies a new RDN along with an option
to delete the old RDN. If you do not delete the old RDN, it becomes part of the
normal attribute (its values are no longer distinguished).
mod-dn-req
entry = <countryName “AU”>
<organizationName “Democorp”>
<organizationalUnitName “R&D” >
new-rdn = <organizationalUnitName “Research & Development”>
delete-old;
You can now move an entry and all of its subordinates to a different place in
the tree, using this option:
new-superior = <DN>
The following example moves the R&D entry and all of its subordinates from
AU,Democorp to under the entry AU, Democorp, Corporate.
mod-dn-req
entry = <countryName “AU”>
<organizationName “Democorp”>
<organizationalUnitName “R&D” >
new-rdn = <organizationalUnitName “Research & Development”>
delete-old
new-superior = <countryName “AU”>
<organizationName “Democorp”>
<organizationalUnitName Corporate>;
You can change the case of a value (for example, Democorp to DEMOCORP)
using the modify-DN service if you set the delete-old option. Although the
matching rules treat the two values as identical, their raw values are different,
which prevents a duplicate value error from occurring.
mod-dn-req
entry = <countryName “AU”>
<organizationName “Democorp”>
new-rdn = <organizationName “DEMOCORP”>
delete-old;
68 Developer Guide
Common Arguments
Common Arguments
The size-limit service control is only applicable to list and search operations. It
indicates the maximum number of objects returned.
search-req
base-object = <countryName “AU”>
...
...
common-args { size-limit = 20 };
When you reach a size limit, the service returns that number of objects and
the qualifier:
Time Limit
The time-limit service control is only applicable to read, compare, list, and
search operations. It indicates the maximum number of seconds that a service
takes for execution.
The time limit has a granularity of one second. However, a time limit of zero
can still result in a successful operation, because the DSA may process the
operation in less than one second.
search-req
base-object = <countryName “AU”>
...
...
common-args { time-limit = 10 };
In some cases, when a time limit expires, partial results may not return. For
example, when a list takes three seconds to return 100 subordinates, then a
time limit of one or two seconds can result in an error with no subordinates
returned:
For more information, see set max-op-time Command in the eTrust Directory
Reference Guide. This command is usually set in the configuration file, and it
can override this service control.
Other Controls
The system provides support for all other X.500 common arguments. These
include service control flags:
prefer-chaining
chaining-prohibited
local-scope
dont-use-copy
dont-deref-aliases
70 Developer Guide
Common Arguments
You can control the amount of entry information returned by read and search
operations by using attr-only or attr-and-vals options.
read-req
entry = <c “AU”><o “Democorp”>
attr-only;
Entry:
<countryName “AU”>
<organizationName “Democorp”>
Contents:
objectClass
organizationName
telephoneNumber
Note: Returning both attributes and values is the default setting for returning
entry information.
You can select which attributes to return. The read service returns an error if it
does not find attributes in the entry.
read-req
entry = <c “AU”><o “Democorp”><ou “Corporate”>
attrs = facsimileTelephoneNumber, telephoneNumber;
Entry:
<countryname “AU”>
<organizationName “Democorp”>
<organizationalUnitName “Corporate”>
Contents:
(facsimileTelephoneNumber “(03) 9727 9722”)
(telephoneNumber “(03) 9727 9942”)
Operational Attributes
In addition to the entry information selection controls, you can possibly receive
extra entry information with the read and search operations. This information
is the operational attributes associated with each entry. Using the all-extra-
attrs or extra-attrs options returns the operational attributes.
read-req
entry = <c “AU”><o “Democorp”>
all-extra-attrs;
The command returns all attributes of the entry, including all operational
attributes, for example:
Entry:
<countryName “AU”>
<organizationName “Democorp”>
Contents:
(objectClass organization)
(organizationName “Democorp”)
(telephoneNumber “(03) 9727 8900”)
(creatorsName
<countryName “AU”>
<organizationName “Democorp”>
<commonName “DSA Administrator”>
)
(createTimestamp 19980712035245Z)
(modifiersName
<countryName “AU”>
<organizationName “Democorp”>
<organizationalUnitName “Services”
<commonName “John Smith”>
)
(modifyTimestamp 19980718062137Z)
(dseType (any)3,2,16)
72 Developer Guide
Common Arguments
read-req
entry = <c “AU”><o “Democorp”><ou “Corporate”>
extra-attrs = modifyTimestamp;
The command returns attributes and values of the entry, plus the requested
operational attributes:
Entry:
<countryname “AU”>
<organizationName “Democorp”>
<organizationalUnitName “Corporate”>
Contents:
(objectClass organizationalUnit)
(organizationalUnitName “Corporate”)
(facsimileTelephoneNumber “(03) 9727 9722”)
(telephoneNumber “(03) 9727 9942”)
(modifyTimestamp 19980718062137Z)
When you enable the op-attrs operational control, operational attributes are
added to an entry automatically when it is created or modified:
Aliases
Some entries at the leaves of the DIT are alias entries, while all other entries
are object entries. Alias entries point to object entries or other alias entries
and thus provide an alternative name for the corresponding object. The
DXserver DSA resolves alias entries to the distinguished name of the object
entry to which they point (the actual object).
Aliases interplay with many aspects of a DSA. For more information, see the
following sections for more details:
See Access Controls and Aliases in the chapter Security in the eTrust
Directory Administrator Guide.
Reading an Alias
Aliases resolve during navigation (the starting point for any service). This
means that the alias object is transparent to the user. When you make a read
request of an alias, the object read is the object to which the alias points.
To let a user read the alias object (as opposed to what it points to), you need
a mechanism. You can turn off alias resolution during navigation with the
X.500 service control dont-deref-aliases.
read-req
entry = <countryName “AU”>
<organizationName “Democorp”>
common-args = {dont-deref-aliases } ;
74 Developer Guide
Aliases
Adding an Alias
Adding an alias uses the normal add entry request. You must supply the object
class alias and the attribute aliasedObjectName. Any attribute that satisfies
the name binding between the alias and its parent can name the alias.
To add an alias:
add-entry-req
entry = <countryname “AU”>
<organizationName “Democorp”>
<commonName “Brendan Randall”>
contents = {
(objectClass alias)
(aliasedObjectName
<countryname “AU”>
<organizationName “Democorp”>
<organizationalUnitName “Services”>
<organizationalUnitName “Networks”>
<commonName “Brendan Randall”> )
};
Important! When the DSA has alias integrity enabled and you add an alias,
the object to which the alias points must exist within the domain of the DSA,
and the DSA must be able to navigate to the object entry.
Deleting an Alias
To delete an alias:
rem-entry-req
entry = <countryName “AU”>
<organizationName “Democorp”>
<commonName “Brendan Randall”>;
When the DSA has alias integrity enabled and you delete an object entry with
an alias entry pointing to it, both the object entry and the alias entry are
deleted.
Modifying an Alias
You can modify alias entries using the normal modify request. When you
change the aliasedObjectName attribute, the alias points to a different entry.
To modify an alias:
mod-entry-req
entry = <countryName “AU”>
<organizationName “Democorp”>
<commonName “Brendan Randall”>
rem-values {
(aliasedObjectName
<countryName “AU”>
<organizationName “Democorp”>
<organizationalUnitName “Services”>
<organizationalUnitName “Networks”>
<commonName “Brendan Randall”> )
},
add-values {
(aliasedObjectName
<countryName “AU”>
<organizationName “Democorp”>
<organizationalUnitName “Services”>
<organizationalUnitName “Networks”>
<commonName “System Manager”>
};
Even though the DSA permits modification of the object class attribute, you
cannot make a non-alias entry an alias entry. To perform such a modification,
first delete the entire entry and then re-add it as an alias (see the X.500
standard).
Important! When the DSA has alias integrity enabled and you modify an alias
entry so that it points to a new object entry, the DSA must be able to navigate
to the new object entry for the modify to succeed.
76 Developer Guide
Chapter 5: The UDDI Server
This section contains the following topics:
…/dxwebserver/webapps/uddi
If this file is not present, the server uses the default configuration, which is
what is normally installed.
This is the URL used to locate the directory server that is the UDDI server’s
data store. This data store is normally located on the same machine as the
UDDI server, and addressed as localhost. This means that you can configure
the DSA to respond only to queries from the local machine, which increases
security.
You can configure the UDDI server to use a DSA on another machine, but this
is less secure than the default setup in two ways:
The DSA must be configured to respond to requests from outside the local
machine – make sure you protect access to the machine running the DSA.
If you install two UDDI servers on the same machine, you have to configure
the second UDDI server to use a non-standard DSA port, and you could do this
by altering the directoryUrl setting. This is not the only setting you would need
to alter – this is not an easy task.
Important! Do not alter this setting unless you have a good understanding of
UDDI keys.
This is the name of a file that contains a list of key pairs, with one being a
UDDI Version 3 key, and the other a UDDI Version 2 key. This is a list of
exceptions – being those Version 3 keys whose matching Version 2 key is not
the one obtained by running the Version 3 key through the standard
translation algorithm, as documented in the UDDI Version 3 Specification.
Normally this file will only contain the keys which have been accorded special
treatment because their Version 2 keys were defined in the UDDI Version 2
Specification, and their Version 3 keys were defined after the Version 2 keys
were already set. These keys are canonical tModels, such as the
categorization:types tModel.
You may have defined some useful tModels using Version 2, and you may have
given them more meaningful names in Version 3, but wish to retain their
Version 2 keys for consistency. You can do this by adding them to the list of
keys in this file. You should make a copy of this file, add your keys, save it
with a different name, and alter this setting to point to your file – that would
avoid having your file over-written during an upgrade or re-installation of the
software.
78 Developer Guide
Comparing the eTrust Directory UDDI Server with the UDDI Specifications
This setting is the string that you wish to see presented in the operator
attribute of each UDDI response.
The UDDI Version 1 specification is the least well-defined, and most likely to
prove a source of problems.
The UDDI Server support of Version 1 is limited to the query interface – you
cannot publish entries in this server using the Version 1 publishing interface.
find_service
find_tModel
get_bindingDetail
get_businessDetail
get_serviceDetail
get_tModelDetail
80 Developer Guide
Comparing the eTrust Directory UDDI Server with the UDDI Specifications
UDDI Version 2
The UDDI Server includes implementations of all of the inquiry and publishing
APIs.
get_businessDetail
get_serviceDetail
get_tModelDetail
add_publisherAssertions
delete_binding
delete_business
delete_publisherAssertions
delete_service
delete_tModel
discard_authToken
get_assertionStatusReport
get_authToken
get_publisherAssertions
get_registerInfo
save_binding
save_business
save_service
save_tModel
set_publisherAssertions
UDDI Version 3
The UDDI Server includes implementations of all of the inquiry and publishing
APIs, plus the security APIs.
get_tModelDetail isReplacedBy
add_publisherAssertions ValidatedBy
delete_binding DerivedFrom
delete_business generalKeywords
delete_publisherAssertions entityKeyValues
delete_service
delete_tModel
get_assertionStatusReport
get_publisherAssertions
get_registerInfo
save_binding
save_business
save_service
save_tModel
set_publisherAssertions
discard_authToken
get_authToken
82 Developer Guide
Comparing the eTrust Directory UDDI Server with the UDDI Specifications
Subscription
The UDDI Server does not support the subscription APIs. This functionality
may be included in a future release.
Custody Transfer
The UDDI Server does not include the custody transfer APIs.
Replication
This server does not implement the UDDI replication APIs because this is
intended to be a single-node implementation of UDDI.
Instead, you can use the mature replication and distribution functionality in
eTrust Directory to replicate or distribute the underlying data store, and install
the UDDI server layer in multiple locations