Changes
→ServiceResponse data and generation
==ServiceResponse data and generation==
===ServiceResponse and related data structures===
Before talking about how the services generate data, we should talk about the data format of a [http://umlaut.rubyforge.org/api/classes/ServiceResponse.html ServiceResponse]. A ServiceResponse is basically a unit of information generated by a Service, generally for display somewhere on the link resolver menu page. For example, there might be a ServiceResponse representing a fulltext link, a help link, or an abstract. ServiceResponses almost always link out somewhere, along with providing other data for display.
The ServiceResponse entity has a few 'standard' properties (display_text, url, notes), but also a property, service_data, consisting of a serialized hash for holding arbitrary key/value information. Different service types might require different key/values here. The [] operator on ServiceResponse conveniently allows you to store arbitrary key/value information in this property (and also access/set the 'built-in' properties). For appropriately loose coupling between data stored, service generating it, and view, we define some conventions for what key/value pairs are used for what purposes in each response type, in comments on [http://umlaut.rubyforge.org/api/classes/ServiceResponse.html ServiceResponse class definition]. A ServiceResponse also records which Service generated it, using that Service's service_id/name as defined in config/umlaut_config/services.yml, and generally retrievable from the ServiceList.
So what do we mean by a 'service type'? The list of all valid service types is defined in the ServiceTypeValue table. Each ServiceTypeValue has a one-word internal identifier token (name), a display_name for user presentation, and optionally a display_name_pluralized (to over-ride standard Rails pluralization). The values in this table are initialized from db/orig_fixed_data/service_type_values.yml when you run rake umlautdb:load_initial_data. We intend the local implementer to be able to create locally defined ServiceTypeValues too, if necessary. ServiceTypeValue uses the acts_as_enumerated plug-in to conveniently allow the developer to refer to an individual ServiceTypeValue by name: ServiceTypeValue[:fulltext] ==> the ServiceTypeValue object with name == 'fulltext'. acts_as_plugin does efficient caching.
So obviously a ServiceResponse object needs to be registered to
This data structure is somewhat confusing, but there are usually convenience methods defined to avoid the complexity; they should be used. See for example (tbd).
===Obligations of Service logic===
What you need to know to write a new Service.
Avoid stateful-ness, object is re-used accross requests, and due to possible multi-threaded implementation, may even be used concurrently, so write thread-safe. Or avoid state altogether.