Vocabulary
The Vocabulary module for Concerto optionally allows human-readable labels (Terms) to be associated with model elements. Terms are stored within a locale specific vocabulary YAML file associated with a Concerto namespace.
For example, a Concerto model that defines an enumeration with the values RED
, GREEN
, BLUE
can be associated with an English vocabulary with the terms "Red", "Green", "Blue" and a French Vocabulary with terms "Rouge", "Vert", "Bleue".
The VocabularyManager
class manages access to a set of Vocabulary files, and includes logic to retrieve the most appropriate term for a requested locale.
Example Model
namespace org.acme
enum Color {
o RED
o BLUE
o GREEN
}
asset Vehicle identified by vin {
o String vin
o Color color
}
asset Truck extends Vehicle {
o Double weight
}
Example Vocabulary Files
English - en
locale: en
namespace: org.acme
declarations:
- Color: A color
- Vehicle: A road vehicle
properties:
- vin: Vehicle Identification Number
- model: Model of the vehicle
- Truck: A vehicle capable of carrying cargo
properties:
- weight: The weight of the truck in KG
British English - en-gb
locale: en-gb
namespace: org.acme
declarations:
- Truck: A lorry (a vehicle capable of carrying cargo)
- Color: A colour
- Milkfloat
French - fr
locale: fr
namespace: org.acme
declarations:
- Vehicle: Véhicule
properties:
- vin: Le numéro d'identification du véhicule (NIV)
Simplified Chinese zh-cn
locale: zh-cn
namespace: org.acme
declarations:
- Color: 颜色
properties:
- RED: 红色
- GREEN: 绿色
- BLUE: 蓝色
- Vehicle: 车辆
properties:
- vin: 车辆识别代号
- color: 颜色
As you can see in the vocabularies above, a vocabulary can supplement or override terms from a base vocabulary, as is the case of the en-gb
vocabulary which redefines and adds terms specific to British English over the generic English en
vocabulary.
Creating a boostrap Vocabulary file
Use the following command to generate a bootstrap Vocabulary file in English Language. This file will give a boilerplate format for the Vocabulary YAML file. This file can be edited to any description that is required or any language that is required.
concerto compile --model test.cto --target vocabulary
Please refer to Vocabulary Code Generation for more information.
API Usage
Use the VocabularyManager
classs to define new vocabularies, retrieve terms for a locale, or to validate
a vocabulary using a ModelManager
.
Adding a Vocabulary
Load the YAML file for the Vocabulary and add it to a VocabularyManager
:
vocabularyManager = new VocabularyManager();
const enVocString = fs.readFileSync('./test/org.acme_en.voc', 'utf-8');
vocabularyManager.addVocabulary(enVocString);
Retrieving a Term
Use the getTerm
method on the VocabularyManager
to retrieve a term for
a declaration or property within a namespace:
const term = vocabularyManager.getTerm('org.acme', 'en-gb', 'Color');
// term.should.equal('A colour');
const term = vocabularyManager.getTerm('org.acme', 'en-gb', 'Vehicle', 'vin');
// term.should.equal('Vehicle Identification Number');
Resolve a Term using ModelManager Type Hierarchy
The resolveTerm
method on the VocabularyManager
may be used to lookup a term
based on the type hierarchy defined by a ModelManager
. In the example below, the property
vin
is not defined on the Truck
declaration but rather on the Vehicle
super-type.
modelManager = new ModelManager();
const model = fs.readFileSync('./test/org.acme.cto', 'utf-8');
modelManager.addModelFile(model);
const term = vocabularyManager.resolveTerm(modelManager, 'org.acme', 'en-gb', 'Truck', 'vin');
// term.should.equal('Vehicle Identification Number');
Validating a Vocabulary Manager
Use the validate
method on the VocabularyManager
to detect missing and redudant vocabulary
terms — comparing the terms in the VocabularyManager
with the declarations in a ModelManager
.
The return value from validate
is an object containing information for the missing and additional terms.
Note that allowing vocabularies to evolve independently of their associated namespace provides definition and translation workflow flexibility.
const result = vocabularyManager.validate(modelManager);
// result.missingVocabularies.length.should.equal(1);
// result.missingVocabularies[0].should.equal('org.accordproject');
// result.additionalVocabularies.length.should.equal(1);
// result.additionalVocabularies[0].getNamespace().should.equal('com.example');
// result.vocabularies['org.acme/en'].additionalTerms.should.have.members(['Vehicle.model']);
// result.vocabularies['org.acme/en'].missingTerms.should.have.members(['Color.RED', 'Color.BLUE', 'Color.GREEN', 'Vehicle.color']);
// result.vocabularies['org.acme/en-gb'].additionalTerms.should.have.members(['Milkfloat']);
// result.vocabularies['org.acme/fr'].missingTerms.should.have.members(['Color', 'Vehicle.color', 'Truck']);
// result.vocabularies['org.acme/fr'].additionalTerms.should.have.members([]);
// result.vocabularies['org.acme/zh-cn'].missingTerms.should.have.members(['Truck']);
// result.vocabularies['org.acme/zh-cn'].additionalTerms.should.have.members([]);
Please refer to the JavaScript API for the concerto-vocabulary
module for detailed API guidance.