# Enhancements in Sapphire 0.7.1

1. Core

1. Custom Collation
2. Element Enhancements
3. Observable Collections

2. Expression Language

1. Replace Function
2. EncodeToXml Function
3. Global Function

3. Forms

1. SapphireWizard Enhancements

4. SDK

1. Logical Structure in the Debugger

## Custom Collation

The developer can now specify a custom collation for a list index, such a collation that ignores letter case differences.

    ElementList
    {
        Index<T> index( ValueProperty property )
        Index<T> index( ValueProperty property, Comparator<String> comparator )
        Index<T> index( String property )
        Index<T> index( String property, Comparator<String> comparator )
    }

The new @Collation annotation can be used to specify collation for a property. The specified collation is leveraged by various parts of the framework, such as the NoDuplicates annotation. The @Collation annotation supports Sapphire EL.

    @NoDuplicates
    @Collation( ignoreCaseDifferences = "true" )

    ValueProperty PROP_NAME = new ValueProperty( TYPE, "Name" );

    Value<String> getName();
    void setName( String value );

When more control is necessary, a custom implementation of CollationService can be provided.

    @NoDuplicates
    @Service( impl = ExampleCollationService.class )

    ValueProperty PROP_NAME = new ValueProperty( TYPE, "Name" );

    Value<String> getName();
    void setName( String value );

    public class ExampleCollationService extends CollationService
    {
        @Override
        protected Comparator<String> compute()
        {
            return new Comparator<String>()
            {
                public int compare( final String a, final String b )
                {
                    ...
                }
            };
        }
    }

## Element Enhancements

Determine if an element is empty using the new method. An element is empty when all of its properties are empty.

    Element
    {
        public boolean empty()
    }

Find all non-empty properties in an element using the new method.

    Element
    {
        public SortedSet<Property> content()
    }

## Observable Collections

Create collections that can be monitored for changes. An Observable wrapper is provided for List, Set and Map.

    ObservableMap<String,String> map = new ObservableMap<String,String>();

    Listener listener = new Listener()
    {
        public void handle( final Event event )
        {
            ...
        }
    };

    map.attach( listener );

    ...

    map.detach( listener );

## Replace Function

Replaces all occurrences of a regular expression pattern with the provided replacement text. The full semantics are specified by Java's String.replaceAll( String, String ) function.

    ${ Message.Replace( "\n", "<br/>" ) }

    ${ Message.Replace( "[0-9]", "x" ) }

## EncodeToXml Function

Encodes a string for use as XML element content or an attribute value.

    ${ Message.EncodeToXml }

## Global Function

Returns a map of global objects maintained through Sapphire.global() API.

    Sapphire.global().put( "User", "John" );

    ${ Global.User }

## SapphireWizard Enhancements

When the finish operation of a SapphireWizard fails with an error status, a dialog is opened showing the failure message. In some cases, customization of the failure handling behavior is desired.

    SapphireWizard
    {
        protected boolean handleFinishFailure( Status status )
    }

Certain use cases require access to the corresponding part from a SapphireWizard instance.

    SapphireWizard
    {
        public WizardPart part()
    }

## Logical Structure in the Debugger

Examining a model in a debug session is difficult as the logical structure is hidden among complex implementation details. A debugger extension is now provided to show the logical structure of elements and properties.

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