Overview of Attribute Editors

Why are Attribute Data Editors Needed?

There are a large number of non-string data types; graphics formats, audio formats, cryptography formats etc. In addition, there are often application specific data types.

In order for the general purpose JXplorer to allow users to modify data, we need to allow for special purpose editors for a particular data type.

I need to Handle Foreign Languages

You don't need to write a pluggable editor. Java's normal string handling of Unicode should automatically translate between the locale specific character encoding and the Unicode format used internally in the browser. The Unicode is read from and written to the directory in a transformation format called UTF-8, but this is invisible to the user. JXplorer has been succesfully tested with European and Asian languages on correctly installed localised platforms.

Can I just use a windows editor?

Yes you can. You'll need to write a simple Java wrapper class that calls the native application and passes the data along. 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.

I don't have Time to do this, and I Really Need to Edit some Binary Data!

The default binary editor displays data in base64 encoded form (suitable for mail programs and text viewing). This isn't very useful for editing, however the default editor also allows you to save the data, and it will be saved in binary form. To modify the data, save it to disk, use your normal tool to manipulate the data, and load it back into the default binary editor. It's clumsy, but it works!


         The Default Binary Editor



Writing a Pluggable Attribute Editor

Writing a Pluggable Editor simply involves writing a Java class that implements the com.ca.directory.jxplorer.editor.abstractbinaryeditor interface, or alternatively, extends the com.ca.directory.jxplorer.editor.BasicBinaryEditer class. The class must be given the name of the attribute type, with the suffix 'Editor'. A small wrinkle: the attribute type should be capitalised in the same way that the server publishes it. For example, writing an editor for the attribute 'ocspRSAPrivateKey' requires the final class to be called 'ocspRSAPrivateKeyEditor.class'. (This restriction may be removed in future.)

Extending the abstractbinaryeditor class

The abstractbinaryeditor Interface has only one method, 'public void setValue(EditableBinary editMe). This passes an EditableBinary object, which is a data object used to store a byte array. The EditableBinary object has two methods, public byte[] getValue() and public void setValue(byte[] bytes), used respectively to read and write to the object.

When an attribute value of the appropriate type is found by JXplorer, and a user wishes to edit it (by clicking on the value cell in the editor pane) JXplorer will run the pluggable editor, passing the byte array to it using the setValue method of abstractbinaryeditor. That Editor can then manipulate the object as it wishes (usually by creating a GUI and allowing the user to edit the data in some way). As long as the EditableBinary object is updated with the final value, when the user hits the 'submit' button in JXplorer the new value will be entered in to the directory.


Extending basicbinaryeditor

basicbinaryeditor is a default implementation of abstractbinaryeditor using a swing JDialogBox. For some purposes it may be easier to extend it, rather than implement a GUI from scratch and using abstractbinaryeditor directly.


An example

The following is an example of a pluggable editor that could be used to handle masked, binary password data. Almost all of this code is simply setting up the GUI.



---------------------------------------------------------------------

/**
 *    All pluggable editors must be in this package
 */
 
package com.ca.directory.jxplorer.editor;

import com.ca.commons.cbutil.CBPanel;      // custom version of JPanel
import com.ca.commons.cbutil.CBIntText;    // i18n support

import Javax.swing.*;
import Java.awt.*;
import Java.awt.event.*;
import Java.io.*;

/**
 *    Password Editor.
 *    Allows user to enter a masked binary password.
 */
 
public class userpasswordeditor extends JDialog 
    implements abstractbinaryeditor
{
    protected JPasswordField pwd;
    protected JButton        btnOK, btnCancel;
    protected EditableBinary editMe = null;
    protected CBPanel        display;

    /**
     *    Constructor - sets up the GUI.
     */
     
    public userpasswordeditor(Frame owner) 
    {
        super(owner);
        setModal(true);
        setTitle(IntText.get("User Password Data"));
        
        display = new CBPanel();
        
        pwd = new JPasswordField();  
        
        btnOK = new JButton(IntText.get("OK"));
        btnOK.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                       load();
                       quit();
           }});
           
        btnCancel = new JButton(IntText.get("Cancel"));
        btnCancel.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                       quit();
           }});
           
        display.makeHeavy();
        display.addln(pwd);
        display.makeLight();
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(btnOK);
        buttonPanel.add(btnCancel);
        display.addln(buttonPanel);
    
        setSize(400,100);
        setTitle(IntText.get("User Password Data"));
        getContentPane().add(display);
    }    

    /** 
     *    This is the abstractbinaryeditor interface method which is
     *    called when the user wants to edit the password
     */
         
    public void setValue(EditableBinary editMe)
    {
        this.editMe = editMe;
        pwd.setText(stringEncode(editMe.getValue()));    
    } 

    /** 
     *    converts between text and a byte array
     */
     
    protected byte[] stringDecode(String s) 
    { 
        if (s==null) 
            return (new byte[0]);
        else    
            return s.getBytes(); 
    } 

    /** 
     *    converts between a byte array and text
     */
     
    protected String stringEncode(byte[] b) 
    { 
        if (b == null || b.length ==0)
            return new String();
        else    
            return new String(b); 
    }

    /**
     * sets the value of the EditableBinary object with whatever the
     * user has entered into the password text field.
     */
         
    protected void load() 
    {
        editMe.setValue(stringDecode(new String(pwd.getPassword())));
    }
    
    /**
     *    Shuts down the GUI.
     */
    
    protected void quit()
    {
        setVisible(false);
        dispose();
    }
}

---------------------------------------------------------------------

» top