Erland Isaksson edited this page Dec 31, 2015 · 1 revision


The project consists of:

  • The domain model implemented as Java with JPA annotations, currently the core model is complete while the subjective/classification model still misses some stuff
  • Some unit test cases, both for managing functionality and for query functionality
  • H2 is used as database, the unit test uses a in-memory version of H2 so they doesn't store anything on the disk
  • When building it also produces a target/hibernate3/sql/schema.sql which contains the schema if you like to look at it separately.

The project also builds a smd-server-1.0-SNAPSHOT.jar which can be executed as: java -jar smd-sserver-1.0-SNAPSHOT.jar

This jar file bundles H2 and creates an empty database persisted in a "smd-database" file when launched the first time. To fill the database, launch the Apache Pivot based SMD Frontend and perform an import from Squeezebox Server.


The smd-server module can be configured through a configuration file called which will be loaded either from the current directory or from the classpath. If it doesn't exist, the default configuration will be loaded from the bundled file.

Some sample properties are:

  • org.socialmusicdiscovery.server.database (default: h2)

  • (default: localhost)

    • Hostname where SBS is installed, this is used by the import module when retrieving data from SBS and also by the mysql-sbs database provider option.
  • squeezeboxserver.port (default: 9000)

    • Port which SBS web interface is using
  • org.socialmusicdiscovery.server.port (default: 9998)

    • Port which SMD Server uses to offer interfaces to its clients

You only need to specify the properties you like to override, so if you for example are running SBS on a separate machine (mynas) you can have a file that looks like:

The properties can also be overriden by specifying them as a -D JVM parameter when launching the application.

SMD Server Database

The SMD Server database is documented on a separate page (follow this link)

Design Choices

These design choices are preliminary, so don't consider them final.

  • We are now using UUID's as primary keys and we have also added a new SMDEntityReference entity that contains the unique key for all entities and a second column with the type of entity a specific key represent.

  • There are some very preliminary representation of some of the subjective entities. In the database some of them are represented with an intermediate table to ensure that the subjective entities doesn't have to add column to the core entities.

  • There is a repository/dao class for each entity to encapsulate JPA a bit from the other business logic and also separate the data access from everything else.

  • Google Guice is used to have support for injections even if we don't execute in a J2EE application server. It's currently used to inject JPA EntityController and the new Repository classes in the right places without having to use some service locator or similar solution.

  • There is a HTTP JSON interface for the management api, currently it's only implemented as two CRUD's, on for Artist and one for Person. It should be fairly simple to offer a XML version of the same API if we like to.

  • The JSON api is implemented using Jersey the JAX-RS reference implementation from Sun/Oracle and it's driven by the Grizzly embedded HTTP server. We haven't decided yet if we want a full blown web or even J2EE server or if we should use something embedded like Grizzly.

  • The JSON conversion is handled by Google Gson by implementing a custom Jersey MessageBodyReader/MessageBodyWriter. The reason to use Google Gson instead of the built-in support in Jersey is to make it control what's serialized and not serialized.

  • All extras are implemented as plugins which implements a defined plugin interface, plugins will be called to startup in the beginning and shutdown at the end.

  • ANTLR is used to implement a flexible title format language which make it possible to convert any object structure to a text that should be displayed based on a formatting string.

  • All unit test cases which requires database access is using a memory based database which will be loaded with data from by using DbUnit.

Browse menus

There are a number of different types of browse interfaces which are supported by the server.

  • The management interface

Allows some browsing but the focus is to retrieve an individual entity instance which should be managed. See SoftwareSMDServerManagementAPI for more information about this.

  • The flexible browse interface

Allows flexible browsing to browse all objects in any order and any hierarchy level. The server doesn't offer a predefined structure, instead it's the responsibility of the client to limit which hierarchies/objects to show. The client will typically specify either to: * Get a list of available child types under a specific object * Get a list of all childs of a specific type under a specific object See the separate description of this interface for more information and sample usage.

  • Server defined browse structure

A fixed browse structure is defined on the server side and the client will be able to browse into an object and get a list of its childs. The type of childs under a specific object is defined on the server side. For more information about this interface, see the separate page dedicated to it

  • UPnP interface

A UPnP interface which makes it possible for a generic UPnP client to connect and browse the menus provided by the "Server defined browse structure" described above. For more information regarding the UPnP interface, see its separate description

Relations between Core and Subjective model

Below follows a sample of some of the database tables to represent the subjective entity classification(genres/tags) and it's relation to to the core entities artists and releases. As you probably can see there is no direct relation between artists/releases and classification, instead their relations goes through the smdentity_references table which ensures consistency and also ensures that classification entries can be tied to any core entity without modifying the database. We might of course limit this a little bit in the application layer or in the user interface but there is no limitation in the database.

In core model:

    create table artists (
        id varchar(36) not null,
        name varchar(255) not null,
        person_id varchar(36),
        alias_artist_id varchar(36),
        primary key (id)

    create table releases (
        id varchar(36) not null,
        date timestamp,
        name varchar(255) not null,
        label_id varchar(36),
        primary key (id)

    create table smdentity_references (
        id varchar(36) not null,
        type varchar(255) not null,
        primary key (id)

And in subjective model:

    create table classification_references (
        classification_id varchar(36) not null,
        reference_id varchar(36) not null,
        unique (reference_id)

    create table classifications (
        id varchar(36) not null,
        name varchar(255),
        type varchar(255) not null,
        parent_id varchar(36),
        primary key (id)

The relevant constraints looks like this:

    alter table artists 
        add constraint FKD4590A0CDE6F986D 
        foreign key (id) 
        references smdentity_references;

    alter table releases 
        add constraint FKDF23D94CDE6F986D 
        foreign key (id) 
        references smdentity_references;

    alter table classification_references 
        add constraint FK87ED808174C9DB6E 
        foreign key (classification_id) 
        references classifications;

    alter table classification_references 
        add constraint FK87ED8081C07B75E1 
        foreign key (reference_id) 
        references smdentity_references;

    alter table classifications 
        add constraint FKC27C494DDE6F986D 
        foreign key (id) 
        references smdentity_references;

    alter table classifications 
        add constraint FKC27C494DDBA1A02A 
        foreign key (parent_id) 
        references classifications;

In the Java code all this is represented by four Java objects:

And the subjective part in:

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.