Adds code that is needed to enable roles/permission delegation to backends
Replace BiDiMappter contraption with ImmutableBiMap
OMR-15: created ods session passing for_user for which session shall be created.
Refactored and fixed creation of session parameters as for_user is not mandatory
JIRA: OMR-15
Add logging to creating the session parameters string
JIRA: OMR-15
Add last changes
Signed-off-by: Silvio Heuberger <silvio.heuberger@gmail.com>
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContext.java b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContext.java
index d924057..c9a3dda 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContext.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContext.java
@@ -7,17 +7,12 @@
*/
package org.eclipse.mdm.api.odsadapter;
-import java.util.Map;
-import java.util.Optional;
-
+import com.highqsoft.corbafileserver.generated.CORBAFileServerIF;
import org.asam.ods.AoException;
import org.asam.ods.AoSession;
-import org.asam.ods.ElemId;
-import org.asam.ods.InstanceElement;
import org.eclipse.mdm.api.base.ConnectionException;
import org.eclipse.mdm.api.base.adapter.ModelManager;
import org.eclipse.mdm.api.base.file.FileService;
-import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.notification.NotificationService;
import org.eclipse.mdm.api.base.query.DataAccessException;
import org.eclipse.mdm.api.base.query.QueryService;
@@ -30,16 +25,15 @@
import org.eclipse.mdm.api.odsadapter.lookup.EntityLoader;
import org.eclipse.mdm.api.odsadapter.notification.ODSNotificationServiceFactory;
import org.eclipse.mdm.api.odsadapter.query.ODSEntityFactory;
-import org.eclipse.mdm.api.odsadapter.query.ODSEntityType;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
import org.eclipse.mdm.api.odsadapter.query.ODSQueryService;
import org.eclipse.mdm.api.odsadapter.search.ODSSearchService;
-import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;
import org.omg.CORBA.ORB;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.highqsoft.corbafileserver.generated.CORBAFileServerIF;
+import java.util.Map;
+import java.util.Optional;
/**
* ODSContext encapsulates a session to the ASAM ODS CORBA API and
@@ -69,7 +63,7 @@
* @param parameters
* @throws AoException
*/
- ODSContext(ORB orb, AoSession aoSession, CORBAFileServerIF fileServer, Map<String, String> parameters) throws AoException {
+ public ODSContext(ORB orb, AoSession aoSession, CORBAFileServerIF fileServer, Map<String, String> parameters) throws AoException {
this.fileServer = fileServer;
this.parameters = parameters;
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContextFactory.java b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContextFactory.java
index 308e591..ed59726 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContextFactory.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContextFactory.java
@@ -11,6 +11,9 @@
import java.util.HashMap;
import java.util.Map;
+import com.google.common.base.Joiner;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
import org.asam.ods.AoException;
import org.asam.ods.AoFactory;
import org.asam.ods.AoFactoryHelper;
@@ -52,9 +55,9 @@
public static final String PARAM_PASSWORD = "password";
- public static final String PARAM_ELASTIC_SEARCH_URL = "elasticsearch.url";
+ private static final String PARAM_FOR_USER = "for_user";
- private static final String AUTH_TEMPLATE = "USER=%s,PASSWORD=%s,CREATE_COSESSION_ALLOWED=TRUE";
+ private static final String AUTH_TEMPLATE = "USER=%s,PASSWORD=%s,CREATE_COSESSION_ALLOWED=TRUE,FOR_USER=%s";
private static final Logger LOGGER = LoggerFactory.getLogger(ODSContextFactory.class);
@@ -84,7 +87,6 @@
* <li>{@value #PARAM_SERVICENAME}</li>
* <li>{@value #PARAM_USER}</li>
* <li>{@value #PARAM_PASSWORD}</li>
- * <li>{@value #PARAM_ELASTIC_SEARCH_URL}</li>
* </ul>
*
* Listed names are available via public fields of this class.
@@ -95,31 +97,50 @@
try (ServiceLocator serviceLocator = new ServiceLocator(orb, getParameter(parameters, PARAM_NAMESERVICE))) {
String nameOfService = getParameter(parameters, PARAM_SERVICENAME).replace(".ASAM-ODS", "");
+
+
AoFactory aoFactory = serviceLocator.resolveFactory(nameOfService);
LOGGER.info("Connecting to ODS Server ...");
+ LOGGER.info("Connecting to ODS Server ...");
+
LOGGER.info("AoFactory name: {}", aoFactory.getName());
LOGGER.info("AoFactory description: {}", aoFactory.getDescription());
LOGGER.info("AoFactory interface version: {}", aoFactory.getInterfaceVersion());
LOGGER.info("AoFactory type: {}", aoFactory.getType());
- aoSession = aoFactory.newSession(String.format(AUTH_TEMPLATE, getParameter(parameters, PARAM_USER),
- getParameter(parameters, PARAM_PASSWORD)));
+ aoSession = aoFactory.newSession(sessionParametersAsString(parameters));
+
LOGGER.info("Connection to ODS server established.");
CORBAFileServerIF fileServer = serviceLocator.resolveFileServer(nameOfService);
-
+
// Create a parameters map without password (which should not be visible from this point onwards),
// leaving the original map untouched:
Map<String, String> mapParams = new HashMap<>(parameters);
mapParams.remove(PARAM_PASSWORD);
- return new ODSContext(orb, aoSession, fileServer, mapParams);
+ return new ODSContext(orb, aoSession, fileServer, mapParams);
} catch (AoException e) {
closeSession(aoSession);
throw new ConnectionException("Unable to connect to ODS server due to: " + e.reason, e);
}
}
+ private String sessionParametersAsString(Map<String, String> parameters) throws ConnectionException {
+ ImmutableMap.Builder<String, String> builder = ImmutableMap.<String, String>builder()
+ .put("USER", getParameter(parameters, PARAM_USER))
+ .put("PASSWORD", getParameter(parameters, PARAM_PASSWORD))
+ .put("CREATE_COSESSION_ALLOWED", "TRUE");
+
+ String forUserName = parameters.get(PARAM_FOR_USER);
+ if(!Strings.isNullOrEmpty(forUserName)) {
+ builder.put("FOR_USER", forUserName);
+ }
+ String result = Joiner.on(",").withKeyValueSeparator("=").join(builder.build());
+ LOGGER.debug("Connecting to ODS using the connection parameters: {}", result);
+ return result;
+ }
+
// ======================================================================
// Private methods
// ======================================================================
@@ -260,4 +281,4 @@
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSAttribute.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSAttribute.java
index 769aaef..430f06b 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSAttribute.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSAttribute.java
@@ -53,7 +53,7 @@
* The ODS meta data for this attribute.
* @param unit
* The unit name.
- * @param enumClass
+ * @param enumObj
* The enumeration class, may be null.
*/
ODSAttribute(EntityType entityType, ApplAttr applAttr, String unit, Enumeration<?> enumObj) {
@@ -65,7 +65,7 @@
valueType = ValueType.STRING;
isIdAttribute = true;
} else {
- valueType = ODSUtils.VALUETYPES.revert(applAttr.dType);
+ valueType = ODSUtils.VALUETYPES.inverse().get(applAttr.dType);
isIdAttribute = false;
}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSModelManager.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSModelManager.java
index 4a2df93..b4d8194 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSModelManager.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSModelManager.java
@@ -1,719 +1,738 @@
-/*
- * 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();
- }
-
-}
+/*
+ * 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.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.stream.Stream;
+
+import com.google.common.base.Stopwatch;
+import org.apache.commons.lang3.time.StopWatch;
+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...");
+
+ Map<String, Map<String, Enumeration<?>>> enumClassMap = loadODSEnumerations();
+
+ long start = System.currentTimeMillis();
+ 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);
+ }
+
+ private Map<String, Map<String, Enumeration<?>>> loadODSEnumerations() throws AoException {
+ LOGGER.debug("Loading ODS enumerations...");
+ long t1 = 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()) {
+
+ EnumerationDefinition bubu = applicationStructure.getEnumerationDefinition(eas.enumName);
+ for (String itemName : bubu.listItemNames()) {
+ final int intValue = bubu.getItem(itemName);
+ LOGGER.debug("{}:{}:{}", eas.enumName, itemName, intValue);
+ }
+
+ // 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);
+ for (String itemName : enumdef.listItemNames()) {
+ final int intValue = enumdef.getItem(itemName);
+ enumdyn.addValue(new ODSEnum(itemName, intValue));
+ }
+ er.add(eas.enumName, enumdyn);
+ }
+
+ enumClassMap.computeIfAbsent(Long.toString(ODSConverter.fromODSLong(eas.aid)), k -> new HashMap<>())
+ .put(eas.aaName, ODSEnumerations.getEnumObj(eas.enumName));
+ }
+ LOGGER.debug("Loading enumerations took {}ms", System.currentTimeMillis() - t1);
+ return enumClassMap;
+ }
+
+ /**
+ * 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.get(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.get(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.get(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();
+ }
+
+}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSQuery.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSQuery.java
index 05db375..7b552b7 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSQuery.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSQuery.java
@@ -194,9 +194,9 @@
if (conditionItem.isCondition()) {
selItem.value(createCondition(conditionItem.getCondition()));
} else if (conditionItem.isBracketOperator()){
- selItem._operator(ODSUtils.BRACKETOPERATORS.convert(conditionItem.getBracketOperator()));
+ selItem._operator(ODSUtils.BRACKETOPERATORS.get(conditionItem.getBracketOperator()));
} else if (conditionItem.isBooleanOperator()) {
- selItem._operator(ODSUtils.OPERATORS.convert(conditionItem.getBooleanOperator()));
+ selItem._operator(ODSUtils.OPERATORS.get(conditionItem.getBooleanOperator()));
condCount++;
} else {
throw new IllegalArgumentException("Passed filter item is neither an operator nor a condition.");
@@ -244,7 +244,7 @@
private SelAIDNameUnitId createSelect(Attribute attribute, Aggregation aggregation) {
SelAIDNameUnitId sanu = new SelAIDNameUnitId();
- sanu.aggregate = ODSUtils.AGGREGATIONS.convert(aggregation);
+ sanu.aggregate = ODSUtils.AGGREGATIONS.get(aggregation);
sanu.attr = createAIDName(attribute);
sanu.unitId = new T_LONGLONG();
@@ -263,7 +263,7 @@
private SelValueExt createCondition(Condition condition) throws DataAccessException {
SelValueExt sve = new SelValueExt();
- sve.oper = ODSUtils.OPERATIONS.convert(condition.getComparisonOperator());
+ sve.oper = ODSUtils.OPERATIONS.get(condition.getComparisonOperator());
sve.attr = new AIDNameUnitId();
sve.attr.unitId = new T_LONGLONG();
sve.attr.attr = createAIDName(condition.getAttribute());
@@ -278,7 +278,7 @@
*
* @param relation
* The {@code Relation}.
- * @param joinType
+ * @param join
* The {@code JoinType}.
* @return The corresponding {@code JoinDef} is returned.
*/
@@ -288,7 +288,7 @@
joinDef.fromAID = ((ODSEntityType) relation.getSource()).getODSID();
joinDef.toAID = ((ODSEntityType) relation.getTarget()).getODSID();
joinDef.refName = relation.getName();
- joinDef.joiningType = ODSUtils.JOINS.convert(join);
+ joinDef.joiningType = ODSUtils.JOINS.get(join);
return joinDef;
}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSRelation.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSRelation.java
index 4da0adc..2ceac1d 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSRelation.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSRelation.java
@@ -58,7 +58,7 @@
this.source = source;
this.target = target;
name = applRel.arName;
- relationType = ODSUtils.RELATIONSHIPS.revert(applRel.arRelationType);
+ relationType = ODSUtils.RELATIONSHIPS.inverse().get(applRel.arRelationType);
rangeMax = applRel.arRelationRange.max;
}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/CatalogManager.java b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/CatalogManager.java
index af8b2ee..e02fe0c 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/CatalogManager.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/CatalogManager.java
@@ -95,7 +95,7 @@
.collect(Collectors.groupingBy(CatalogComponent::getContextType));
for (Entry<ContextType, List<CatalogComponent>> entry : catalogComponentsByContextType.entrySet()) {
- String odsContextTypeName = ODSUtils.CONTEXTTYPES.convert(entry.getKey());
+ String odsContextTypeName = ODSUtils.CONTEXTTYPES.get(entry.getKey());
ApplicationElement contextRootApplicationElement = getApplicationStructure()
.getElementByName(odsContextTypeName);
BaseElement contextRootBaseElement = contextRootApplicationElement.getBaseElement();
@@ -230,7 +230,7 @@
for (CatalogAttribute catalogAttribute : entry.getValue()) {
ApplicationAttribute applicationAttribute = applicationElement.createAttribute();
- DataType dataType = ODSUtils.VALUETYPES.convert(catalogAttribute.getValueType());
+ DataType dataType = ODSUtils.VALUETYPES.get(catalogAttribute.getValueType());
applicationAttribute.setDataType(dataType);
applicationAttribute.setName(catalogAttribute.getName());
if (dataType == DataType.DT_ENUM) {
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/BiDiMapper.java b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/BiDiMapper.java
deleted file mode 100644
index ac47195..0000000
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/BiDiMapper.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2016 Gigatronik Ingolstadt GmbH
- * 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.utils;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Bidirectional mapping of configured values.
- *
- * @param <T>
- * Mapped object type one.
- * @param <S>
- * Mapped object type two.
- * @since 1.0.0
- * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
- */
-public final class BiDiMapper<T, S> {
-
- // ======================================================================
- // Instance variables
- // ======================================================================
-
- private final Map<Object, Object> map = new HashMap<>();
-
- // ======================================================================
- // Public methods
- // ======================================================================
-
- /**
- * Returns the mapping for given value.
- *
- * @param input
- * The value.
- * @return The corresponding mapped value is returned.
- */
- @SuppressWarnings("unchecked")
- public S convert(T input) {
- return (S) map.get(input);
- }
-
- /**
- * Returns the mapping for given value.
- *
- * @param input
- * The value.
- * @return The corresponding mapped value is returned.
- */
- @SuppressWarnings("unchecked")
- public T revert(S input) {
- return (T) map.get(input);
- }
-
- // ======================================================================
- // Package methods
- // ======================================================================
-
- /**
- * Adds a new bidirectional mapping for given values.
- *
- * @param t
- * Not allowed to be null.
- * @param s
- * Not allowed to be null.
- */
- void addMappings(T t, S s) {
- map.put(t, s);
- map.put(s, t);
- }
-
-}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSConverter.java b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSConverter.java
index c62c05f..339deae 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSConverter.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSConverter.java
@@ -322,7 +322,7 @@
if (Aggregation.NONE == aggregation) {
return attribute.createValue(unit, valid, input);
} else {
- ValueType<?> valueType = ODSUtils.VALUETYPES.revert(dataType);
+ ValueType<?> valueType = ODSUtils.VALUETYPES.inverse().get(dataType);
if (valueType.isEnumerationType()
&& attribute.getValueType().isEnumerationType()
&& Sets.immutableEnumSet(Aggregation.MINIMUM, Aggregation.MAXIMUM, Aggregation.DISTINCT)
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSEnumerations.java b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSEnumerations.java
index 6479fac..095c479 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSEnumerations.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSEnumerations.java
@@ -45,7 +45,7 @@
// Constructors
// ======================================================================
- /**
+ /*o*
* Constructor.
*/
private ODSEnumerations() {
@@ -58,7 +58,6 @@
/**
* Returns the enumeration class identified by given name.
*
- * @param <E>
* The enumeration type.
* @param name
* The ODS name of the requested enumeration class.
@@ -89,8 +88,8 @@
/**
* Returns the ODS enumeration name for given enumeration class.
*
- * @param enumClass
- * The enumeration class name.
+ * @param enumObj
+ * The enumeration object.
* @return The corresponding ODS enumeration name is returned.
* @throws IllegalArgumentException
* Thrown if enumeration class is unknown.
@@ -297,7 +296,7 @@
return ScalarType.FLOAT_COMPLEX;
} else if (value == 14) {
return ScalarType.DOUBLE_COMPLEX;
- } else if (value == 28) {
+ } else if (value == 28) {
return ScalarType.FILE_LINK;
} else if (value == 30) {
return ScalarType.ENUMERATION;
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSUtils.java b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSUtils.java
index 1f69761..5650866 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSUtils.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSUtils.java
@@ -8,6 +8,7 @@
package org.eclipse.mdm.api.odsadapter.utils;
+import com.google.common.collect.ImmutableBiMap;
import org.asam.ods.AggrFunc;
import org.asam.ods.DataType;
import org.asam.ods.SelOpcode;
@@ -24,141 +25,142 @@
/**
* Utility class provides bidirectional mappings for ODS types
*
- * @since 1.0.0
* @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ * @since 1.0.0
*/
public abstract class ODSUtils {
+ /**
+ * Maps {@link RelationType} to the corresponding ODS {@link RelationType}.
+ */
+ public static final ImmutableBiMap<RelationType, org.asam.ods.RelationType> RELATIONSHIPS =
+ ImmutableBiMap.<RelationType, org.asam.ods.RelationType>builder()
+ .put(RelationType.FATHER_CHILD, org.asam.ods.RelationType.FATHER_CHILD)
+ .put(RelationType.INFO, org.asam.ods.RelationType.INFO)
+ .put(RelationType.INHERITANCE, org.asam.ods.RelationType.INHERITANCE)
+ .build();
- // ======================================================================
- // Class variables
- // ======================================================================
+ /**
+ * Maps {@link Aggregation} to the corresponding ODS {@link AggrFunc}.
+ */
+ public static final ImmutableBiMap<Aggregation, AggrFunc> AGGREGATIONS =
+ ImmutableBiMap.<Aggregation, AggrFunc>builder()
+ .put(Aggregation.NONE, AggrFunc.NONE)
+ .put(Aggregation.COUNT, AggrFunc.COUNT)
+ .put(Aggregation.DISTINCT_COUNT, AggrFunc.DCOUNT)
+ .put(Aggregation.MINIMUM, AggrFunc.MIN)
+ .put(Aggregation.MAXIMUM, AggrFunc.MAX)
+ .put(Aggregation.AVERAGE, AggrFunc.AVG)
+ .put(Aggregation.DEVIATION, AggrFunc.STDDEV)
+ .put(Aggregation.SUM, AggrFunc.SUM)
+ .put(Aggregation.DISTINCT, AggrFunc.DISTINCT)
+ .build();
- /**
- * Maps {@link RelationType} to the corresponding ODS {@link RelationType}.
- */
- public static final BiDiMapper<RelationType, org.asam.ods.RelationType> RELATIONSHIPS = new BiDiMapper<>();
+ /**
+ * Maps {@link ContextType} to the corresponding ODS {@link String}.
+ */
+ public static final ImmutableBiMap<ContextType, String> CONTEXTTYPES =
+ ImmutableBiMap.<ContextType, String>builder()
+ .put(ContextType.UNITUNDERTEST, "UnitUnderTest")
+ .put(ContextType.TESTSEQUENCE, "TestSequence")
+ .put(ContextType.TESTEQUIPMENT, "TestEquipment")
+ .build();
- /**
- * Maps {@link Aggregation} to the corresponding ODS {@link AggrFunc}.
- */
- public static final BiDiMapper<Aggregation, AggrFunc> AGGREGATIONS = new BiDiMapper<>();
+ /**
+ * Maps {@link ComparisonOperator} to the corresponding ODS {@link SelOpcode}.
+ */
+ public static final ImmutableBiMap<ComparisonOperator, SelOpcode> OPERATIONS =
+ ImmutableBiMap.<ComparisonOperator, SelOpcode>builder()
+ .put(ComparisonOperator.LIKE, SelOpcode.LIKE)
+ .put(ComparisonOperator.CASE_INSENSITIVE_LIKE, SelOpcode.CI_LIKE)
+ .put(ComparisonOperator.NOT_LIKE, SelOpcode.NOTLIKE)
+ .put(ComparisonOperator.CASE_INSENSITIVE_NOT_LIKE, SelOpcode.CI_NOTLIKE)
+ .put(ComparisonOperator.EQUAL, SelOpcode.EQ)
+ .put(ComparisonOperator.CASE_INSENSITIVE_EQUAL, SelOpcode.CI_EQ)
+ .put(ComparisonOperator.NOT_EQUAL, SelOpcode.NEQ)
+ .put(ComparisonOperator.CASE_INSENSITIVE_NOT_EQUAL, SelOpcode.CI_NEQ)
+ .put(ComparisonOperator.GREATER_THAN, SelOpcode.GT)
+ .put(ComparisonOperator.CASE_INSENSITIVE_GREATER_THAN, SelOpcode.CI_GT)
+ .put(ComparisonOperator.GREATER_THAN_OR_EQUAL, SelOpcode.GTE)
+ .put(ComparisonOperator.CASE_INSENSITIVE_GREATER_THAN_OR_EQUAL, SelOpcode.CI_GTE)
+ .put(ComparisonOperator.LESS_THAN, SelOpcode.LT)
+ .put(ComparisonOperator.CASE_INSENSITIVE_LESS_THAN, SelOpcode.CI_LT)
+ .put(ComparisonOperator.LESS_THAN_OR_EQUAL, SelOpcode.LTE)
+ .put(ComparisonOperator.CASE_INSENSITIVE_LESS_THAN_OR_EQUAL, SelOpcode.CI_LTE)
+ .put(ComparisonOperator.IS_NULL, SelOpcode.IS_NULL)
+ .put(ComparisonOperator.IS_NOT_NULL, SelOpcode.IS_NOT_NULL)
+ .put(ComparisonOperator.IN_SET, SelOpcode.INSET)
+ .put(ComparisonOperator.CASE_INSENSITIVE_IN_SET, SelOpcode.CI_INSET)
+ .put(ComparisonOperator.NOT_IN_SET, SelOpcode.NOTINSET)
+ .put(ComparisonOperator.CASE_INSENSITIVE_NOT_IN_SET, SelOpcode.CI_NOTINSET)
+ .put(ComparisonOperator.BETWEEN, SelOpcode.BETWEEN)
+ .build();
- /**
- * Maps {@link ContextType} to the corresponding ODS {@link String}.
- */
- public static final BiDiMapper<ContextType, String> CONTEXTTYPES = new BiDiMapper<>();
+ /**
+ * Maps {@link BooleanOperator} to the corresponding ODS {@link SelOperator}.
+ */
+ public static final ImmutableBiMap<BooleanOperator, SelOperator> OPERATORS =
+ ImmutableBiMap.<BooleanOperator, SelOperator>builder()
+ .put(BooleanOperator.AND, SelOperator.AND)
+ .put(BooleanOperator.OR, SelOperator.OR)
+ .put(BooleanOperator.NOT, SelOperator.NOT)
+ .build();
- /**
- * Maps {@link ComparisonOperator} to the corresponding ODS {@link SelOpcode}.
- */
- public static final BiDiMapper<ComparisonOperator, SelOpcode> OPERATIONS = new BiDiMapper<>();
+ /**
+ * Maps {@link BracketOperator} to the corresponding ODS {@link SelOperator}.
+ */
+ public static final ImmutableBiMap<BracketOperator, SelOperator> BRACKETOPERATORS =
+ ImmutableBiMap.<BracketOperator, SelOperator>builder()
+ .put(BracketOperator.OPEN, SelOperator.OPEN)
+ .put(BracketOperator.CLOSE, SelOperator.CLOSE)
+ .build();
- /**
- * Maps {@link BooleanOperator} to the corresponding ODS {@link SelOperator}.
- */
- public static final BiDiMapper<BooleanOperator, SelOperator> OPERATORS = new BiDiMapper<>();
-
- /**
- * Maps {@link BracketOperator} to the corresponding ODS {@link SelOperator}.
- */
- public static final BiDiMapper<BracketOperator, SelOperator> BRACKETOPERATORS = new BiDiMapper<>();
+ /**
+ * Maps {@link ValueType} to the corresponding ODS {@link DataType}.
+ */
+ public static final ImmutableBiMap<ValueType<?>, DataType> VALUETYPES =
+ ImmutableBiMap.<ValueType<?>, DataType> builder()
+ .put(ValueType.UNKNOWN, DataType.DT_UNKNOWN)
+ .put(ValueType.STRING, DataType.DT_STRING)
+ .put(ValueType.STRING_SEQUENCE, DataType.DS_STRING)
+ .put(ValueType.DATE, DataType.DT_DATE)
+ .put(ValueType.DATE_SEQUENCE, DataType.DS_DATE)
+ .put(ValueType.BOOLEAN, DataType.DT_BOOLEAN)
+ .put(ValueType.BOOLEAN_SEQUENCE, DataType.DS_BOOLEAN)
+ .put(ValueType.BYTE, DataType.DT_BYTE)
+ .put(ValueType.BYTE_SEQUENCE, DataType.DS_BYTE)
+ .put(ValueType.SHORT, DataType.DT_SHORT)
+ .put(ValueType.SHORT_SEQUENCE, DataType.DS_SHORT)
+ .put(ValueType.INTEGER, DataType.DT_LONG)
+ .put(ValueType.INTEGER_SEQUENCE, DataType.DS_LONG)
+ .put(ValueType.LONG, DataType.DT_LONGLONG)
+ .put(ValueType.LONG_SEQUENCE, DataType.DS_LONGLONG)
+ .put(ValueType.FLOAT, DataType.DT_FLOAT)
+ .put(ValueType.FLOAT_SEQUENCE, DataType.DS_FLOAT)
+ .put(ValueType.DOUBLE, DataType.DT_DOUBLE)
+ .put(ValueType.DOUBLE_SEQUENCE, DataType.DS_DOUBLE)
+ .put(ValueType.BYTE_STREAM, DataType.DT_BYTESTR)
+ .put(ValueType.BYTE_STREAM_SEQUENCE, DataType.DS_BYTESTR)
+ .put(ValueType.FLOAT_COMPLEX, DataType.DT_COMPLEX)
+ .put(ValueType.FLOAT_COMPLEX_SEQUENCE, DataType.DS_COMPLEX)
+ .put(ValueType.DOUBLE_COMPLEX, DataType.DT_DCOMPLEX)
+ .put(ValueType.DOUBLE_COMPLEX_SEQUENCE, DataType.DS_DCOMPLEX)
+ .put(ValueType.ENUMERATION, DataType.DT_ENUM)
+ .put(ValueType.ENUMERATION_SEQUENCE, DataType.DS_ENUM)
+ .put(ValueType.FILE_LINK, DataType.DT_EXTERNALREFERENCE)
+ .put(ValueType.FILE_LINK_SEQUENCE, DataType.DS_EXTERNALREFERENCE)
+ .put(ValueType.BLOB, DataType.DT_BLOB)
+ .build();
- /**
- * Maps {@link ValueType} to the corresponding ODS {@link DataType}.
- */
- public static final BiDiMapper<ValueType<?>, DataType> VALUETYPES = new BiDiMapper<>();
+ /**
+ * Maps {@link JoinType} to the corresponding ODS {@link org.asam.ods.JoinType}.
+ */
+ public static final ImmutableBiMap<JoinType, org.asam.ods.JoinType> JOINS =
+ ImmutableBiMap.<JoinType, org.asam.ods.JoinType>builder()
+ .put(JoinType.INNER, org.asam.ods.JoinType.JTDEFAULT)
+ .put(JoinType.OUTER, org.asam.ods.JoinType.JTOUTER)
+ .build();
- /**
- * Maps {@link JoinType} to the corresponding ODS {@link org.asam.ods.JoinType}.
- */
- public static final BiDiMapper<JoinType, org.asam.ods.JoinType> JOINS = new BiDiMapper<>();
-
- static {
- RELATIONSHIPS.addMappings(RelationType.FATHER_CHILD, org.asam.ods.RelationType.FATHER_CHILD);
- RELATIONSHIPS.addMappings(RelationType.INFO, org.asam.ods.RelationType.INFO);
- RELATIONSHIPS.addMappings(RelationType.INHERITANCE, org.asam.ods.RelationType.INHERITANCE);
-
- AGGREGATIONS.addMappings(Aggregation.NONE, AggrFunc.NONE);
- AGGREGATIONS.addMappings(Aggregation.COUNT, AggrFunc.COUNT);
- AGGREGATIONS.addMappings(Aggregation.DISTINCT_COUNT, AggrFunc.DCOUNT);
- AGGREGATIONS.addMappings(Aggregation.MINIMUM, AggrFunc.MIN);
- AGGREGATIONS.addMappings(Aggregation.MAXIMUM, AggrFunc.MAX);
- AGGREGATIONS.addMappings(Aggregation.AVERAGE, AggrFunc.AVG);
- AGGREGATIONS.addMappings(Aggregation.DEVIATION, AggrFunc.STDDEV);
- AGGREGATIONS.addMappings(Aggregation.SUM, AggrFunc.SUM);
- AGGREGATIONS.addMappings(Aggregation.DISTINCT, AggrFunc.DISTINCT);
-
- CONTEXTTYPES.addMappings(ContextType.UNITUNDERTEST, "UnitUnderTest");
- CONTEXTTYPES.addMappings(ContextType.TESTSEQUENCE, "TestSequence");
- CONTEXTTYPES.addMappings(ContextType.TESTEQUIPMENT, "TestEquipment");
-
- OPERATIONS.addMappings(ComparisonOperator.LIKE, SelOpcode.LIKE);
- OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_LIKE, SelOpcode.CI_LIKE);
- OPERATIONS.addMappings(ComparisonOperator.NOT_LIKE, SelOpcode.NOTLIKE);
- OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_NOT_LIKE, SelOpcode.CI_NOTLIKE);
- OPERATIONS.addMappings(ComparisonOperator.EQUAL, SelOpcode.EQ);
- OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_EQUAL, SelOpcode.CI_EQ);
- OPERATIONS.addMappings(ComparisonOperator.NOT_EQUAL, SelOpcode.NEQ);
- OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_NOT_EQUAL, SelOpcode.CI_NEQ);
- OPERATIONS.addMappings(ComparisonOperator.GREATER_THAN, SelOpcode.GT);
- OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_GREATER_THAN, SelOpcode.CI_GT);
- OPERATIONS.addMappings(ComparisonOperator.GREATER_THAN_OR_EQUAL, SelOpcode.GTE);
- OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_GREATER_THAN_OR_EQUAL, SelOpcode.CI_GTE);
- OPERATIONS.addMappings(ComparisonOperator.LESS_THAN, SelOpcode.LT);
- OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_LESS_THAN, SelOpcode.CI_LT);
- OPERATIONS.addMappings(ComparisonOperator.LESS_THAN_OR_EQUAL, SelOpcode.LTE);
- OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_LESS_THAN_OR_EQUAL, SelOpcode.CI_LTE);
- OPERATIONS.addMappings(ComparisonOperator.IS_NULL, SelOpcode.IS_NULL);
- OPERATIONS.addMappings(ComparisonOperator.IS_NOT_NULL, SelOpcode.IS_NOT_NULL);
- OPERATIONS.addMappings(ComparisonOperator.IN_SET, SelOpcode.INSET);
- OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_IN_SET, SelOpcode.CI_INSET);
- OPERATIONS.addMappings(ComparisonOperator.NOT_IN_SET, SelOpcode.NOTINSET);
- OPERATIONS.addMappings(ComparisonOperator.CASE_INSENSITIVE_NOT_IN_SET, SelOpcode.CI_NOTINSET);
- OPERATIONS.addMappings(ComparisonOperator.BETWEEN, SelOpcode.BETWEEN);
-
- OPERATORS.addMappings(BooleanOperator.AND, SelOperator.AND);
- OPERATORS.addMappings(BooleanOperator.OR, SelOperator.OR);
- OPERATORS.addMappings(BooleanOperator.NOT, SelOperator.NOT);
-
- BRACKETOPERATORS.addMappings(BracketOperator.OPEN, SelOperator.OPEN);
- BRACKETOPERATORS.addMappings(BracketOperator.CLOSE, SelOperator.CLOSE);
-
- VALUETYPES.addMappings(ValueType.UNKNOWN, DataType.DT_UNKNOWN);
- VALUETYPES.addMappings(ValueType.STRING, DataType.DT_STRING);
- VALUETYPES.addMappings(ValueType.STRING_SEQUENCE, DataType.DS_STRING);
- VALUETYPES.addMappings(ValueType.DATE, DataType.DT_DATE);
- VALUETYPES.addMappings(ValueType.DATE_SEQUENCE, DataType.DS_DATE);
- VALUETYPES.addMappings(ValueType.BOOLEAN, DataType.DT_BOOLEAN);
- VALUETYPES.addMappings(ValueType.BOOLEAN_SEQUENCE, DataType.DS_BOOLEAN);
- VALUETYPES.addMappings(ValueType.BYTE, DataType.DT_BYTE);
- VALUETYPES.addMappings(ValueType.BYTE_SEQUENCE, DataType.DS_BYTE);
- VALUETYPES.addMappings(ValueType.SHORT, DataType.DT_SHORT);
- VALUETYPES.addMappings(ValueType.SHORT_SEQUENCE, DataType.DS_SHORT);
- VALUETYPES.addMappings(ValueType.INTEGER, DataType.DT_LONG);
- VALUETYPES.addMappings(ValueType.INTEGER_SEQUENCE, DataType.DS_LONG);
- VALUETYPES.addMappings(ValueType.LONG, DataType.DT_LONGLONG);
- VALUETYPES.addMappings(ValueType.LONG_SEQUENCE, DataType.DS_LONGLONG);
- VALUETYPES.addMappings(ValueType.FLOAT, DataType.DT_FLOAT);
- VALUETYPES.addMappings(ValueType.FLOAT_SEQUENCE, DataType.DS_FLOAT);
- VALUETYPES.addMappings(ValueType.DOUBLE, DataType.DT_DOUBLE);
- VALUETYPES.addMappings(ValueType.DOUBLE_SEQUENCE, DataType.DS_DOUBLE);
- VALUETYPES.addMappings(ValueType.BYTE_STREAM, DataType.DT_BYTESTR);
- VALUETYPES.addMappings(ValueType.BYTE_STREAM_SEQUENCE, DataType.DS_BYTESTR);
- VALUETYPES.addMappings(ValueType.FLOAT_COMPLEX, DataType.DT_COMPLEX);
- VALUETYPES.addMappings(ValueType.FLOAT_COMPLEX_SEQUENCE, DataType.DS_COMPLEX);
- VALUETYPES.addMappings(ValueType.DOUBLE_COMPLEX, DataType.DT_DCOMPLEX);
- VALUETYPES.addMappings(ValueType.DOUBLE_COMPLEX_SEQUENCE, DataType.DS_DCOMPLEX);
- VALUETYPES.addMappings(ValueType.ENUMERATION, DataType.DT_ENUM);
- VALUETYPES.addMappings(ValueType.ENUMERATION_SEQUENCE, DataType.DS_ENUM);
- VALUETYPES.addMappings(ValueType.FILE_LINK, DataType.DT_EXTERNALREFERENCE);
- VALUETYPES.addMappings(ValueType.FILE_LINK_SEQUENCE, DataType.DS_EXTERNALREFERENCE);
- VALUETYPES.addMappings(ValueType.BLOB, DataType.DT_BLOB);
-
- JOINS.addMappings(JoinType.INNER, org.asam.ods.JoinType.JTDEFAULT);
- JOINS.addMappings(JoinType.OUTER, org.asam.ods.JoinType.JTOUTER);
- }
-
- public static boolean isValidID(String instanceID) {
- return instanceID != null && !instanceID.isEmpty() && !"0".equals(instanceID);
- }
+ public static boolean isValidID(String instanceID) {
+ return instanceID != null && !instanceID.isEmpty() && !"0".equals(instanceID);
+ }
}