# 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.