What is it?

LuciadLightspeed uses a mechanism similar to the java.util.ServiceLoader concept to expose certain services objects. The main distinction with the ServiceLoader concept is that the LuciadLightspeed services mechanism allows you to assign a priority.

It has two main usages:

Using all available instances

As a user of the LuciadLightspeed API, you can easily use all our implementations of an interface.

For example, if you need to decode a data source, you can use a composite ILcdModelDecoder implementation. That composite decoder contains model decoders for all supported formats. The Visualize SHP data on a Lightspeed map tutorial uses that mechanism to decode a SHP file.

Extending the product

As a user of the LuciadLightspeed API, you can plug in your own interface implementations. LuciadLightspeed will pick them up and use them, together with the standard implementations available in the product.

For example, our WMS server implementation uses this mechanism to pick up all available model decoders and layer factories. You can add support for your custom data format to our WMS server by creating a layer factory and model decoder, and registering them as service.

Using the available services

To obtain all the available services of a certain interface, you use the TLcdServiceLoader class.

For example, to obtain all available ILcdModelDecoder instances, you call:

//Create the service loader, and specify which services you want
TLcdServiceLoader<ILcdModelDecoder> serviceLoader =
    TLcdServiceLoader.getInstance(ILcdModelDecoder.class);
//The service loader provides an iterator over those instances
Iterator<ILcdModelDecoder> allAvailableModelDecoders = serviceLoader.iterator();

For the majority of the registered interfaces, there is a composite implementation available. See Services available by default for an overview. For the model decoders, this is the TLcdCompositeModelDecoder class:

ILcdModelDecoder modelDecoder =
    new TLcdCompositeModelDecoder(TLcdServiceLoader.getInstance(ILcdModelDecoder.class));

The composite implementation will internally loop over the services, so you don’t have to.

For example, you can use the composite model decoder to decode a SHP file. The composite implementation will internally loop over all available ILcdModelDecoder instances until it finds one that can decode the SHP file:

private static ILcdModel createSHPModel() throws IOException {
  // This composite decoder can decode all supported formats
  ILcdModelDecoder decoder =
      new TLcdCompositeModelDecoder(TLcdServiceLoader.getInstance(ILcdModelDecoder.class));

  // Decode city_125.shp to create an ILcdModel
  ILcdModel shpModel = decoder.decode("Data/Shp/Usa/city_125.shp");

  return shpModel;
}

These snippets only work from your IDE if you annotation processing has been activated.

See the Installation documentation for more details on how to set up your IDE, and the Fixing service registry errors article for specific tips related to annotation processing.

Registering your own instances

You can register your own implementations of an interface using the @LcdService annotation. You must add the annotation to your class, and specify for which interface you are registering the service.

For example, to register a new ILcdGXYLayerFactory, you use:

@LcdService(service = ILcdGXYLayerFactory.class)
public static class CustomLayerFactory implements ILcdGXYLayerFactory {

Classes that you annotate as service must have a default, no-argument constructor.

If you want your custom instance to get priority over already existing instances, set the priority in the annotation:

@LcdService(service = ILcdGXYLayerFactory.class, priority = LcdService.HIGH_PRIORITY)
public static class CustomLayerFactoryWithPriority implements ILcdGXYLayerFactory {

You can use any integer for the priority. The LcdService annotation contains a few pre-defined values, but you are free to choose any integer.

Services available by default

The available services are listed in the table below.

The Register your own instances column indicates:

  • Yes, if LuciadLightspeed or the LuciadFusion server queries the service registry for service instances you registered yourself.

    In that case, the Example usage column contains a brief description of an example scenario where the instance you registered is automatically picked up and used.

  • No, if LuciadLightspeed or the LuciadFusion server does not query the service registry for service instances you registered yourself. Registering your own instance has no effect, unless you query the service registry for those instances yourself.

    In that case, the Example usage column contains a brief description of how you can use the services in the registry.

Interface Composite implementation Register your own instances Example usage

ILcdModelDecoder

TLcdCompositeModelDecoder

Yes

The standard WMS server uses your custom decoding services to decode your own data formats.

ILcdModelEncoder

Not available

No

You can save the data of an ILcdModel to a file using the available model encoders.

ILcdGXYLayerFactory

TLcdCompositeGXYLayerFactory

Yes

The standard WMS server uses the available layer factories to visualize the decoded data.

ILspLayerFactory

TLspCompositeLayerFactory

No

You can create a Lightspeed layer for a model.

ILcdModelMeasureProviderFactory

Not available

No

You can create a mouse readout that shows the measurement value under the cursor.

ILcdLayerMeasureProviderFactory

Not available

No

You can create a mouse readout that shows the measurement value under the cursor.

ILcdInputStreamFactory

TLcdCompositeInputStreamFactory

Yes

Add support for custom input stream sources. The majority of the ILcdModelDecoder implementations use the available ILcdInputStreamFactory instances when they need to access the data.

ILcdModelReferenceDecoder

TLcdCompositeModelReferenceDecoder

Yes

Add support for custom model reference files. The majority of the ILcdModelDecoder implementations use the available ILcdModelReferenceDecoder instances when they need to decode an external model reference file.

ILcdModelReferenceEncoder

TLcdCompositeModelReferenceEncoder

Yes

Add support to store model references to a custom format, or to store custom model references. The majority of the ILcdModelEncoder implementations use the available ILcdModelReferenceEncoder instances when they need to store the model reference to an external file.

ILcdSLDGXYLayerFactory

Not available

Yes

The standard WMS server uses these registered services to visualize the decoded data and style it using SLD.

ILcdGXYViewEncoder

Not available

Yes

The standard WMS server uses these registered services to convert the GXY view to an image that be sent to the client.

ILcdBalloonContentProvider

Not available

Yes

The Swing balloon managers use these registered services to provide the balloon contents.

ILcdFXBalloonContentProvider

Not available

Yes

The JavaFX balloon manager uses these registered services to provide the balloon contents.

ILcdWMSGetFeatureInfoRequestEncoder

Not available

Yes

The standard WMS server uses these registered services to encode the requested information when a WMS client performs a GetFeatureInfo request.

ILcdLoggerFactory

Not available

Yes

You can use a different logging framework. For example, LuciadFusion uses this class to register its own logging framework. For more information, see the documentation of the TLcdLoggerFactory class.

ILcdStringTranslator

TLcdCompositeStringTranslator

Yes

You can provide your own translator which may use your own internationalization mechanism.

ILcdWMSGetLegendGraphicRequestEncoder

Not available

Yes

The standard WMS server uses the available legend graphic encoders to generate a legend for the decoded data.

ILcdWMTSGetLegendGraphicRequestEncoder

Not available

Yes

The standard WMTS server uses the available legend graphic encoders to generate a legend for the decoded data.

ILcdMetadataDecoder

TLcdCompositeMetadataDecoder

Yes

Add support for custom metadata parsers. LuciadFusion searches for an appropriate parser to create the metadata of crawled data files.

The table does not describe all possible use cases for these service objects. It provides a brief description of a single use case per service object.