Wednesday, August 24, 2011

Using Sapphire to Work with Java Types

This article covers an intermediate topic related to Sapphire. Those unfamiliar with Sapphire should first read the introduction.

When implementing Eclipse tooling that works with Java projects, a frequent requirement is to deliver models and UI that reference Java types (classes, interfaces, enumerations and annotations). Implementing this from scratch, even using the excellent API provided by JDT is a challenge. Fortunately, Sapphire's JDT integration makes this quite easy.

The first step is the model.

@Type( base = JavaTypeName.class )
@Reference( target = JavaType.class )
@Label( standard = "filter" )
@JavaTypeConstraint( kind = { JavaTypeKind.CLASS, JavaTypeKind.INTERFACE }, type = "java.io.FileFilter" )
@MustExist
@Required

ValueProperty PROP_FILTER = new ValueProperty( TYPE, "Filter" );

ReferenceValue<JavaTypeName,JavaType> getFilter();
void setFilter( String value );
void setFilter( JavaTypeName value );

Here we utilize reference value construct which states that the property holds a JavaTypeName which is resolvable to a JavaType. The resolution is provided by the framework and works as long as the model is loaded in the context of a Java project.

The @JavaTypeConstraint annotation specifies that the referenced type must be a class or an interface and that it must derive from java.io.FileFilter type.

The @MustExist annotation specifies that the named type must be present in the project.

The @Required annotation specifies that the property must have a value (null is not ok).

The next step is the UI definition. Here we create an editor section with a single property editor, but the property editor is, of course, not limited to editor sections. It can be used in any form context.

<section>
    <content>
        <property-editor>Filter</property-editor>
    </content>
</section>

That is all that is necessary to define a model property that references a Java type and to present that property in the UI. Once this example is executed, you will see a property editor that is composed of a label, a text box, two action buttons and a validation feedback marker.

Capture-1

Clicking on the validation feedback marker shows the problem message along with wealth of semantic information about the property.

Capture-2

The browse button provides the means to select from among existing Java types using JDT's type selection dialog. The framework automatically constraints the contents of the dialog based on @JavaTypeConstraint annotation.

Capture-3

Capture-4

The create button provides the means to define a new Java type if the specified type name cannot be resolved.

Capture-5

Since @JavaTypeConstraint annotation in this example specifies that the property can reference either a class or an interface, the user is presented with a choice after clicking on the create button.

Capture-6

Once the appropriate option is selected, the new type is created and opened in the Java editor. The created type derives from the type specified in @JavaTypeConstraint annotation and is formatted according to user's format preferences.

Capture-7

Note that this article covers features in 0.3.1 and 0.4 releases of Sapphire, which at the time of this writing are still in development. A subset of the described features is available in version 0.3, which is the latest released version. Please direct all questions to the forum.

No comments: