# Enhancements in Sapphire 9

1. AutoCloseable

1. DefinitionLoader.Reference
2. Element
3. Event Suspension Handle
4. FunctionResult
5. SapphireCondition
6. SapphirePart

2. Repeatable

1. @Fact
2. @Service
3. @Validation
4. @XmlNamespace
5. @XmlSchema

3. Miscellaneous

1. Transparent Reference Setting
2. Ordered Possible Types
3. Diagram Palette Icons

## DefinitionLoader.Reference is AutoCloseable

Taking advantage of Java 7, DefinitionLoader.Reference now extends AutoCloseable, so it can be used in the try-with-resources construct.

    try( DefinitionLoader.Reference<DialogDef> def = DefinitionLoader.sdef( getClass() ).dialog() )
    {
        ...
    }

## Element is AutoCloseable

Taking advantage of Java 7, Element now extends AutoCloseable, so it can be used in the try-with-resources construct.

    try( ExampleElement example = ExampleElement.TYPE.instantiate() )
    {
        ...
    }

## Event Suspension Handle is AutoCloseable

Taking advantage of Java 7, the event suspension handle returned from Property.suspend() and Element.suspend() methods now implements AutoCloseable, so it can be used in the try-with-resources construct.

    try( Suspension suspension = property.suspend() )
    {
        ...
    }

    try( Suspension suspension = element.suspend() )
    {
        ...
    }

## FunctionResult is AutoCloseable

Taking advantage of Java 7, FunctionResult now implements AutoCloseable, so it can be used in the try-with-resources construct.

    try( FunctionResult fr = ExpressionLanguageParser.parse( expr ).evaluate( context ) )
    {
        ...
    }

## SapphirePart is AutoCloseable

Taking advantage of Java 7, SapphirePart now implements AutoCloseable, so it can be used in the try-with-resources construct.

    try( SapphirePart part = new DialogPart() )
    {
        ...
    }

## SapphireCondition is AutoCloseable

Taking advantage of Java 7, SapphireCondition now implements AutoCloseable, so it can be used in the try-with-resources construct.

    try( SapphireCondition condition = ... )
    {
        ...
    }

## Repeatable @Fact

Taking advantage of Java 8, @Fact annotation is now repeatable, saving user the trouble of manually wrapping @Facts container annotation around multiple @Fact annotations present at a single site.

    @Fact( statement = "First fact" )
    @Fact( statement = "Second fact" )
    @Fact( statement = "Third fact" )

    ValueProperty PROP_EXAMPLE = new ValueProperty( TYPE, "Example" );

    Value<String> getExample();
    void setExample( String value );

## Repeatable @Service

Taking advantage of Java 8, @Service annotation is now repeatable, saving user the trouble of manually wrapping @Services container annotation around multiple @Service annotations present at a single site.

    @Type( base = Path.class )
    @Reference( target = IContainer.class )
    @ValidFileSystemResourceType( FileSystemResourceType.FOLDER )
    @Service( impl = FolderReferenceService.class )
    @Service( impl = FolderValidationService.class )
    @Service( impl = FolderInitialValueService.class )

    ValueProperty PROP_FOLDER = new ValueProperty( TYPE, "Folder" );

    ReferenceValue<Path,IContainer> getFolder();
    void setFolder( String value );
    void setFolder( Path value );
    void setFolder( IContainer value );

## Repeatable @Validation

Taking advantage of Java 8, @Validation annotation is now repeatable, saving user the trouble of manually wrapping @Validations container annotation around multiple @Validation annotations present at a single site.

    @Type( base = Integer.class )
    @DefaultValue( text = "0" )
    @Validation( rule = "${ Max >= Min }", message = "Must not be smaller than min" )
    @Validation( rule = "${ Max <= 100 }", message = "Must be less than or equal to 100", severity = Status.Severity.WARNING )

    ValueProperty PROP_MAX = new ValueProperty( TYPE, "Max" );

    Value<Integer> getMax();
    void setMax( String value );
    void setMax( Integer value );

## Repeatable @XmlNamespace

