JPOX
JPOX
 Project  |  Ver 1.1  |  Ver 1.2  |  JDO  |  JPA  |  Guides  |  Tools
1.1 | Preparation | O/R Mapping | Runtime | Extensions | Developer
Extensions
Plugins : Value Generators

JPOX is developed as a plugin-driven framework and one of the components that is pluggable is the generation of identity or field values. JPOX provides a large selection of generators but is structured so that you can easily add your own variant and have it usable within your JPOX usage. This is available in JPOX from version 1.1.2

The following sections describe how to create your own value generator plugin for JPOX.

Interface

Any value generator plugin will need to implement org.jpox.store.poid.PoidGenerator which in turn extends javax.jdo.datastore.Sequence). So you need to implement the following interface

import javax.jdo.datastore;

public interface Sequence
{
    /**
     * Returns the fully qualified name of the Sequence.
     * @return the name of the sequence
     */
    String getName();

    /**
     * Returns the next sequence value as an Object. If the next
     * sequence value is not available, throw JDODataStoreException.
     * @return the next value
     */
    Object next();

    /**
     * Provides a hint to the implementation that the application
     * will need additional sequence value objects in
     * short order. There is no externally visible behavior of this
     * method. It is used to potentially improve the efficiency of
     * the algorithm of obtaining additional sequence value objects.
     * @param additional the number of additional values to allocate
     */
    void allocate(int additional);

    /**
     * Returns the current sequence value object if it is
     * available. It is intended to return a sequence value object
     * previously used. If the current sequence value is not available,
     * throw JDODataStoreException.
     * @return the current value
     */
    Object current();

    /** 
     * Returns the next sequence value as a long. If the next
     * sequence value is not available or is not numeric, throw
     * JDODataStoreException.
     * @return the next value
     */
    long nextValue();

    /** 
     * Returns the current sequence value as a long. If the current
     * sequence value is not available or is not numeric, throw
     * JDODataStoreException.
     * @return the current value
     */
    long currentValue();
}
import org.jpox.store.poid;

public interface PoidGenerator extends Sequence
{
}


Implementation

JPOX provides an abstract base class org.jpox.store.poid.AbstractPoidGenerator to extend if you don't require datastore access. If you do require (RDBMS) datastore access for your PoidGenerator then you can extend org.jpox.store.rdbms.poid.AbstractRDBMSPoidGenerator Let's give an example, here we want a generator that provides a form of UUID identity. We define our class as

package mydomain;

import org.jpox.store.poid.PoidBlock;
import org.jpox.store.poid.AbstractPoidGenerator;

public class MyUUIDPoidGenerator extends AbstractPoidGenerator
{
    public MyUUIDPoidGenerator(String name, Properties props)
    {
        super(name, props);
    }

    /**
     * Method to reserve "size" POIDs to the PoidBlock.
     * @param size The block size
     * @return The reserved block
     */
    public PoidBlock reserveBlock(long size)
    {
        Object[] ids = new Object[(int) size];
        for (int i = 0; i < size; i++)
        {
            ids[i] = getIdentifier();
        }
        return new PoidBlock(ids);
    }

    /**
     * Create a UUID identifier.
     * @return The identifier
     */
    private String getIdentifier()
    {
        ... Write this method to generate the identifier
    }
}

As show you need a constructor taking 2 arguments String and java.util.Properties. The first being the name of the generator, and the second containing properties for use in the generator.

  • class-name Name of the class that the value is being added to
  • root-class-name Name of the root class in this inheritance tree
  • field-name Name of the field whose value is being set (not provided if this is datastore identity field)
  • catalog-name Catalog that objects of the class are stored in
  • schema-name Schema that objects of the class are stored in
  • table-name Name of the (root) table storing this field
  • column-name Name of the column storing this field
  • sequence-name Name of the sequence (if specified in the MetaData)


Plugin Specification

So we now have our custom "value generator" and we just need to make this into a JPOX plugin. To do this you simply add a file plugin.xml to your JAR either at the root, or in META-INF/plugins. The file plugin.xml should look like this

<?xml version="1.0"?>
<plugin id="mydomain" name="JPOX plug-ins" provider-name="My Company">
    <extension point="org.jpox.store_valuegenerator">
        <valuegenerator name="myuuid" class-name="mydomain.MyUUIDPoidGenerator" unique="true"/>
    </extension>
</plugin>

The name "myuuid" is what you will use as the "strategy" when specifying to use it in MetaData. The flag "unique" is only needed if your generator is to be unique across all requests. For example if your generator was only unique for a particular class then you should omit that part. Thats all. You now have a JPOX "value generator" plugin.

Plugin Usage

To use your value generator you would reference it in your JDO MetaData like this

<class name="MyClass">
    <datastore-identity strategy="myuuid"/>
    ...
</class>

Don't forget that if you write a value generator that could be of value to others you could easily donate it to JPOX for inclusion in the next release.