# Migration Guide for Sapphire 8

This documents covers changes that need to be made by Sapphire adopters as part of migrating to Sapphire 8 from a prior release. Only changes from the previous major release are covered.

Table of Contents

1. DefaultValueService
2. DefaultValueServiceData
3. DerivedValueService
4. DerivedValueServiceData
5. EnablementService
6. EnablementServiceData
7. Filter
8. InitialValueService
9. InitialValueServiceData
10. ListenerContext
11. @Localizable
12. NoDuplicates
13. PossibleValues
14. PossibleValuesService
15. ReferenceService
16. ReferenceValue
17. StatusException

## DefaultValueService

Before | After
--- | ---

    org.eclipse.sapphire.services.DefaultValueService

    org.eclipse.sapphire.DefaultValueService

    public class ExampleDefaultValueService extends DefaultValueService
    {
        @Override
        protected DefaultValueServiceData compute()
        {
            return new DefaultValueServiceData( ... );
        }
    }

    public class ExampleDefaultValueService extends DefaultValueService
    {
        @Override
        protected String compute()
        {
            return ...;
        }
    }

## DefaultValueServiceData

This class has been removed. See DefaultValueService migration.

## DerivedValueService

Before | After
--- | ---

    org.eclipse.sapphire.services.DerivedValueService

    org.eclipse.sapphire.DerivedValueService

    public class ExampleDerivedValueService extends DerivedValueService
    {
        @Override
        protected DerivedValueServiceData compute()
        {
            return new DerivedValueServiceData( ... );
        }
    }

    public class ExampleDerivedValueService extends DerivedValueService
    {
        @Override
        protected String compute()
        {
            return ...;
        }
    }

## DerivedValueServiceData

This class has been removed. See DerivedValueService migration.

## EnablementService

Before | After
--- | ---

    org.eclipse.sapphire.services.EnablementService

    org.eclipse.sapphire.EnablementService

    public class ExampleEnablementService extends EnablementService
    {
        @Override
        protected EnablementServiceData compute()
        {
            return new EnablementServiceData( ... );
        }
    }

    public class ExampleEnablementService extends EnablementService
    {
        @Override
        protected Boolean compute()
        {
            return ...;
        }
    }

## EnablementServiceData

This class has been removed. See EnablementService migration.

## InitialValueService

Before | After
--- | ---

    org.eclipse.sapphire.services.InitialValueService

    org.eclipse.sapphire.InitialValueService

    public class ExampleInitialValueService extends InitialValueService
    {
        @Override
        protected InitialValueServiceData compute()
        {
            return new InitialValueServiceData( ... );
        }
    }

    public class ExampleInitialValueService extends InitialValueService
    {
        @Override
        protected String compute()
        {
            return ...;
        }
    }

## Filter

Before | After
--- | ---

    org.eclipse.sapphire.util.Filter

    org.eclipse.sapphire.Filter

    public class ExampleFilter extends Filter<Object>
    {
        ...
    }

    public class ExampleFilter implements Filter<Object>
    {
        ...
    }

## InitialValueServiceData

This class has been removed. See InitialValueService migration.

## ListenerContext

Before | After
--- | ---

    ListenerContext context = new ListenerContext();
    context.coordinate( another );

    ListenerContext context = new ListenerContext( another.queue() );

    context.suspend( ExampleEvent.class );

    try
    {
        ...
    }
    finally
    {
        context.resume( ExampleEvent.class );
    }

    final Disposable suspension = context.queue().suspend
    (
        new Filter<EventDeliveryJob>()
        {
            @Override
            public boolean allows( final EventDeliveryJob job )
            {
                return ! ( job.event() instanceof ExampleEvent );
            }
        }
    );

    try
    {
        ...
    }
    finally
    {
        suspension.dispose();
        context.queue().process();
    }

## @Localizable

This annotation is not longer available and no analog has been provided.

## NoDuplicates

Before | After
--- | ---

    org.eclipse.sapphire.modeling.annotations.NoDuplicates

    org.eclipse.sapphire.Unique

## PossibleValues

Before | After
--- | ---

    org.eclipse.sapphire.modeling.annotations.PossibleValues

    org.eclipse.sapphire.PossibleValues

    @PossibleValues
    (
        invalidValueMessage = "\"{0}\" is not a known entity"
    )

    @PossibleValues
    (
        invalidValueMessage = "\"${Entity}\" is not a known entity"
    )

