The prototype UI for faceted search configuration implemented in ACE-270 is backed by the QuADDS prototyping service to persist data to the Repository and we need to replace this with a dedicated service.
Mike Farman and I discussed this with Derek and the following requirements were drawn up...
- There needs to be an initial default configuration defined
- The default configuration needs to be overridden by a per-tenant configuration
We decided that one approach (that has previously been used successfully) would be to store the data in property files that are loaded from the classpath. We would declare the following 3 locations to search for files:
- Core repository classpath (e.g. tomcat/webapps/alfresco/WEB-INF/classes/alfresco)
- Repository extension classpath (e.g. tomcat/shared/classes/alfresco/extension)
- Data dictionary
We would create a default properties file that would be stored in the classpath but that could be overridden (e.g. via AMP) on the extenstion classpath and finally that could be customized via a file created and stored in the Data Dictionary via the REST API.
The REST API should support POST, PUT, DELETE and GET methods. It should both accept and return JSON.
The properties files would be dot-notations reflections of the JSON body where the first element is a value that represents membership of a specific list such that multiple lists of facets could be "blended".
The advantage of using the properties file approach is that we can use Spring to merge the multiple properties files together. Derek should be able to provide examples of where he has previously used this approach.
The "key" for each item should be the property QName (since it makes no sense to duplicate this). Data that we need to store is as follows:
- facet property qname (e.g. taken from the model)
- display name (this could either be an i18n key or just a string - Aikau will make an attempt to resolve strings as i18n keys and then fallback to the supplied value)
- display control (e.g. this would be the Aikau widget used)
- max results to display (default = 5)
- filter hit threshold (default = 1)
- min filter value size (default = 4)
- sort order (enumeration of "ALPHABETICAL", "ASCENDING", "DESCENDING" .... default = "DESCENDING")
- scope (enumeration of "ALL", "REPOSITORY", "ALL_SITES", "SCOPED_SITES", default = "ALL")
- scopedSites (an array of the sites to scope by, default - empty array)
The "index" attribute for each configured facet property should be updated by the REST API when it's returning the data so that each entry has a unique index starting from 0 (in increments of 1)... if two entries are configured with the same index (e.g. a facet defined in the root config is 0 but one defined in the web-extension config is also 0) then they should be sorted by some means so that one is "bumped" down to 1 so that whoever uses the service gets a sensible order. If the user then decides to re-order they will be manually overriding each index in the Data Dictionary configuration. E.g. it could be possible for the Data Dictionary config to define nothing but order.
We want to return data for facets as follows:
However, this would be stored as follows:
(In the above example, the qname would need to be escaped)
If this was stored as a file in the core repository classpath then a path in the web extension could change the sortBy fields and display name as follows:
It's only when the user uses the Faceted Search administration panel and makes some changes that we could then create a new properties file in the Data Dictionary.... e.g, the facet manager could then change the display name via the UI and the service would create a new properties file containing the following:
The root of the property "default" is a way in which we can order the "blending" of multiple lists to control overrides, for example.... say we had the following:
... and ...
...then we could set an order of merging such that if the order is "default,custom" then the displayName would be "MIME Type" and if it was "custom,default" then it would be "Format". We may not actually want to make use of this initially but we should not prevent ourselves expanding into this area in the future. Derek will hopefully be able to provide an example of where this is approach used.