blob: 4a2df93cf389bafcd602524a6a990acddca86ede [file] [log] [blame]
/*
* Copyright (c) 2016 Gigatronik Ingolstadt GmbH and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.mdm.api.odsadapter.query;
import static java.util.stream.Collectors.groupingBy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Stream;
import org.asam.ods.AIDName;
import org.asam.ods.AggrFunc;
import org.asam.ods.AoException;
import org.asam.ods.AoSession;
import org.asam.ods.ApplElem;
import org.asam.ods.ApplElemAccess;
import org.asam.ods.ApplRel;
import org.asam.ods.ApplicationStructure;
import org.asam.ods.ApplicationStructureValue;
import org.asam.ods.ElemResultSetExt;
import org.asam.ods.EnumerationAttributeStructure;
import org.asam.ods.EnumerationDefinition;
import org.asam.ods.JoinDef;
import org.asam.ods.QueryStructureExt;
import org.asam.ods.SelAIDNameUnitId;
import org.asam.ods.SelItem;
import org.asam.ods.SelOrder;
import org.asam.ods.T_LONGLONG;
import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.adapter.ModelManager;
import org.eclipse.mdm.api.base.adapter.Relation;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ChannelGroup;
import org.eclipse.mdm.api.base.model.ContextComponent;
import org.eclipse.mdm.api.base.model.ContextRoot;
import org.eclipse.mdm.api.base.model.ContextSensor;
import org.eclipse.mdm.api.base.model.ContextType;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.EnumRegistry;
import org.eclipse.mdm.api.base.model.Enumeration;
import org.eclipse.mdm.api.base.model.Environment;
import org.eclipse.mdm.api.base.model.Measurement;
import org.eclipse.mdm.api.base.model.Parameter;
import org.eclipse.mdm.api.base.model.ParameterSet;
import org.eclipse.mdm.api.base.model.PhysicalDimension;
import org.eclipse.mdm.api.base.model.Quantity;
import org.eclipse.mdm.api.base.model.Sortable;
import org.eclipse.mdm.api.base.model.Test;
import org.eclipse.mdm.api.base.model.TestStep;
import org.eclipse.mdm.api.base.model.Unit;
import org.eclipse.mdm.api.base.model.User;
import org.eclipse.mdm.api.dflt.model.CatalogAttribute;
import org.eclipse.mdm.api.dflt.model.CatalogComponent;
import org.eclipse.mdm.api.dflt.model.CatalogSensor;
import org.eclipse.mdm.api.dflt.model.Pool;
import org.eclipse.mdm.api.dflt.model.Project;
import org.eclipse.mdm.api.dflt.model.TemplateAttribute;
import org.eclipse.mdm.api.dflt.model.TemplateComponent;
import org.eclipse.mdm.api.dflt.model.TemplateRoot;
import org.eclipse.mdm.api.dflt.model.TemplateSensor;
import org.eclipse.mdm.api.dflt.model.TemplateTest;
import org.eclipse.mdm.api.dflt.model.TemplateTestStep;
import org.eclipse.mdm.api.dflt.model.TemplateTestStepUsage;
import org.eclipse.mdm.api.dflt.model.ValueList;
import org.eclipse.mdm.api.dflt.model.ValueListValue;
import org.eclipse.mdm.api.dflt.model.Versionable;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig.Key;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfigRepository;
import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;
import org.eclipse.mdm.api.odsadapter.utils.ODSEnum;
import org.eclipse.mdm.api.odsadapter.utils.ODSEnumerations;
import org.eclipse.mdm.api.odsadapter.utils.ODSUtils;
import org.omg.CORBA.ORB;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* ODS implementation of the {@link ModelManager} interface.
*
* @since 1.0.0
* @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
*/
public class ODSModelManager implements ModelManager {
private static final Logger LOGGER = LoggerFactory.getLogger(ODSModelManager.class);
private final Map<String, EntityType> entityTypesByName = new HashMap<>();
private final ORB orb;
private final Lock write;
private final Lock read;
private EntityConfigRepository entityConfigRepository;
private ApplElemAccess applElemAccess;
private AoSession aoSession;
/**
* Constructor.
*
* @param orb
* Used to activate CORBA service objects.
* @param aoSession
* The underlying ODS session.
* @throws AoException
* Thrown on errors.
*/
public ODSModelManager(ORB orb, AoSession aoSession) throws AoException {
this.aoSession = aoSession;
this.orb = orb;
applElemAccess = aoSession.getApplElemAccess();
// setup locks
ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
write = reentrantReadWriteLock.writeLock();
read = reentrantReadWriteLock.readLock();
initialize();
}
/**
* Returns the {@link ORB}.
*
* @return The {@code ORB} is returned.
*/
public ORB getORB() {
return orb;
}
/**
* Returns the non root {@link EntityConfig} for given {@link Key}.
*
* @param <T>
* The concrete entity type.
* @param key
* Used as identifier.
* @return The non root {@code EntityConfig} is returned.
*/
public <T extends Entity> EntityConfig<T> findEntityConfig(Key<T> key) {
read.lock();
try {
return entityConfigRepository.find(key);
} finally {
read.unlock();
}
}
/**
* Returns the root {@link EntityConfig} for given {@link Key}.
*
* @param <T>
* The concrete entity type.
* @param key
* Used as identifier.
* @return The root {@code EntityConfig} is returned.
*/
public <T extends Entity> EntityConfig<T> getEntityConfig(Key<T> key) {
read.lock();
try {
return entityConfigRepository.findRoot(key);
} finally {
read.unlock();
}
}
/**
* Returns the {@link EntityConfig} associated with given
* {@link EntityType}.
*
* @param entityType
* Used as identifier.
* @return The {@code EntityConfig} is returned.
*/
public EntityConfig<?> getEntityConfig(EntityType entityType) {
read.lock();
try {
return entityConfigRepository.find(entityType);
} finally {
read.unlock();
}
}
/**
* {@inheritDoc}
*/
@Override
public List<EntityType> listEntityTypes() {
read.lock();
try {
return Collections.unmodifiableList(new ArrayList<>(entityTypesByName.values()));
} finally {
read.unlock();
}
}
/**
* {@inheritDoc}
*/
@Override
public EntityType getEntityType(Class<? extends Entity> entityClass) {
read.lock();
try {
return getEntityConfig(new Key<>(entityClass)).getEntityType();
} finally {
read.unlock();
}
}
/**
* {@inheritDoc}
*/
@Override
public EntityType getEntityType(Class<? extends Entity> entityClass, ContextType contextType) {
read.lock();
try {
return getEntityConfig(new Key<>(entityClass, contextType)).getEntityType();
} finally {
read.unlock();
}
}
/**
* {@inheritDoc}
*/
@Override
public EntityType getEntityType(String name) {
read.lock();
try {
EntityType entityType = entityTypesByName.get(name);
if (entityType == null) {
throw new IllegalArgumentException("Entity with name '" + name + "' not found.");
}
return entityType;
} finally {
read.unlock();
}
}
@Override
public EntityType getEntityTypeById(String id) {
Optional<EntityType> entityType = listEntityTypes().stream().filter(et -> et.getId().equals(id)).findFirst();
if (!entityType.isPresent()) {
throw new IllegalArgumentException("Entity with id '" + id + "' not found.");
}
return entityType.get();
}
/**
* Returns the {@link AoSession} of this model manager.
*
* @return The {@code AoSession} is returned.
*/
public AoSession getAoSession() {
write.lock();
try {
return aoSession;
} finally {
write.unlock();
}
}
/**
* Returns the {@link ApplElemAccess} of this model manager.
*
* @return The {@code ApplElemAccess} is returned.
*/
public ApplElemAccess getApplElemAccess() {
read.lock();
try {
return applElemAccess;
} finally {
read.unlock();
}
}
/**
* Closes the ODS connection.
*
* @throws AoException
* Thrown on errors.
*/
public void close() throws AoException {
read.lock();
try {
applElemAccess._release();
aoSession.close();
} finally {
read.unlock();
aoSession._release();
}
}
/**
* Reloads the complete session context.
*/
public void reloadApplicationModel() {
write.lock();
AoSession aoSessionOld = aoSession;
ApplElemAccess applElemAccessOld = applElemAccess;
try {
entityTypesByName.clear();
aoSession = aoSession.createCoSession();
applElemAccess = aoSession.getApplElemAccess();
initialize();
} catch (AoException e) {
LOGGER.error("Unable to reload the application model due to: " + e.reason, e);
} finally {
write.unlock();
}
try {
applElemAccessOld._release();
aoSessionOld.close();
} catch (AoException e) {
LOGGER.debug("Unable to close replaced session due to: " + e.reason, e);
} finally {
aoSessionOld._release();
}
}
/**
* Initializes this model manager by caching the application model and
* loading the {@link EntityConfig}s.
*
* @throws AoException
* Thrown on errors.
*/
private void initialize() throws AoException {
loadApplicationModel();
loadEntityConfigurations();
}
/**
* Caches the whole application model as provided by the ODS session.
*
* @throws AoException
* Thrown on errors.
*/
private void loadApplicationModel() throws AoException {
LOGGER.debug("Reading the application model...");
long start = System.currentTimeMillis();
// enumeration mappings (aeID -> (aaName -> enumClass))
Map<String, Map<String, Enumeration<?>>> enumClassMap = new HashMap<>();
EnumRegistry er = EnumRegistry.getInstance();
ApplicationStructure applicationStructure = aoSession.getApplicationStructure();
for (EnumerationAttributeStructure eas : aoSession.getEnumerationAttributes()) {
// make sure the enumeration is found
if (ODSEnumerations.getEnumObj(eas.enumName) == null) {
Enumeration<ODSEnum> enumdyn = new Enumeration<>(ODSEnum.class, eas.enumName);
EnumerationDefinition enumdef = applicationStructure.getEnumerationDefinition(eas.enumName);
String[] listItemNames = enumdef.listItemNames();
for (String item : listItemNames) {
int ordinal=enumdef.getItem(item);
enumdyn.addValue(new ODSEnum(item, ordinal));
}
er.add(eas.enumName, enumdyn);
}
enumClassMap.computeIfAbsent(Long.toString(ODSConverter.fromODSLong(eas.aid)), k -> new HashMap<>())
.put(eas.aaName, ODSEnumerations.getEnumObj(eas.enumName));
}
ApplicationStructureValue applicationStructureValue = aoSession.getApplicationStructureValue();
Map<String, String> units = getUnitMapping(applicationStructureValue.applElems);
// create entity types (incl. attributes)
Map<String, ODSEntityType> entityTypesByID = new HashMap<>();
String sourceName = aoSession.getName();
for (ApplElem applElem : applicationStructureValue.applElems) {
String odsID = Long.toString(ODSConverter.fromODSLong(applElem.aid));
Map<String, Enumeration<?>> entityEnumMap = enumClassMap.getOrDefault(odsID, new HashMap<>());
ODSEntityType entityType = new ODSEntityType(sourceName, applElem, units, entityEnumMap);
entityTypesByName.put(applElem.aeName, entityType);
entityTypesByID.put(odsID, entityType);
}
// create relations
List<Relation> relations = new ArrayList<>();
for (ApplRel applRel : applicationStructureValue.applRels) {
EntityType source = entityTypesByID.get(Long.toString(ODSConverter.fromODSLong(applRel.elem1)));
EntityType target = entityTypesByID.get(Long.toString(ODSConverter.fromODSLong(applRel.elem2)));
relations.add(new ODSRelation(applRel, source, target));
}
// assign relations to their source entity types
relations.stream().collect(groupingBy(Relation::getSource))
.forEach((e, r) -> ((ODSEntityType) e).setRelations(r));
long stop = System.currentTimeMillis();
LOGGER.debug("{} entity types with {} relations found in {} ms.", entityTypesByName.size(), relations.size(),
stop - start);
}
/**
* Loads all available {@link Unit} names mapped by their instance IDs.
*
* @param applElems
* The application element meta data instances.
* @return The unit names mapped by the corresponding instance IDs.
* @throws AoException
* Thrown if unable to load the unit mappings.
*/
private Map<String, String> getUnitMapping(ApplElem[] applElems) throws AoException {
ApplElem unitElem = Stream.of(applElems).filter(ae -> ae.beName.equals("AoUnit")).findAny()
.orElseThrow(() -> new IllegalStateException("Application element 'Unit' is not defined."));
QueryStructureExt qse = new QueryStructureExt();
qse.anuSeq = new SelAIDNameUnitId[] {
new SelAIDNameUnitId(new AIDName(unitElem.aid, "Id"), new T_LONGLONG(), AggrFunc.NONE),
new SelAIDNameUnitId(new AIDName(unitElem.aid, "Name"), new T_LONGLONG(), AggrFunc.NONE) };
qse.condSeq = new SelItem[0];
qse.groupBy = new AIDName[0];
qse.joinSeq = new JoinDef[0];
qse.orderBy = new SelOrder[0];
Map<String, String> units = new HashMap<>();
ElemResultSetExt unitResultSetExt = getApplElemAccess().getInstancesExt(qse, 0)[0].firstElems[0];
for (int i = 0; i < unitResultSetExt.values[0].value.flag.length; i++) {
String unitID = Long
.toString(ODSConverter.fromODSLong(unitResultSetExt.values[0].value.u.longlongVal()[i]));
String unitName = unitResultSetExt.values[1].value.u.stringVal()[i];
units.put(unitID, unitName);
}
return units;
}
/**
* Loads the {@link EntityConfig}s.
*/
private void loadEntityConfigurations() {
LOGGER.debug("Loading entity configurations...");
long start = System.currentTimeMillis();
entityConfigRepository = new EntityConfigRepository();
// Environment | Project | Pool | PhysicalDimension | User | Measurement
// | ChannelGroup
entityConfigRepository.register(create(new Key<>(Environment.class), "Environment", false));
entityConfigRepository.register(create(new Key<>(Project.class), "Project", false));
entityConfigRepository.register(create(new Key<>(Pool.class), "StructureLevel", true));
entityConfigRepository.register(create(new Key<>(PhysicalDimension.class), "PhysDimension", false));
entityConfigRepository.register(create(new Key<>(User.class), "User", false));
entityConfigRepository.register(create(new Key<>(Measurement.class), "MeaResult", false));
entityConfigRepository.register(create(new Key<>(ChannelGroup.class), "SubMatrix", false));
// Unit
EntityConfig<Unit> unitConfig = create(new Key<>(Unit.class), "Unit", false);
unitConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(PhysicalDimension.class)));
entityConfigRepository.register(unitConfig);
// Quantity
EntityConfig<Quantity> quantityConfig = create(new Key<>(Quantity.class), "Quantity", false);
quantityConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(Unit.class)));
entityConfigRepository.register(quantityConfig);
// Channel
EntityConfig<Channel> channelConfig = create(new Key<>(Channel.class), "MeaQuantity", false);
channelConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(Unit.class)));
channelConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(Quantity.class)));
entityConfigRepository.register(channelConfig);
// ValueList
EntityConfig<ValueListValue> valueListValueConfig = create(new Key<>(ValueListValue.class), "ValueListValue",
true);
valueListValueConfig.setComparator(Sortable.COMPARATOR);
EntityConfig<ValueList> valueListConfig = create(new Key<>(ValueList.class), "ValueList", true);
valueListConfig.addChild(valueListValueConfig);
entityConfigRepository.register(valueListConfig);
// ParameterSet
EntityConfig<Parameter> parameterConfig = create(new Key<>(Parameter.class), "ResultParameter", true);
parameterConfig.addOptional(entityConfigRepository.findRoot(new Key<>(Unit.class)));
EntityConfig<ParameterSet> parameterSetConfig = create(new Key<>(ParameterSet.class), "ResultParameterSet",
true);
parameterSetConfig.addChild(parameterConfig);
entityConfigRepository.register(parameterSetConfig);
// CatalogComponents
registerCatalogComponent(ContextType.UNITUNDERTEST);
registerCatalogComponent(ContextType.TESTSEQUENCE);
registerCatalogComponent(ContextType.TESTEQUIPMENT);
// TemplateRoots
registerTemplateRoot(ContextType.UNITUNDERTEST);
registerTemplateRoot(ContextType.TESTSEQUENCE);
registerTemplateRoot(ContextType.TESTEQUIPMENT);
// TemplateTestStep
EntityConfig<TemplateTestStep> templateTestStepConfig = create(new Key<>(TemplateTestStep.class), "TplTestStep",
true);
templateTestStepConfig
.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateRoot.class, ContextType.UNITUNDERTEST)));
templateTestStepConfig
.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateRoot.class, ContextType.TESTSEQUENCE)));
templateTestStepConfig
.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateRoot.class, ContextType.TESTEQUIPMENT)));
templateTestStepConfig.setComparator(Versionable.COMPARATOR);
entityConfigRepository.register(templateTestStepConfig);
// Status TestStep
// TODO check MIME type genration
// entityConfigRepository.register(create(new Key<>(Status.class,
// TestStep.class), "StatusTestStep", true));
// TestStep
EntityConfig<TestStep> testStepConfig = create(new Key<>(TestStep.class), "TestStep", true);
// testStepConfig.addMandatory(entityConfigRepository.findRoot(new
// Key<>(Status.class, TestStep.class)));
testStepConfig.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateTestStep.class)));
testStepConfig.setComparator(Sortable.COMPARATOR);
entityConfigRepository.register(testStepConfig);
// TemplateTest
EntityConfig<TemplateTestStepUsage> templateTestStepUsageConfig = create(new Key<>(TemplateTestStepUsage.class),
"TplTestStepUsage", true);
templateTestStepUsageConfig.addMandatory(templateTestStepConfig);
templateTestStepUsageConfig.setComparator(Sortable.COMPARATOR);
EntityConfig<TemplateTest> templateTestConfig = create(new Key<>(TemplateTest.class), "TplTest", true);
templateTestConfig.addChild(templateTestStepUsageConfig);
templateTestConfig.setComparator(Versionable.COMPARATOR);
entityConfigRepository.register(templateTestConfig);
// Status Test
// TODO check MIME type genration
// entityConfigRepository.register(create(new Key<>(Status.class,
// Test.class), "StatusTest", true));
// Test
EntityConfig<Test> testConfig = create(new Key<>(Test.class), "Test", true);
testConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(User.class)));
// testConfig.addMandatory(entityConfigRepository.findRoot(new
// Key<>(Status.class, Test.class)));
testConfig.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateTest.class)));
entityConfigRepository.register(testConfig);
// ContextRoots
registerContextRoot(ContextType.UNITUNDERTEST);
registerContextRoot(ContextType.TESTSEQUENCE);
registerContextRoot(ContextType.TESTEQUIPMENT);
LOGGER.debug("Entity configurations loaded in {} ms.", System.currentTimeMillis() - start);
}
/**
* Loads the {@link EntityConfig}s required for {@link ContextRoot} with
* given {@link ContextType}.
*
* @param contextType
* The {@code ContextType}.
*/
private void registerContextRoot(ContextType contextType) {
EntityConfig<ContextRoot> contextRootConfig = create(new Key<>(ContextRoot.class, contextType),
ODSUtils.CONTEXTTYPES.convert(contextType), true);
contextRootConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(TemplateRoot.class, contextType)));
for (Relation contextComponentRelation : contextRootConfig.getEntityType().getChildRelations()) {
EntityType contextComponentEntityType = contextComponentRelation.getTarget();
EntityConfig<ContextComponent> contextComponentConfig = create(
new Key<>(ContextComponent.class, contextType), contextComponentEntityType.getName(), true);
contextComponentConfig
.addInherited(entityConfigRepository.findImplicit(new Key<>(TemplateComponent.class, contextType)));
contextRootConfig.addChild(contextComponentConfig);
if (contextType.isTestEquipment()) {
for (Relation contextSensorRelation : contextComponentEntityType.getChildRelations()) {
EntityType contextSensorEntityType = contextSensorRelation.getTarget();
EntityConfig<ContextSensor> contextSensorConfig = create(new Key<>(ContextSensor.class),
contextSensorEntityType.getName(), true);
contextSensorConfig
.addInherited(entityConfigRepository.findImplicit(new Key<>(TemplateSensor.class)));
contextComponentConfig.addChild(contextSensorConfig);
}
}
}
entityConfigRepository.register(contextRootConfig);
}
/**
* Loads the {@link EntityConfig}s required for {@link TemplateRoot} with
* given {@link ContextType}.
*
* @param contextType
* The {@code ContextType}.
*/
private void registerTemplateRoot(ContextType contextType) {
String odsName = ODSUtils.CONTEXTTYPES.convert(contextType);
EntityConfig<TemplateAttribute> templateAttributeConfig = create(
new Key<>(TemplateAttribute.class, contextType), "Tpl" + odsName + "Attr", true);
templateAttributeConfig
.addInherited(entityConfigRepository.findImplicit(new Key<>(CatalogAttribute.class, contextType)));
templateAttributeConfig.setComparator(TemplateAttribute.COMPARATOR);
EntityConfig<TemplateComponent> templateComponentConfig = create(
new Key<>(TemplateComponent.class, contextType), "Tpl" + odsName + "Comp", true);
templateComponentConfig.addChild(templateAttributeConfig);
templateComponentConfig
.addMandatory(entityConfigRepository.findRoot(new Key<>(CatalogComponent.class, contextType)));
templateComponentConfig.addChild(templateComponentConfig);
templateComponentConfig.setComparator(Sortable.COMPARATOR);
if (contextType.isTestEquipment()) {
EntityConfig<TemplateAttribute> templateSensorAttributeConfig = create(new Key<>(TemplateAttribute.class),
"TplSensorAttr", true);
templateSensorAttributeConfig.setComparator(TemplateAttribute.COMPARATOR);
templateSensorAttributeConfig
.addInherited(entityConfigRepository.findImplicit(new Key<>(CatalogAttribute.class)));
EntityConfig<TemplateSensor> templateSensorConfig = create(new Key<>(TemplateSensor.class), "TplSensor",
true);
templateSensorConfig.addChild(templateSensorAttributeConfig);
templateSensorConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(Quantity.class)));
templateSensorConfig.addInherited(entityConfigRepository.findImplicit(new Key<>(CatalogSensor.class)));
templateSensorConfig.setComparator(Sortable.COMPARATOR);
templateComponentConfig.addChild(templateSensorConfig);
}
EntityConfig<TemplateRoot> templateRootConfig = create(new Key<>(TemplateRoot.class, contextType),
"Tpl" + odsName + "Root", true);
templateRootConfig.addChild(templateComponentConfig);
templateRootConfig.setComparator(Versionable.COMPARATOR);
entityConfigRepository.register(templateRootConfig);
}
/**
* Loads the {@link EntityConfig}s required for {@link CatalogComponent}
* with given {@link ContextType}.
*
* @param contextType
* The {@code ContextType}.
*/
private void registerCatalogComponent(ContextType contextType) {
String odsName = ODSUtils.CONTEXTTYPES.convert(contextType);
EntityConfig<CatalogAttribute> catalogAttributeConfig = create(new Key<>(CatalogAttribute.class, contextType),
"Cat" + odsName + "Attr", true);
catalogAttributeConfig.addOptional(entityConfigRepository.findRoot(new Key<>(ValueList.class)));
catalogAttributeConfig.setComparator(Sortable.COMPARATOR);
EntityConfig<CatalogComponent> catalogComponentConfig = create(new Key<>(CatalogComponent.class, contextType),
"Cat" + odsName + "Comp", true);
catalogComponentConfig.addChild(catalogAttributeConfig);
if (contextType.isTestEquipment()) {
EntityConfig<CatalogAttribute> catalogSensorAttributeConfig = create(new Key<>(CatalogAttribute.class),
"CatSensorAttr", true);
catalogSensorAttributeConfig.addOptional(entityConfigRepository.findRoot(new Key<>(ValueList.class)));
EntityConfig<CatalogSensor> catalogSensorConfig = create(new Key<>(CatalogSensor.class), "CatSensor", true);
catalogSensorConfig.addChild(catalogSensorAttributeConfig);
catalogComponentConfig.addChild(catalogSensorConfig);
}
entityConfigRepository.register(catalogComponentConfig);
}
/**
* Creates a new {@link EntityConfig}.
*
* @param <T>
* The entity type.
* @param key
* Used as identifier.
* @param typeName
* Name of the associated {@link EntityType}.
* @param appendName
* Flag indicates whether to append the entity types base name to
* the MIME type.
* @return The created {@code EntityConfig} is returned.
*/
private <T extends Entity> EntityConfig<T> create(Key<T> key, String typeName, boolean appendName) {
EntityConfig<T> entityConfig = new EntityConfig<>(key);
ODSEntityType entityType = (ODSEntityType) getEntityType(typeName);
entityConfig.setEntityType(entityType);
entityConfig.setMimeType(buildDefaultMimeType(entityType, appendName));
return entityConfig;
}
/**
* Creates a default MIME type for given {@link EntityType}.
*
* @param entityType
* The {@code EntityType}.
* @param appendName
* Flag indicates whether to append the entity types base name to
* the MIME type.
* @return The created MIME type {@code String} is returned.
*/
private String buildDefaultMimeType(ODSEntityType entityType, boolean appendName) {
StringBuilder sb = new StringBuilder();
sb.append("application/x-asam.");
sb.append(entityType.getBaseName().toLowerCase(Locale.ROOT));
if (appendName) {
sb.append('.').append(entityType.getName().toLowerCase(Locale.ROOT));
}
return sb.toString();
}
}