Thursday, December 1, 2011

Announcing Sapphire 0.4 Release

On behalf of all who contributed, I am very proud to announce availability of Sapphire 0.4 release. This release includes major enhancements, such as API improvements in services and XML binding, more powerful Sapphire EL and ability to use it in more places, content proposals in text fields, split form, regular multi-section form editor page for cases where master-details presentation isn't appropriate, and much more.

Enhancements
Migration Guide
Developer Guide
Downloads

Saturday, November 19, 2011

Java Language Puzzle 3

Given the following source listing, explain why the compiler is producing a warning at invocation to the list method and give a solution for removing the warning without resorting to @SuppressWarnings annotation.

public class JavaLanguagePuzzle3
{
    public static void main( String[] args )
    {
        list( "1", 2, new BigDecimal( "3.5" ) );
    }
    
    private static <T> List<T> list( T... items )
    {
        return Arrays.asList( items );
    }
}

Warning:

Type safety: A generic array of Object&Serializable&Comparable<?> is created for a varargs parameter

Friday, October 7, 2011

Announcing Sapphire 0.3.1 Release

It is with great pleasure that I announce availability of Sapphire 0.3.1 release. This maintenance release includes 64 bug fixes and enhancements. Adopters of 0.3 release can expect full backwards compatibility. No migration guide is being published.

Enhancements
Developer Guide
Downloads

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.

Monday, August 1, 2011

From XML to Form to Diagram with Sapphire

Many of the systems that developers and administrators interact with on the daily basis are configured via a menagerie of XML files. Even armed with a schema and a good XML editor, users have a hard time editing these files by hand. A good tooling strategy to address this difficulty is to create a multi-page editor where a user can flip back-n-forth between XML source view and a higher level form-based view. Going a notch further, certain relationships can be presented with one or more diagrams on separate pages.

Unfortunately, building such multi-page editor using basic Eclipse platform facilities is a daunting challenge. It can take many months to create something half-decent for even smaller schemas. Sapphire can make this a much less daunting task by focusing developer attention on modeling semantics of the data rather than wiring individual widgets.

properties-view-1

I have proposed a talk for EclipseCon Europe 2011 to present Sapphire as a whole and the new diagram editing features in Sapphire 0.3 (Indigo) release. You can comment and vote on the proposal if you are interested.

Proposed Talk: From XML to Form to Diagram with Sapphire

Sapphire is a relatively new project at Eclipse started with an initial contribution from Oracle. It is a UI building framework that allows developers to specify UI in terms of higher level constructs like property editors instead of widgets and layouts. This paradigm results in several orders of magnitude improvement in developer productivity while simultaneously delivering better quality UI that is easier to maintain.

Friday, July 1, 2011

Sapphire 0.4 : FactsService

This is the first in what I hope to be a series of blog posts highlighting new features in the upcoming Sapphire 0.4 release.

When a property is described to a user in documentation one does it with a series of short statements that define its semantics, such as "must be specified" or "maximum value is 100". When a property is described to Sapphire one does it with a series of annotations, such as @Required or @NumericRange. This duplicate specification is a maintenance problem.

A FactsService provides a means to dynamically derive statements about property's semantics based on property's metadata. The derived facts can then be presented to the user as part of documentation, property editor information popup and in other relevant places.

A single facts service can produce multiple facts and multiple facts services can be active concurrently for a given property. FactsAggregationServices provides an easier way to consume all facts.

Sapphire includes a number of FactsService implementations.