The invalid value message must now be in Sapphire EL syntax, rather than in MessageFormat syntax.

    @PossibleValues( caseSensitive = false )

    @PossibleValues( ... )
    @Collation( ignoreCaseDifferences = "true" )

## PossibleValuesService

Before | After
--- | ---

    org.eclipse.sapphire.services.PossibleValuesService

    org.eclipse.sapphire.PossibleValuesService

    public class ExamplePossibleValuesService extends PossibleValuesService
    {
        @Override
        protected void init()
        {
            super.init();

            ...

            inside a listener
            {
                broadcast();
            }
        }
    }

    public class ExamplePossibleValuesService extends PossibleValuesService
    {
        @Override
        protected void initPossibleValuesService()
        {
            ...

            inside a listener
            {
                refresh();
            }
        }
    }

    public class ExamplePossibleValuesService extends PossibleValuesService
    {
        @Override
        protected void fillPossibleValues( Set<String> values )
        {
            ...
        }
    }

    public class ExamplePossibleValuesService extends PossibleValuesService
    {
        @Override
        protected void compute( Set<String> values )
        {
            ...
        }
    }

    public class ExamplePossibleValuesService extends PossibleValuesService
    {
        @Override
        public String getInvalidValueMessage( String value)
        {
            ...
        }

        @Override
        public Status.Severity getInvalidValueSeverity( String value )
        {
            ...
        }
    }

    public class ExamplePossibleValuesService extends PossibleValuesService
    {
        @Override
        public Status problem( Value<?> value )
        {
            ...
        }
    }

    public class ExamplePossibleValuesService extends PossibleValuesService
    {
        @Override
        public String getInvalidValueMessage( String value)
        {
            return MessageFormat.format( "\"{0}\" is not a known entity", value );
        }

        @Override
        public Status.Severity getInvalidValueSeverity( String value )
        {
            return Status.Severity.WARNING;
        }
    }

    public class ExamplePossibleValuesService extends PossibleValuesService
    {
        @Override
        protected void initPossibleValuesService()
        {
            this.invalidValueMessage = "\"${Entity}\" is not a known entity";
            this.invalidValueSeverity = Status.Severity.WARNING;
        }
    }

This simpler migration can be used in many cases where complex heuristics are not required. Note that the invalid value message must be in Sapphire EL syntax, rather than in MessageFormat syntax.

    public class ExamplePossibleValuesService extends PossibleValuesService
    {
        public ExamplePossibleValuesService()
        {
            super
            (
                "\"{0}\" is not a known entity",
                Status.Severity.WARNING,
                false /* caseSensitive */,
                true /* ordered */,
            );
        }
    }

    public class ExamplePossibleValuesService extends PossibleValuesService
    {
        @Override
        protected void initPossibleValuesService()
        {
            this.invalidValueMessage = "\"${Entity}\" is not a known entity";
            this.invalidValueSeverity = Status.Severity.WARNING;
            this.ordered = true;
        }
    }

    @Collation( ignoreCaseDifferences = "true" )

The invalid value message must now be in Sapphire EL syntax, rather than in MessageFormat syntax. Each of these properties has a default value, so typically only a subset needs to be set explicitly. Collation is now specified separately from the possible values, either through @Collation annotation or through CollationService.

    public class ExamplePossibleValuesService extends PossibleValuesService
    {
        @Override
        public boolean isCaseSensitive()
        {
            return false;
        }
    }

    public class ExamplePossibleValuesService extends PossibleValuesService
    {
        ...
    }

    @Collation( ignoreCaseDifferences = "true" )

Collation is now specified separately from the possible values, either through @Collation annotation or through CollationService.

## ReferenceService

Before | After
--- | ---

    public class ExampleReferenceService extends ReferenceService
    {
        @Override
        protected void init()
        {
            super.init();

            ...
        }

        @Override
        public Object resolve( final String reference )
        {
            ...
        }
    }

    public class ExampleReferenceService extends ReferenceService<ExampleEntity>
    {
        @Override
        protected void initReferenceService()
        {
            ...
        }

        @Override
        protected ExampleEntity compute()
        {
            final String reference = context( Value.class ).text();

            ...
        }
    }

## ReferenceValue

Before | After
--- | ---

    reference.resolve()

    reference.target()

## StatusException

This class is not longer available and no analog has been provided.

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