Sapphire Developer Guide

Services

Many aspects of Sapphire can be extended by third parties.

DependenciesAggregationService

The DependenciesAggregationService combines the data from all applicable dependencies services in order to produce a single set of dependencies. A dependency is a model paths that points to parts of the model that the property depends on. A property listens on all of its dependencies and triggers refresh when any of the dependencies change.

An implementation of this service is provided with Sapphire. This service is not intended to be implemented by adopters. See DependenciesService instead.

DependenciesService

The DependenciesService produces the set of model paths that point to parts of the model that the property depends on. A property listens on all of its dependencies and triggers refresh when any of the dependencies change.

Although custom implementations are supported, in most cases the supplied implementation that is configured via @DependsOn annotation should be sufficient.

Example

@DependsOn( "Name" )

ValueProperty PROP_ID = new ValueProperty( TYPE, "Id" );

Value<String> getId();
void setId( String value );

Other annotations, such as @NoDuplicates can also inject implied dependencies (via their own DependenciesService implementations). For instance, placing @NoDuplicates annotation on a Name property automatically adds "#/Name" dependency.

If declarative approach is not sufficient, a custom DependenciesService implementation can be supplied.

Example

public class CustomDependenciesService extends DependenciesService
{
    @Override
    protected void compute( Set<ModelPath> dependencies )
    {
        // Compute the list of extensions.
    }
}
@Service( impl = CustomDependenciesService.class )

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

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

FileExtensionsService

The FileExtensionsService produces the list of file extensions that are allowed for a path value property.

Although custom implementations are supported, in most cases the supplied implementation that is configured via @FileExtensions annotation should be sufficient. In many cases, specifying file extensions is as simple as listing them with a comma in between.

Example

@Type( base = Path.class )
@AbsolutePath
@MustExist
@ValidFileSystemResourceType( FileSystemResourceType.FILE )
@FileExtensions( expr = "jar,zip" )

ValueProperty PROP_FILE_PATH = new ValueProperty( TYPE, "FilePath" );

Value<Path> getFilePath();
void setFilePath( String value );
void setFilePath( Path value );

File extensions can also be specified via an expression that takes into account values of other properties.

Examples

@FileExtensions( expr = "${ Extension }" )
@FileExtensions( expr = "${ LossyFormat ? "jpeg,jpg" : "png,gif" }" )

If declarative approach is not sufficient, a custom FileExtensionsService implementation can be supplied.

Example

public class CustomFileExtensionsService extends FileExtensionsService
{
    @Override
    public void initFileExtensionsService( IModelElement element,
                                           ModelProperty property,
                                           String[] params )
    {
        // Optionally register listeners to invoke refresh method when the list of extensions
        // may need to be updated.
    }

    @Override
    protected void compute( List<String> extensions )
    {
        // Compute the list of extensions.
    }

    @Override
    public void dispose()
    {
        super.dispose();

        // Remove any listeners that were added during initialization.
    }
}
@Type( base = Path.class )
@AbsolutePath
@MustExist
@ValidFileSystemResourceType( FileSystemResourceType.FILE )
@Service( impl = CustomFileExtensionsService.class )

ValueProperty PROP_FILE_PATH = new ValueProperty( TYPE, "FilePath" );

Value<Path> getFilePath();
void setFilePath( String value );
void setFilePath( Path value );