ID Description
Sapphire.FactsService.JavaTypeConstraint Creates fact statements about Java type property's constraints by using semantical information specified by @JavaTypeConstraints annotation.
Sapphire.FactsService.Static Creates fact statements about property by using static content specified in @Fact and @Facts annotations.
Sapphire.FactsService.DefaultValue Creates fact statements about property's default value by using semantical information specified by DefaultValueService and @DefaultValue annotation.
Sapphire.FactsService.NumericRange Creates fact statements about numeric value property's range by using semantical information specified by @NumericRange annotation.
Sapphire.FactsService.Required Creates fact statements about property's optionality by using semantical information specified by @Required annotation.
Sapphire.FactsService.ReadOnly Creates fact statements about property's read-only state by using semantical information specified by @ReadOnly annotation.
Sapphire.FactsService.CountConstraint Creates fact statements about list property's count constraint by using semantical information specified by @CountConstraint annotation.
Sapphire.FactsService.AbsolutePath Creates fact statements about property's absolute path requirement by using semantical information specified by @AbsolutePath annotation.
Sapphire.FactsService.MustExist Creates fact statements about existence requirement on the entity referenced by property's value by using semantical information specified by @MustExist annotation.
Sapphire.FactsService.NoDuplicates Creates fact statements about value property's uniqueness constraint by using semantical information specified by @NoDuplicates annotation.
Sapphire.FactsService.ValidFileExtensions Creates fact statements about valid file extensions for property's value by using semantical information specified by @ValidFileExtensions annotation.
Sapphire.FactsService.ValidFileSystemResourceType Creates fact statements about valid file system resource type (file or folder) for property's value by using semantical information specified by @ValidFileSystemResourceType annotation.
Sapphire.FactsService.ProjectRelativePath Creates fact statements about property's relative to the project path requirement by using semantical information specified by @ProjectRelativePath annotation.
Sapphire.FactsService.WorkspaceRelativePath Creates fact statements about property's relative to the workspace path requirement by using semantical information specified by @WorkspaceRelativePath annotation.

Example

This screen capture shows user experience with some of the provided FactsService implementation. See if you can match facts in the screen capture to service implementations above.

FactsService

Adopters can provide custom FactService implementations either globally using Sapphire extension system or at the property level using @Service annotation.

Example

A simple global FactsService implementation that is triggered by a hypothetical @Since property annotation.

public class SinceVersionFactsService extends FactsService
{
    @Override
    protected void facts( List facts )
    {
        Since since = property().getAnnotation( Since.class );
        facts.add( "Since version " + since.version() + "." );
    }

    public static class Factory extends ModelPropertyServiceFactory
    {
        @Override
        public boolean applicable( IModelElement element,
                                   ModelProperty property,
                                   Class<? extends ModelPropertyService> service )
        {
            return property.hasAnnotation( Since.class );
        }
    
        @Override
        public ModelPropertyService create( IModelElement element,
                                            ModelProperty property,
                                            Class<? extends ModelPropertyService> service )
        {
            return new SinceVersionFactsService();
        }
    }
}

The service implementation is registered in META-INF/sapphire-extension.xml file.

<extension xmlns="http://www.eclipse.org/sapphire/xmlns/extension">
    <model-property-service>
        <id>Example.SinceVersionFactsService</id>
        <type>org.eclipse.sapphire.services.FactsService</type>
        <factory>example.SinceVersionFactsService$Factory</factory>
    </model-property-service>
</extension>

Facts can also be statically specified for a given property by using @Fact annotation. Use @Facts annotation to specify multiple facts. The facts contained in these annotations are surfaced by an included FactsService implementation (id:Sapphire.FactsService.Static).

Example

// *** ExampleOne ***
    
@Fact( statement = "Important fact.")
    
ValueProperty PROP_EXAMPLE_ONE = new ValueProperty( TYPE, "ExampleOne" );
    
Value getExampleOne();
void setExampleOne( String value );

// *** ExampleMultiple ***
    
@Facts( { @Fact( statement = "First important fact." ), @Fact( statement = "Second important fact." ) } )
    
ValueProperty PROP_EXAMPLE_MULTIPLE = new ValueProperty( TYPE, "ExampleMultiple" );
    
Value getExampleMultiple();
void setExampleMultiple( String value );

Please direct your comments and questions to Sapphire adopter forum.

Monday, June 27, 2011

Java Language Puzzle 2

Given the following source listing, explain why InstantiationException is thrown when running (via the main method entry point) and how the code should be fixed.

package puzzle;

public class Entity
{
    private Entity()
    {
    }
    
    public class Factory
    {
        public Entity create()
        {
            return new Entity();
        }
    }
    
    public static void main( String[] args ) throws Exception
    {
        Factory.class.newInstance();
    }
}
Exception in thread "main" java.lang.InstantiationException: puzzle.Entity$Factory
	at java.lang.Class.newInstance0(Unknown Source)
	at java.lang.Class.newInstance(Unknown Source)
	at puzzle.Entity.main(Entity.java:19)

ANSWER:  It looks like everyone who responded correctly identified the fact that Factory class is not defined as static as the cause of this exception. The solution is to add the static keyword. I would imagine that vast majority of Java developers are pretty comfortable with static/non-static inner classes semantics. What raises this to a puzzle level is a rather unhelpful exception.