Taking advantage of Java 8, @XmlNamespace annotation is now repeatable, saving user the trouble of manually wrapping @XmlNamespaces container annotation around multiple @XmlNamespace annotations present at a single site.

    @XmlNamespace( uri = "http://www.eclipse.org/sapphire/example/x", prefix = "x" )
    @XmlNamespace( uri = "http://www.eclipse.org/sapphire/example/y", prefix = "y" )
    @XmlNamespace( uri = "http://www.eclipse.org/sapphire/example/z", prefix = "" )
    @XmlSchema( namespace="http://www.eclipse.org/sapphire/example/x", location="http://www.eclipse.org/sapphire/example/x/1.0" )
    @XmlSchema( namespace="http://www.eclipse.org/sapphire/example/y", location="http://www.eclipse.org/sapphire/example/y/1.0" )
    @XmlSchema( namespace="http://www.eclipse.org/sapphire/example/z", location="http://www.eclipse.org/sapphire/example/z/1.0" )
    @XmlBinding( path = "example" )

    public interface ExampleElement extends Element
    {
        ...
    }

## Repeatable @XmlSchema

Taking advantage of Java 8, @XmlSchema annotation is now repeatable, saving user the trouble of manually wrapping @XmlSchemas container annotation around multiple @XmlSchema annotations present at a single site.

    @XmlNamespace( uri = "http://www.eclipse.org/sapphire/example/x", prefix = "x" )
    @XmlNamespace( uri = "http://www.eclipse.org/sapphire/example/y", prefix = "y" )
    @XmlNamespace( uri = "http://www.eclipse.org/sapphire/example/z", prefix = "" )
    @XmlSchema( namespace="http://www.eclipse.org/sapphire/example/x", location="http://www.eclipse.org/sapphire/example/x/1.0" )
    @XmlSchema( namespace="http://www.eclipse.org/sapphire/example/y", location="http://www.eclipse.org/sapphire/example/y/1.0" )
    @XmlSchema( namespace="http://www.eclipse.org/sapphire/example/z", location="http://www.eclipse.org/sapphire/example/z/1.0" )
    @XmlBinding( path = "example" )

    public interface ExampleElement extends Element
    {
        ...
    }

## Transparent Reference Setting

Set a reference property to the target object and let the system figure out the key to write to the model. This facility is made possible by a new API in ReferenceService.

    public abstract class ReferenceService<T> extends DataService<T>
    {
        /**
         * Returns the key that can be used to reference the provided object. The default implementation
         * throws UnsupportedOperationException.
         *
         * @param object the object
         * @return the key
         * @throws UnsupportedOperationException if this service does not support key extraction
         * @throws IllegalArgumentException if the object is not a valid target for this reference
         */

        public String reference( T object )
    }

ElementReferenceService and JavaTypeReferenceService implement the new API out of the box. Other ReferenceService implementations will need to be updated before model consumers can take advantage of this facility.

To use this facility, simply call the existing property write method with the target object.

    @Reference( target = Table.class )
    @ElementReference( list = "/Tables", key = "Name" )

    ValueProperty PROP_TABLE = new ValueProperty( TYPE, "Table" );

    ReferenceValue<String,Table> getTable();
    void setTable( String value );

    Table table = ...
    element.getTable().write( table );

Alternatively, add a typed setter method to the interface and Sapphire will implement it.

    @Reference( target = Table.class )
    @ElementReference( list = "/Tables", key = "Name" )

    ValueProperty PROP_TABLE = new ValueProperty( TYPE, "Table" );

    ReferenceValue<String,Table> getTable();
    void setTable( String value );
    void setTable( Table value );

    Table table = ...
    element.setTable( table );

## Ordered Possible Types

Typically, possible types have no particular order and it is desirable to present them sorted by the type name. In some cases, the order is significant. New API allows these cases to be differentiated.

    @Type
    {
        boolean ordered() default false
    }

    PossibleTypesService
    {
        public boolean ordered()
        {
            return false;
        }
    }

## Diagram Editor Palette Icons

Developers can now specify up to two icons for a node or a connection to be used in a diagram editor's palette. Sapphire will choose an appropriate icon based on the palette's "Use Large Icons" setting.

    <tool-palette-image>DependsOn-16.png</tool-palette-image>
    <tool-palette-image>DependsOn-32.png</tool-palette-image>

Copyright (c) 2015 Oracle
Content made available under the terms of Eclipse Public License.