EnviroCar Service

Developer Guide

API Reference

Linked Open Data

Additional encodings for tracks

Developer Guide

Build & Installation

Guice

The service makes heavy use of Guice. Implementations are bound in a Module. For a detailed documentation see the Guice Wiki. The service loads available module using the Java ServiceLoader API.

public class CoreModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(DataService.class).to(DataServiceImpl.class);
        bind(UserService.class).to(UserServiceImpl.class);
        bind(FriendService.class).to(FriendServiceImpl.class);
        bind(GroupService.class).to(GroupServiceImpl.class);
        bind(StatisticsService.class).to(StatisticsServiceImpl.class);
        bind(ActivityListener.class).asEagerSingleton();
        bind(PasswordEncoder.class).to(BCryptPasswordEncoder.class);
        DateTimeZone.setDefault(DateTimeZone.UTC);
    }
}

Event Bus

The service offers an extension API using a Guava EventBus. The following events are accessible for extensions:

To subscribe to an event type you have to annotate some method with @Subscribe. The parameter type determines the type of event:

public class SomeListener {
    private final DataService service;

    @Inject
    public SomeListener(DataService service) {
        this.service = service;
    }

    @Subscribe
    public void onCreatedTrackEvent(CreatedTrackEvent e) {
        doSomething(e.getUser(), service.getMeasurements(
            new MeasurementFilter(e.getTrack())));
    }
}

A class that wants to receive events has to be created by Guice. For this you could declare it as a eager singleton in any module:

bind(SomeListener.class).asEagerSingleton();

RDF API

Additional resources can be linked by implementing the interface RDFLinker<T> for the entity type T:

import javax.ws.rs.core.UriBuilder;
import org.envirocar.server.rest.rights.AccessRights;
import com.google.inject.Provider;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Resource;

public interface RDFLinker<T> {
    void link(Model m, T t, AccessRights rights,
              Resource r, Provider<UriBuilder> uriBuilder);
}

The additional triples have to be added to the Model m. URIs to other entities can be build using the supplied UriBuilder. The rights of the current user to see properties and entities can be obtained using the AccessRights object. The following example adds latitude and longitude to a point measurement using the W3C Basic Geo vocabulary:

import javax.ws.rs.core.UriBuilder;
import org.envirocar.server.core.entities.Measurement;
import org.envirocar.server.rest.encoding.rdf.RDFLinker;
import org.envirocar.server.rest.encoding.rdf.vocab.W3CGeo;
import org.envirocar.server.rest.rights.AccessRights;
import com.google.inject.Provider;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Resource;
import com.vividsolutions.jts.geom.Point;

public class W3CGeoMeasurementLinker implements RDFLinker<Measurement> {
    @Override
    public void link(Model m, Measurement t, AccessRights rights,
                     Resource r, Provider<UriBuilder> uriBuilder) {
        if (t.getGeometry() instanceof Point) {
            m.setNsPrefix(W3CGeo.PREFIX, W3CGeo.URI);
            Point p = (Point) t.getGeometry();
            r.addLiteral(W3CGeo.lat, p.getY())
             .addLiteral(W3CGeo.lon, p.getX());
        }
    }
}

To let the service automatically faciliate the linker it has to be bound in any Guice module:

Multibinder<RDFLinker<Measurement>> b = Multibinder.newSetBinder(
        binder(), new TypeLiteral<RDFLinker<Measurement>>() {});
b.addBinding().to(W3CGeoMeasurementLinker.class);