Wednesday, June 22, 2011

Announcing Sapphire 0.3 Release

It is with great pleasure that I announce on-time availability of Sapphire 0.3 release. This release includes numerous enhancements, some of which I will briefly describe. Current users of 0.2.x line will want to consult the migration guide.

Before we get to the new features, it is important to take a few minutes to thank all the people who made this release possible. Shenxue Zhou is a new committer on the project and has been working hard to bring us diagram editing support. A key new features in this release. The community around Sapphire has grown substantially in the last few months. Many of the enhancements that you will find in this release are based on ideas and requirements brought by the new adopters. All of the adopters deserve a thank you, but I will call out one by name. Greg Amerson (Liferay) has progressed very quickly from an adopter to a contributors. Five patches from Greg are in the 0.3 release. Greg has the distinction of being the first non-Oracle contributor to Sapphire. Last but not least, several members of Oracle QA has pitched in to verify enhancements and fixed bugs.

Without further ado, I present the enhancements in the 0.3 release…

Diagram Editing – Define diagram UI just as easily as a form. Sapphire declarative UI language has been expanded to cover basic diagram concepts. This feature opens the door for very sophisticated editors that provide diagram, form and source views on the same data. Yet, no matter how many diagram, form and source views on the data you define, Sapphire keeps everything in sync with n-way synchronization.

Properties View Integration – Easily attach properties view content to diagram nodes, connections, form outline nodes, etc. using the same UI definition facilities as the editor. Sapphire will automatically inject that content into the standard Eclipse properties view when that part has selection.

UI Definition Editor – Spend less time trying to get sdef syntax right with the new form-based editor for Sapphire UI Definition files. The editor is, of course, itself built using Sapphire.

Expression Language Enhancements – Use EL in more areas of model and UI specification than before. The EL itself is now even more powerful with better handling of collections and support for custom type casts among other features.

Modularity Improvements – Use Sapphire in more scenarios than before. The core modeling framework now only requires Java. Add integration with OSGi, Eclipse platform resources, JDT, etc. by installing separate modules.

Miscellaneous Enhancements – Embed snippets of HTML into a form, show related content next to a property editor, choose from three layouts for a checkbox, specify editor header image, define collapsible sections, the list goes on. Head over to the enhancements guide for all the details.

Of course, no release of a UI framework would be complete without screen captures. Here are a few to wet your appetite…

properties-view-1

properties-view-3

properties-view-2

Enhancements
Migration Guide
Developer Guide
Downloads

Concurrently with 0.3, we are also shipping 0.2.3 release to bring support for Indigo to adopters who still rely on the 0.2.x line.

Friday, June 17, 2011

Java EE Module Configuration Editors Draft Proposal

I am working on a proposal for Java EE Module Configuration Editors project. The goal is to create a new project under WTP Java EE Tools project and build there editors for web.xml, application.xml, ejb-jar.xml and possibly all the rest of the module configuration files. The editors would be built using Sapphire and work across various versions of Java EE spec. For Java EE 5 or newer, the editors would be able to also edit Java annotations instead of the XML configuration file from the same interface.

Draft Proposal

While I am working on the getting the new project created to hold this work, I’ve started implementing the web.xml editor in Sapphire repository as a sample. You can get a feel for what’s there now and what the final result will look like in the screencast that I put together.

Screencast

To take the editor for a spin yourself, install everything from the following repository. Don't try to go to a newer build as this plugin has been removed from the Sapphire build in preparation for the 0.3 release.

https://hudson.eclipse.org/hudson/job/sapphire-0.3.x/408/artifact/build/repository/

To access the source code, point your Eclipse at the following location in CVS. Note that you will need WTP + Sapphire in your target platform and Sapphire SDK in your dev eclipse. The latter part is very important as the Sapphire SDK contains the code generate necessary to build this plugin.

Source Code

If you are interested in this work, leave a comment with your name on this blog post or send a note to wtp-dev mailing list so that I can add you to the list of interested parties in the project proposal. If you are interested in helping to implement these editors, state as much as well and we will discuss.

Friday, March 18, 2011

State of Sapphire for Spring 2011

It has been a busy five months for the Sapphire team since the project was created in October of 2010. The initial code contribution from Oracle has gone through the Eclipse Foundation’s IP review, we have source in CVS, bugs in Bugzilla and builds running on every commit. Even though the current project team is only staffed by Oracle employees, we make it a point to communicate in the open on the adopter forum and the developer mailing list.

Releases

Two feature releases and two service releases shipped so far.

Version 0.1

The initial stable code contribution from Oracle, but refactored for eclipse.org namespace, build and legal requirements.

Version 0.1.1

Some infrastructure work was still ongoing when 0.1 shipped. Version 0.1.1 delivered the binaries in signed form.

Version 0.2

Major enhancements, such as a powerful resource abstraction for models, expression language, transient properties, derived properties, new property editors and many more. Despite shipping concurrently with the 0.1 release, version 0.2 represents roughly six months of new feature work that was happening as we were waiting on the project creation process.

Version 0.2.1

No major release can happen without at least a few bugs getting through.

Adoption

You might ask… This technology does look promising, but how do I really know if it is ready for production?

Sapphire may be young at Eclipse, but it has been in development since at least 2007 as part of BEA’s and later Oracle’s Eclipse tooling efforts. Oracle Enterprise Pack for Eclipse (OEPE) heavily leverages Sapphire to create a variety of form based user interfaces across the product.  During the transition to Eclipse, we worked quickly to close the feedback loop between the new Sapphire project and its big adopter. To that end, OEPE 11.1.1.7 shipped with Sapphire 0.1.1 and upcoming OEPE 11.1.1.7.1 will ship with Sapphire 0.2.1 release. The tight feedback loop from OEPE has enabled us to quickly stabilize the major new features delivered in the 0.2 release.

We are also getting ready to announce a major new endeavor to, in part, promote adoption of Sapphire across Eclipse. In the next few weeks, we will formally propose a project under WTP to use Sapphire to create editors for standard Java EE deployment descriptors.

Little Miss Sapphire

On February 8th, Sapphire family grew by one with the birth of Little Miss Sapphire or Amelia as she is known when she is not voicing opinions on architectural issues.

3D2B2359

I am still mastering the art of typing with one hand. My Das Keyboard doesn’t make this easy, but I like a good challenge.

Release 0.3 and Indigo

The next major Sapphire release is scheduled to go out concurrently with Indigo in June of 2011. We are pushing improvements on two fronts.

First, we are adding support for creating diagram editors, defined and wired to the model in a similar way that forms are today. The current diagram parts renderer uses Graphiti, but the application developer will not interact with Graphiti directly, allowing renderer implementation to be changed or swapped out in the future.

By the time 0.3 ships, you will be able to create slick three-page editors showing source, form and diagram views on the same data. Bi-directional editing is so yesterday. Welcome to tri-directional editing!

diagram

Second, we are making a major push on improving the facilities provided by the SDK to make developing with Sapphire even easier. The big new feature is an editor for Sapphire UI definitions (aka sdef files). All the content assist and validation isn’t finished yet, but the editor is already much better than editing XML markup by hand. The editor is, naturally, built using Sapphire. Yesterday, I spent a good portion of the day using the sdef editor from a previous build to work on new editor features for the next build. Extreme dogfooding!

sdef

Shenxue Zhou Becomes a Committer

Shenxue has been involved with Sapphire as a consumer for a long time, but over the last several months, she has progressed to contributor status with her work on the diagram editing support. After a number of high quality patches, we welcomed Shenxue as the first elected committer on the project.

EclipseCon 2011

I am going to be giving a 20 minute talk on Sapphire at this year’s EclipseCon. No slides to bore you with. Just a live demo of building a project using Sapphire. If you are at all interested in this technology, come see the demo. It should be entertaining (one way or another).

If you cannot make it to the talk, I will be at the conference all four days, so flag me down between sessions or at the bar. Another Sapphire committer, Ling Hao, will also be attending EclipseCon this year.

Tuesday, February 22, 2011

Announcing Sapphire logo

Every noteworthy project requires a cool logo, so I am very pleased to announce that Sapphire now joins that distinguished circle with a brand new logo. The new logo is a contribution of Jean Yao, a talented graphics designer at Oracle. I think you will agree that she has done a great job.

sapphire

The new logo is already featured on the project home page and you can also spot it in recent 0.2.1 and 0.3.0 builds.

about

project-explorer