Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Koller2019-02-27 11:12:33 +0000
committerMatthias Koller2019-02-27 11:12:33 +0000
commita06539e576842b4d78baccfb38bcf26eaaaaf7a7 (patch)
treef673fd88b0f88302360a12623942e11a140ca98c
parente9e139185ea8df98b49d31af85a6efc08e751ce6 (diff)
parentb5444eb1a875b04f8a71b93bfa6dd2b4a3fe40b5 (diff)
downloadorg.eclipse.mdm.api.odsadapter-a06539e576842b4d78baccfb38bcf26eaaaaf7a7.tar.gz
org.eclipse.mdm.api.odsadapter-a06539e576842b4d78baccfb38bcf26eaaaaf7a7.tar.xz
org.eclipse.mdm.api.odsadapter-a06539e576842b4d78baccfb38bcf26eaaaaf7a7.zip
Merge branch 'dev'
-rw-r--r--NOTICE.txt27
-rw-r--r--build.gradle17
-rw-r--r--src/main/java/org/eclipse/mdm/api/odsadapter/ODSContext.java28
-rw-r--r--src/main/java/org/eclipse/mdm/api/odsadapter/ODSContextFactory.java28
-rw-r--r--src/main/java/org/eclipse/mdm/api/odsadapter/ODSEntityManager.java20
-rw-r--r--src/main/java/org/eclipse/mdm/api/odsadapter/ReadRequestHandler.java274
-rw-r--r--src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/DefaultEntityConfigRepositoryLoader.java336
-rw-r--r--src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/EntityConfigRepositoryLoader.java26
-rw-r--r--src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityFactory.java32
-rw-r--r--src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSModelManager.java340
-rw-r--r--src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSRelation.java8
-rw-r--r--src/main/java/org/eclipse/mdm/api/odsadapter/transaction/InsertStatement.java31
-rw-r--r--src/main/java/org/eclipse/mdm/api/odsadapter/transaction/ODSTransaction.java95
-rw-r--r--src/main/java/org/eclipse/mdm/api/odsadapter/transaction/UpdateStatement.java31
-rw-r--r--src/main/java/org/eclipse/mdm/api/odsadapter/transaction/WriteRequestHandler.java42
-rw-r--r--src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSConverter.java68
-rw-r--r--src/test/java/org/eclipse/mdm/api/odsadapter/ODSRoleTest.java209
17 files changed, 1104 insertions, 508 deletions
diff --git a/NOTICE.txt b/NOTICE.txt
index 8bbd2e1..0dc71e0 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -17,13 +17,13 @@ For more information regarding authorship of content, please consult the listed
source code repository logs.
Copyright (c) 2016-2018 Gigatronik Ingolstadt GmbH
-Copyright (c) 2016-2018 Peak Solution GmbH
+Copyright (c) 2016-2019 Peak Solution GmbH
Copyright (c) 2017-2018 science + computing AG Tuebingen (ATOS SE)
Copyright (c) 2017-2018 Canoo Engineering AG
Copyright (c) 2017 Florian Schmitt
-Copyright (c) 2017-2018 Angelika Wittek
+Copyright (c) 2017-2019 Angelika Wittek
Copyright (c) 2018 Elektronische Fahrwerksysteme GMBH
-Copyright (c) 2018 Karakun AG
+Copyright (c) 2018-2019 Karakun AG
## Declared Project Licenses
@@ -61,7 +61,13 @@ commons-codec-1.2.jar (1.2)
commons-httpclient-3.1.jar (3.1)
* License: Apache License, 2.0
-commons-lang3-3.4.jar (3.4)
+commons-lang3-3.8.1.jar (3.8.1)
+ * License: Apache License, 2.0
+
+commons-text-1.6.jar (1.6)
+ * License: Apache License, 2.0
+
+commons-math-2.2.jar (2.2)
* License: Apache License, 2.0
gson-2.7.jar (2.7)
@@ -71,7 +77,7 @@ Google Guava Version: 25.0-jre (25.0)
* License: Apache License, 2.0
Gradle Wrapper (4.10.2)
- * License: Apache License, 2.0
+ * License: Apache License, 2.0
hk2-api-2.5.0-b05.jar (2.5.0-b05)
* License: CDDL-1.1
@@ -130,6 +136,9 @@ jersey-media-jaxb-2.23.2.jar(2.23.2)
jersey-media-sse-2.23.2.jar (2.23.2)
* License: CDDL
+jersey-media-multipart-2.23.2.jar (2.23.2)
+ * License: CDDL
+
jersey-server-2.23.2.jar (2.23.2)
* License: Apache-2.0
@@ -317,10 +326,10 @@ Permission of use:
From Dr. Ralph Noerenberg
Date: 08/15/2016
"Herewith, we release the generated Client-Source-Code generated from our CORBA IDLs, namely
-* CORBANotification Service (generated from „AvalonEvent.idl”)
-* CORBAFileServer (generated from „CorbaFileServer.idl“),
-Under the Eclipse Public License (EPL). This agreement does not include the „AvalonEvent.idl“ and
-„CorbaFileServer.idl“ itself, which remain protected property of HighQSoft. "
+* CORBANotification Service (generated from AvalonEvent.idl)
+* CORBAFileServer (generated from CorbaFileServer.idl),
+Under the Eclipse Public License (EPL). This agreement does not include the AvalonEvent.idl and
+CorbaFileServer.idl itself, which remain protected property of HighQSoft. "
OMG Notification Service Specification Version: 1.1
The terms of use are defined in section "Freely Available And Available
diff --git a/build.gradle b/build.gradle
index cb964a2..b4f00da 100644
--- a/build.gradle
+++ b/build.gradle
@@ -14,7 +14,7 @@
description = 'MDM API - ODSAdapter'
group = 'org.eclipse.mdm'
-version = '5.1.0M1'
+version = '5.1.0M2-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'maven'
@@ -94,7 +94,7 @@ dependencies {
// querying es
compile 'commons-httpclient:commons-httpclient:3.1'
- compile 'org.apache.commons:commons-lang3:3.4'
+ compile 'org.apache.commons:commons-lang3:3.8.1'
// testing
testCompile 'junit:junit:4.12'
@@ -140,7 +140,7 @@ task compileIDL(type: JavaExec) {
main = 'com.sun.tools.corba.se.idl.toJavaPortable.Compile'
// add 'fallTIE' if <Type>POA & <Type>POATie have to be generated
- args '-td', 'src/gen/java/', 'src/main/idl/ods530.idl'
+ args '-fallTIE', '-td', 'src/gen/java/', 'src/main/idl/ods530.idl'
outputs.dir("src/gen/java")
}
@@ -150,7 +150,7 @@ task compileNotificationServiceIDL(type: JavaExec) {
main = 'com.sun.tools.corba.se.idl.toJavaPortable.Compile'
- args '-emitAll', '-fall', '-i', 'src/main/idl/', '-td', 'src/gen/java/', 'src/main/idl/CosNotifyChannelAdmin.idl'
+ args '-emitAll', '-fallTIE', '-i', 'src/main/idl/', '-td', 'src/gen/java/', 'src/main/idl/CosNotifyChannelAdmin.idl'
outputs.dir("src/gen/java")
outputs.upToDateWhen { false }
@@ -175,6 +175,15 @@ jar {
metaInf { from 'LICENSE.txt' }
}
+task sourcesJar(type: Jar, dependsOn: classes) {
+ classifier = 'sources'
+ from sourceSets.main.allSource
+}
+
+artifacts {
+ archives sourcesJar
+}
+
task deleteGenerated(type: Delete) {
delete 'src/gen'
delete 'build'
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 013c077..e1cb7fc 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContext.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContext.java
@@ -1,16 +1,16 @@
-/********************************************************************************
- * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- ********************************************************************************/
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
package org.eclipse.mdm.api.odsadapter;
@@ -97,7 +97,7 @@ public class ODSContext implements ApplicationContext {
@Override
public Optional<EntityFactory> getEntityFactory() {
try {
- return Optional.of(new ODSEntityFactory(modelManager, entityManager.loadLoggedOnUser().get()));
+ return Optional.of(new ODSEntityFactory(modelManager, entityManager.loadLoggedOnUser()));
} catch (DataAccessException e) {
throw new IllegalStateException("Unable to load instance of the logged in user.");
}
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 0546c46..4084697 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContextFactory.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContextFactory.java
@@ -1,16 +1,16 @@
-/********************************************************************************
- * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- ********************************************************************************/
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
package org.eclipse.mdm.api.odsadapter;
@@ -62,7 +62,7 @@ public class ODSContextFactory implements ApplicationContextFactory {
private static final Logger LOGGER = LoggerFactory.getLogger(ODSContextFactory.class);
- private final ORB orb = ORB.init(new String[] {}, System.getProperties());
+ private static final ORB orb = ORB.init(new String[] {}, System.getProperties());
public ODSContextFactory() {
}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSEntityManager.java b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSEntityManager.java
index bb7b141..bbbad94 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSEntityManager.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSEntityManager.java
@@ -25,11 +25,13 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.asam.ods.AoException;
import org.asam.ods.ApplicationStructure;
import org.asam.ods.ElemId;
import org.asam.ods.InstanceElement;
+import org.asam.ods.T_LONGLONG;
import org.eclipse.mdm.api.base.ServiceNotProvidedException;
import org.eclipse.mdm.api.base.Transaction;
import org.eclipse.mdm.api.base.adapter.EntityType;
@@ -355,9 +357,25 @@ public class ODSEntityManager implements EntityManager {
/**
* {@inheritDoc}
*/
+ public <T extends Entity> List<T> loadRelatedEntities(Entity entity, String relationName, Class<T> relatedClass) {
+ ODSEntityType entityType = ((ODSEntityType) context.getODSModelManager().getEntityType(entity));
+ ElemId elemId = new ElemId(entityType.getODSID(), ODSConverter.toODSID(entity.getID()));
+
+ try {
+ T_LONGLONG[] instanceIds = context.getAoSession().getApplElemAccess().getRelInst(elemId, relationName);
+ List<String> instanceIDs = Stream.of(instanceIds).map(ODSConverter::fromODSLong).map(l -> l.toString()).collect(Collectors.toList());
+ return entityLoader.loadAll(new Key<>(relatedClass), instanceIDs);
+ } catch (AoException e) {
+ throw new DataAccessException("" + e.reason, e); // TODO
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
@Override
public List<MeasuredValues> readMeasuredValues(ReadRequest readRequest) throws DataAccessException {
- return new ReadRequestHandler(odsModelManager).execute(readRequest);
+ return new ReadRequestHandler(odsModelManager, queryService).execute(readRequest);
}
/**
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/ReadRequestHandler.java b/src/main/java/org/eclipse/mdm/api/odsadapter/ReadRequestHandler.java
index 7d4603e..44d32fd 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/ReadRequestHandler.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/ReadRequestHandler.java
@@ -1,24 +1,29 @@
-/********************************************************************************
- * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- ********************************************************************************/
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
package org.eclipse.mdm.api.odsadapter;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
import org.asam.ods.AoException;
import org.asam.ods.Column;
import org.asam.ods.ElemId;
@@ -26,29 +31,111 @@ import org.asam.ods.NameValueSeqUnit;
import org.asam.ods.T_LONGLONG;
import org.asam.ods.ValueMatrix;
import org.asam.ods.ValueMatrixMode;
+import org.eclipse.mdm.api.base.adapter.Attribute;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.massdata.ReadRequest;
+import org.eclipse.mdm.api.base.massdata.ReadRequest.ValuesMode;
+import org.eclipse.mdm.api.base.model.AxisType;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.MeasuredValues;
+import org.eclipse.mdm.api.base.model.SequenceRepresentation;
import org.eclipse.mdm.api.base.model.Unit;
+import org.eclipse.mdm.api.base.model.Value;
+import org.eclipse.mdm.api.base.query.ComparisonOperator;
import org.eclipse.mdm.api.base.query.DataAccessException;
+import org.eclipse.mdm.api.base.query.Filter;
+import org.eclipse.mdm.api.base.query.Query;
+import org.eclipse.mdm.api.base.query.QueryService;
+import org.eclipse.mdm.api.base.query.Result;
import org.eclipse.mdm.api.odsadapter.query.ODSEntityType;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;
+import com.google.common.collect.Lists;
+
/**
* Reads mass data specified in {@link ReadRequest}s.
*
* @since 1.0.0
* @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
*/
-final class ReadRequestHandler {
+public final class ReadRequestHandler {
+ public static final class ColumnAttributes
+ {
+ private String name;
+ private SequenceRepresentation sequenceRepresentation;
+ private double[] generationParameters;
+ private boolean independent;
+ private AxisType axisType;
+
+ public ColumnAttributes(String name, SequenceRepresentation sequenceRepresentation, double[] generationParameters, boolean independent, AxisType axisType)
+ {
+ this.name = name;
+ this.sequenceRepresentation = sequenceRepresentation;
+ this.generationParameters = generationParameters;
+ this.independent = independent;
+ this.axisType = axisType;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public SequenceRepresentation getSequenceRepresentation()
+ {
+ return sequenceRepresentation;
+ }
+
+ public void setSequenceRepresentation(SequenceRepresentation sequenceRepresentation)
+ {
+ this.sequenceRepresentation = sequenceRepresentation;
+ }
+
+ public double[] getGenerationParameters()
+ {
+ return generationParameters;
+ }
+
+ public void setGenerationParameters(double[] generationParameters)
+ {
+ this.generationParameters = generationParameters;
+ }
+
+ public boolean isIndependentColumn()
+ {
+ return independent;
+ }
+
+ public void setIndependentColumn(boolean independent)
+ {
+ this.independent = independent;
+ }
+
+ public AxisType getAxisType()
+ {
+ return axisType;
+ }
+
+ public void setAxisType(AxisType axisType)
+ {
+ this.axisType = axisType;
+ }
+
+ }
// ======================================================================
// Instance variables
// ======================================================================
private final ODSModelManager modelManager;
+ private final QueryService queryService;
// ======================================================================
// Constructors
@@ -60,8 +147,9 @@ final class ReadRequestHandler {
* @param modelManager
* Used to gain access to value matrices.
*/
- public ReadRequestHandler(ODSModelManager modelManager) {
+ public ReadRequestHandler(ODSModelManager modelManager, QueryService queryService) {
this.modelManager = modelManager;
+ this.queryService = queryService;
}
// ======================================================================
@@ -80,18 +168,22 @@ final class ReadRequestHandler {
*/
public List<MeasuredValues> execute(ReadRequest readRequest) throws DataAccessException {
ValueMatrix valueMatrix = null;
- Column[] columns = null;
+ Column[] arrColumns = null;
try {
valueMatrix = getValueMatrix(readRequest);
- columns = getODSColumns(readRequest, valueMatrix);
- NameValueSeqUnit[] nvsus = valueMatrix.getValue(columns, readRequest.getStartIndex(),
+ List<Pair<Column, ColumnAttributes>> listColumnPairs = getODSColumns(readRequest, valueMatrix);
+
+ arrColumns = listColumnPairs.stream().map(Pair::getLeft).toArray(Column[]::new);
+ ColumnAttributes[] arrColumnAttributes = listColumnPairs.stream().map(Pair::getRight).toArray(ColumnAttributes[]::new);
+
+ NameValueSeqUnit[] nvsus = valueMatrix.getValue(arrColumns, readRequest.getStartIndex(),
readRequest.getRequestSize());
- return ODSConverter.fromODSMeasuredValuesSeq(nvsus);
+ return ODSConverter.fromODSMeasuredValuesSeq(nvsus, arrColumnAttributes);
} catch (AoException aoe) {
throw new DataAccessException(aoe.reason, aoe);
} finally {
- releaseColumns(columns);
+ releaseColumns(arrColumns);
releaseValueMatrix(valueMatrix);
}
}
@@ -116,36 +208,120 @@ final class ReadRequestHandler {
* @throws DataAccessException
* Thrown on wrong {@code ReadRequest} setup.
*/
- private Column[] getODSColumns(ReadRequest readRequest, ValueMatrix valueMatrix)
+ private List<Pair<Column, ColumnAttributes>> getODSColumns(ReadRequest readRequest, ValueMatrix valueMatrix)
throws AoException, DataAccessException {
- if (readRequest.isLoadAllChannels()) {
- // TODO should it be possible to overwrite the unit of some
- // channels?!
- // -> this results in a performance issue since we need to call
- // getName()
- // on each column for mapping!
- return valueMatrix.getColumns("*");
- }
+ List<Pair<Column, ColumnAttributes>> listColumnPairs = new ArrayList<>();
+ Map<String, Column> mapColumns = new HashMap<>();
- List<Column> columnList = new ArrayList<>();
try {
- for (Entry<Channel, Unit> entry : readRequest.getChannels().entrySet()) {
- Channel channel = entry.getKey();
- Unit unit = entry.getValue();
- Column[] columns = valueMatrix.getColumns(channel.getName());
- if (columns == null || columns.length != 1) {
- releaseColumns(columns);
- throw new DataAccessException("Column with name '" + channel.getName() + "' not found.");
+ if (readRequest.isLoadAllChannels()) {
+ // TODO should it be possible to overwrite the unit of some
+ // channels?!
+ // -> this results in a performance issue since we need to call
+ // getName()
+ // on each column for mapping! (no longer, see below!)
+ Column[] columns = valueMatrix.getColumns("*");
+
+ if (null != columns) {
+ for (Column column : columns) {
+ String columnName = column.getName();
+ if (mapColumns.containsKey(columnName))
+ {
+ releaseColumns(columns);
+ throw new DataAccessException(String.format("Duplicate column name '%s' found within submatrix ID %d!",
+ columnName, Long.valueOf(readRequest.getChannelGroup().getID())));
+ }
+
+ mapColumns.put(columnName, column);
+ }
+ }
+ } else {
+ for (Entry<Channel, Unit> entry : readRequest.getChannels().entrySet()) {
+ Channel channel = entry.getKey();
+ Unit unit = entry.getValue();
+ String channelName = channel.getName();
+ Column[] columns = valueMatrix.getColumns(channelName);
+ if (columns == null || columns.length != 1) {
+ releaseColumns(columns);
+ throw new DataAccessException(String.format("Zero or more than one column with name '%s' found within submatrix ID %d!",
+ channelName, Long.valueOf(readRequest.getChannelGroup().getID())));
+ }
+
+ Column column = columns[0];
+ if (!unit.nameEquals(channel.getUnit().getName())) {
+ column.setUnit(unit.getName());
+ }
+
+ mapColumns.put(channelName, column);
+ }
+ }
+
+ if (mapColumns.size() > 0) {
+ EntityType localColumnEntityType = modelManager.getEntityType("LocalColumn");
+ Attribute idAttr = localColumnEntityType.getAttribute("Id");
+ Attribute nameAttr = localColumnEntityType.getAttribute("Name");
+ Attribute submatrixAttr = localColumnEntityType.getAttribute("SubMatrix");
+
+ // Don't query GenerationParameters together with other non-ID attributes as Avalon dislikes this:
+ Query query1 = queryService.createQuery()
+ .select(Lists.newArrayList(idAttr,
+ nameAttr,
+ localColumnEntityType.getAttribute("SequenceRepresentation"),
+ localColumnEntityType.getAttribute("IndependentFlag"),
+ localColumnEntityType.getAttribute("axistype")));
+
+
+
+ Filter filter = Filter.and()
+ .add(ComparisonOperator.EQUAL.create(submatrixAttr, Long.valueOf(readRequest.getChannelGroup().getID())));
+
+ Set<String> setColumnNames = mapColumns.keySet();
+
+ Map<Long, ColumnAttributes> mapColumnAttributes = new HashMap<>();
+
+ for (Result result : query1.fetch(filter)) {
+ Map<String, Value> mapValues = result.getRecord(localColumnEntityType).getValues();
+
+ String columnName = mapValues.get("Name").extract();
+
+ if (setColumnNames.contains(columnName))
+ {
+ ColumnAttributes ca = new ColumnAttributes(columnName,
+ (ValuesMode.CALCULATED == readRequest.getValuesMode() ? SequenceRepresentation.EXPLICIT : mapValues.get("SequenceRepresentation").extract()),
+ new double[0],
+ ((short) mapValues.get("IndependentFlag").extract() != 0),
+ mapValues.get("axistype").extract());
+
+ mapColumnAttributes.put(mapValues.get("Id").extract(), ca);
+ }
+ }
+
+ if (ValuesMode.CALCULATED != readRequest.getValuesMode())
+ {
+ Query query2 = queryService.createQuery()
+ .select(idAttr,
+ localColumnEntityType.getAttribute("GenerationParameters"));
+
+ for (Result result : query2.fetch(filter)) {
+ Map<String, Value> mapValues = result.getRecord(localColumnEntityType).getValues();
+
+ ColumnAttributes ca = mapColumnAttributes.get(mapValues.get("Id").extract());
+
+ if (ca != null) {
+ ca.setGenerationParameters(mapValues.get("GenerationParameters").extract());
+ }
+ }
}
- Column column = columns[0];
- if (!unit.nameEquals(channel.getUnit().getName())) {
- column.setUnit(unit.getName());
+
+ for (Map.Entry<Long, ColumnAttributes> me : mapColumnAttributes.entrySet()) {
+ ColumnAttributes ca = me.getValue();
+ listColumnPairs.add(new ImmutablePair<Column, ColumnAttributes>(mapColumns.get(ca.getName()), ca));
}
- columnList.add(column);
}
- return columnList.toArray(new Column[columnList.size()]);
+
+ return listColumnPairs;
} catch (AoException e) {
- releaseColumns(columnList.toArray(new Column[columnList.size()]));
+ releaseColumns(listColumnPairs.stream().map(Pair::getLeft).toArray(Column[]::new));
throw new DataAccessException("Unable to load column due to: " + e.reason, e);
}
}
@@ -164,7 +340,17 @@ final class ReadRequestHandler {
Entity entity = readRequest.getChannelGroup();
T_LONGLONG iid = ODSConverter.toODSID(entity.getID());
T_LONGLONG aid = ((ODSEntityType) modelManager.getEntityType(entity)).getODSID();
- return modelManager.getApplElemAccess().getValueMatrixInMode(new ElemId(aid, iid), ValueMatrixMode.CALCULATED);
+ ValueMatrixMode valueMatrixMode = ValueMatrixMode.CALCULATED;
+ switch (readRequest.getValuesMode())
+ {
+ case CALCULATED: valueMatrixMode = ValueMatrixMode.CALCULATED; break;
+ case STORAGE: valueMatrixMode = ValueMatrixMode.STORAGE; break;
+ default:
+ throw new DataAccessException(
+ String.format("Unsupported ValueMode %s!", readRequest.getValuesMode().name()));
+ }
+
+ return modelManager.getApplElemAccess().getValueMatrixInMode(new ElemId(aid, iid), valueMatrixMode);
}
/**
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/DefaultEntityConfigRepositoryLoader.java b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/DefaultEntityConfigRepositoryLoader.java
new file mode 100644
index 0000000..5f17e54
--- /dev/null
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/DefaultEntityConfigRepositoryLoader.java
@@ -0,0 +1,336 @@
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.odsadapter.lookup.config;
+
+import java.util.Locale;
+
+import org.eclipse.mdm.api.base.adapter.EntityType;
+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.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.Role;
+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.Key;
+import org.eclipse.mdm.api.odsadapter.query.ODSEntityType;
+import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
+import org.eclipse.mdm.api.odsadapter.utils.ODSUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DefaultEntityConfigRepositoryLoader implements EntityConfigRepositoryLoader {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultEntityConfigRepositoryLoader.class);
+
+ EntityConfigRepository entityConfigRepository;
+
+
+ public DefaultEntityConfigRepositoryLoader() {
+ }
+
+ /**
+ * Loads the {@link EntityConfig}s.
+ * @return
+ */
+ @Override
+ public EntityConfigRepository loadEntityConfigurations(ODSModelManager modelManager) {
+ LOGGER.debug("Loading entity configurations...");
+ long start = System.currentTimeMillis();
+
+ entityConfigRepository = new EntityConfigRepository();
+
+ entityConfigRepository.register(create(modelManager, new Key<>(Role.class), "Role", false));
+
+ // Environment | Project | Pool | PhysicalDimension | User | Measurement
+ // | ChannelGroup
+ entityConfigRepository.register(create(modelManager, new Key<>(Environment.class), "Environment", false));
+ entityConfigRepository.register(create(modelManager, new Key<>(Project.class), "Project", false));
+ entityConfigRepository.register(create(modelManager, new Key<>(Pool.class), "StructureLevel", true));
+ entityConfigRepository.register(create(modelManager, new Key<>(PhysicalDimension.class), "PhysDimension", false));
+ entityConfigRepository.register(create(modelManager, new Key<>(User.class), "User", false));
+ entityConfigRepository.register(create(modelManager, new Key<>(Measurement.class), "MeaResult", false));
+ entityConfigRepository.register(create(modelManager, new Key<>(ChannelGroup.class), "SubMatrix", false));
+
+ // Unit
+ EntityConfig<Unit> unitConfig = create(modelManager, new Key<>(Unit.class), "Unit", false);
+ unitConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(PhysicalDimension.class)));
+ entityConfigRepository.register(unitConfig);
+
+ // Quantity
+ EntityConfig<Quantity> quantityConfig = create(modelManager, new Key<>(Quantity.class), "Quantity", false);
+ quantityConfig.addMandatory(entityConfigRepository.findRoot(new Key<>(Unit.class)));
+ entityConfigRepository.register(quantityConfig);
+
+ // Channel
+ EntityConfig<Channel> channelConfig = create(modelManager, 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(modelManager, new Key<>(ValueListValue.class), "ValueListValue",
+ true);
+ valueListValueConfig.setComparator(Sortable.COMPARATOR);
+ EntityConfig<ValueList> valueListConfig = create(modelManager, new Key<>(ValueList.class), "ValueList", true);
+ valueListConfig.addChild(valueListValueConfig);
+ entityConfigRepository.register(valueListConfig);
+
+ // ParameterSet
+ EntityConfig<Parameter> parameterConfig = create(modelManager, new Key<>(Parameter.class), "ResultParameter", true);
+ parameterConfig.addOptional(entityConfigRepository.findRoot(new Key<>(Unit.class)));
+ EntityConfig<ParameterSet> parameterSetConfig = create(modelManager, new Key<>(ParameterSet.class), "ResultParameterSet",
+ true);
+ parameterSetConfig.addChild(parameterConfig);
+ entityConfigRepository.register(parameterSetConfig);
+
+ // CatalogComponents
+ registerCatalogComponent(modelManager, ContextType.UNITUNDERTEST);
+ registerCatalogComponent(modelManager, ContextType.TESTSEQUENCE);
+ registerCatalogComponent(modelManager, ContextType.TESTEQUIPMENT);
+
+ // TemplateRoots
+ registerTemplateRoot(modelManager, ContextType.UNITUNDERTEST);
+ registerTemplateRoot(modelManager, ContextType.TESTSEQUENCE);
+ registerTemplateRoot(modelManager, ContextType.TESTEQUIPMENT);
+
+ // TemplateTestStep
+ EntityConfig<TemplateTestStep> templateTestStepConfig = create(modelManager, 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(modelManager, 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(modelManager, new Key<>(TemplateTestStepUsage.class),
+ "TplTestStepUsage", true);
+ templateTestStepUsageConfig.addMandatory(templateTestStepConfig);
+ templateTestStepUsageConfig.setComparator(Sortable.COMPARATOR);
+ EntityConfig<TemplateTest> templateTestConfig = create(modelManager, 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(modelManager, 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(modelManager, ContextType.UNITUNDERTEST);
+ registerContextRoot(modelManager, ContextType.TESTSEQUENCE);
+ registerContextRoot(modelManager, ContextType.TESTEQUIPMENT);
+
+ LOGGER.debug("Entity configurations loaded in {} ms.", System.currentTimeMillis() - start);
+ return entityConfigRepository;
+ }
+
+ /**
+ * Loads the {@link EntityConfig}s required for {@link ContextRoot} with
+ * given {@link ContextType}.
+ *
+ * @param contextType
+ * The {@code ContextType}.
+ */
+ private void registerContextRoot(ODSModelManager modelManager, ContextType contextType) {
+ EntityConfig<ContextRoot> contextRootConfig = create(modelManager, 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(modelManager,
+ 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(modelManager, 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(ODSModelManager modelManager, ContextType contextType) {
+ String odsName = ODSUtils.CONTEXTTYPES.get(contextType);
+ EntityConfig<TemplateAttribute> templateAttributeConfig = create(modelManager,
+ 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(modelManager,
+ 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(modelManager, new Key<>(TemplateAttribute.class),
+ "TplSensorAttr", true);
+ templateSensorAttributeConfig.setComparator(TemplateAttribute.COMPARATOR);
+ templateSensorAttributeConfig
+ .addInherited(entityConfigRepository.findImplicit(new Key<>(CatalogAttribute.class)));
+ EntityConfig<TemplateSensor> templateSensorConfig = create(modelManager, 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(modelManager, 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(ODSModelManager modelManager, ContextType contextType) {
+ String odsName = ODSUtils.CONTEXTTYPES.get(contextType);
+ EntityConfig<CatalogAttribute> catalogAttributeConfig = create(modelManager, 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(modelManager, new Key<>(CatalogComponent.class, contextType),
+ "Cat" + odsName + "Comp", true);
+ catalogComponentConfig.addChild(catalogAttributeConfig);
+ if (contextType.isTestEquipment()) {
+ EntityConfig<CatalogAttribute> catalogSensorAttributeConfig = create(modelManager, new Key<>(CatalogAttribute.class),
+ "CatSensorAttr", true);
+ catalogSensorAttributeConfig.addOptional(entityConfigRepository.findRoot(new Key<>(ValueList.class)));
+ EntityConfig<CatalogSensor> catalogSensorConfig = create(modelManager, 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(ODSModelManager modelManager, Key<T> key, String typeName, boolean appendName) {
+ EntityConfig<T> entityConfig = new EntityConfig<>(key);
+ ODSEntityType entityType = (ODSEntityType) modelManager.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/lookup/config/EntityConfigRepositoryLoader.java b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/EntityConfigRepositoryLoader.java
new file mode 100644
index 0000000..80b205d
--- /dev/null
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/EntityConfigRepositoryLoader.java
@@ -0,0 +1,26 @@
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+package org.eclipse.mdm.api.odsadapter.lookup.config;
+
+import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
+
+public interface EntityConfigRepositoryLoader {
+
+ /**
+ * Loads the {@link EntityConfigRepository}.
+ * @return
+ */
+ EntityConfigRepository loadEntityConfigurations(ODSModelManager modelManager);
+}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityFactory.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityFactory.java
index c66516f..14d5d19 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityFactory.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityFactory.java
@@ -1,16 +1,16 @@
-/********************************************************************************
- * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- ********************************************************************************/
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
package org.eclipse.mdm.api.odsadapter.query;
@@ -76,7 +76,7 @@ public final class ODSEntityFactory extends EntityFactory {
// ======================================================================
private final ODSModelManager modelManager;
- private final User loggedInUser;
+ private final Optional<User> loggedInUser;
// ======================================================================
// Constructors
@@ -90,7 +90,7 @@ public final class ODSEntityFactory extends EntityFactory {
* @param loggedInUser
* The logged in {@link User}.
*/
- public ODSEntityFactory(ODSModelManager modelManager, User loggedInUser) {
+ public ODSEntityFactory(ODSModelManager modelManager, Optional<User> loggedInUser) {
this.modelManager = modelManager;
this.loggedInUser = loggedInUser;
}
@@ -153,7 +153,7 @@ public final class ODSEntityFactory extends EntityFactory {
*/
@Override
protected Optional<User> getLoggedInUser() {
- return Optional.of(loggedInUser);
+ return loggedInUser;
}
/**
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 6efe7f3..b1e9b07 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
@@ -21,7 +21,6 @@ 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;
@@ -49,52 +48,19 @@ 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.Classification;
-import org.eclipse.mdm.api.dflt.model.Domain;
-import org.eclipse.mdm.api.dflt.model.Pool;
-import org.eclipse.mdm.api.dflt.model.Project;
-import org.eclipse.mdm.api.dflt.model.ProjectDomain;
-import org.eclipse.mdm.api.dflt.model.Status;
-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.DefaultEntityConfigRepositoryLoader;
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.lookup.config.EntityConfigRepositoryLoader;
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;
@@ -118,6 +84,7 @@ public class ODSModelManager implements ModelManager {
private final Lock read;
private EntityConfigRepository entityConfigRepository;
+ private EntityConfigRepositoryLoader entityConfigRepositoryLoader;
private ApplElemAccess applElemAccess;
private AoSession aoSession;
@@ -133,10 +100,25 @@ public class ODSModelManager implements ModelManager {
* Thrown on errors.
*/
public ODSModelManager(ORB orb, AoSession aoSession) throws AoException {
+ this(orb, aoSession, new DefaultEntityConfigRepositoryLoader());
+ }
+
+ /**
+ * 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, EntityConfigRepositoryLoader entityConfigRepositoryLoader) throws AoException {
this.aoSession = aoSession;
this.orb = orb;
applElemAccess = aoSession.getApplElemAccess();
-
+ this.entityConfigRepositoryLoader = entityConfigRepositoryLoader;
+
// setup locks
ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
write = reentrantReadWriteLock.writeLock();
@@ -368,7 +350,7 @@ public class ODSModelManager implements ModelManager {
*/
private void initialize() throws AoException {
loadApplicationModel();
- loadEntityConfigurations();
+ entityConfigRepository = entityConfigRepositoryLoader.loadEntityConfigurations(this);
}
/**
@@ -428,7 +410,7 @@ public class ODSModelManager implements ModelManager {
EnumerationDefinition bubu = applicationStructure.getEnumerationDefinition(eas.enumName);
for (String itemName : bubu.listItemNames()) {
final int intValue = bubu.getItem(itemName);
- LOGGER.debug("{}:{}:{}", eas.enumName, itemName, intValue);
+ LOGGER.trace("{}:{}:{}", eas.enumName, itemName, intValue);
}
// make sure the enumeration is found
@@ -482,284 +464,4 @@ public class ODSModelManager implements ModelManager {
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<>(ChannelGroup.class), "SubMatrix", false));
- entityConfigRepository.register(create(new Key<>(Status.class), "Status", true));
-
- // Project Domain
- EntityConfig<ProjectDomain> projectDomainEntityConfig = create(new Key<>(ProjectDomain.class), "ProjectDomain", true);
- entityConfigRepository.register(projectDomainEntityConfig);
-
- // Domain
- EntityConfig<Domain> domainEntityConfig = create(new Key<>(Domain.class), "Domain", true);
- entityConfigRepository.register(domainEntityConfig);
-
- // Classification
- EntityConfig<Classification> classificationEntityConfig = create(new Key<>(Classification.class), "Classification", true);
- classificationEntityConfig.addOptional(entityConfigRepository.findRoot(new Key<>(ProjectDomain.class)));
- classificationEntityConfig.addOptional(entityConfigRepository.findRoot(new Key<>(Domain.class)));
- classificationEntityConfig.addOptional(entityConfigRepository.findRoot(new Key<>(Status.class)));
- entityConfigRepository.register(classificationEntityConfig);
-
- EntityConfig<Measurement> measurementEntityConfig = create(new Key<>(Measurement.class), "MeaResult", false);
- measurementEntityConfig.addOptional(entityConfigRepository.findRoot(new Key<>(Classification.class)));
- entityConfigRepository.register(measurementEntityConfig);
-
- // 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/ODSRelation.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSRelation.java
index a6055c3..a623d0e 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
@@ -44,7 +44,7 @@ public final class ODSRelation implements Relation {
private final String name;
private final int rangeMax;
-
+ private final int invRangeMax;
private Attribute attribute;
// ======================================================================
@@ -67,6 +67,7 @@ public final class ODSRelation implements Relation {
name = applRel.arName;
relationType = ODSUtils.RELATIONSHIPS.inverse().get(applRel.arRelationType);
rangeMax = applRel.arRelationRange.max;
+ invRangeMax = applRel.invRelationRange.max;
}
// ======================================================================
@@ -164,5 +165,10 @@ public final class ODSRelation implements Relation {
public boolean isIncoming(RelationType relationType) {
return relationType.equals(getRelationType()) && rangeMax == -1;
}
+
+ @Override
+ public boolean isNtoM() {
+ return relationType == RelationType.INFO && rangeMax == -1 && invRangeMax == -1;
+ }
}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/InsertStatement.java b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/InsertStatement.java
index 0fc5e90..b7fff30 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/InsertStatement.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/InsertStatement.java
@@ -1,16 +1,16 @@
-/********************************************************************************
- * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- ********************************************************************************/
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
package org.eclipse.mdm.api.odsadapter.transaction;
@@ -272,14 +272,15 @@ final class InsertStatement extends BaseStatement {
EntityType test = getModelManager().getEntityType(Test.class);
Relation parentRelation = testStep.getRelation(test);
+ Attribute attrSortIndex = testStep.getAttribute(Sortable.ATTR_SORT_INDEX);
Query query = getQueryService().createQuery().select(parentRelation.getAttribute())
- .select(testStep.getAttribute(Sortable.ATTR_SORT_INDEX), Aggregation.MAXIMUM)
+ .select(attrSortIndex, Aggregation.MAXIMUM)
.group(parentRelation.getAttribute());
Filter filter = Filter.idsOnly(parentRelation, sortIndexTestSteps.keySet());
for (Result result : query.fetch(filter)) {
Record record = result.getRecord(testStep);
- int sortIndex = (Integer) record.getValues().get(Sortable.ATTR_SORT_INDEX).extract();
+ int sortIndex = (Integer) record.getValues().get(ODSConverter.getColumnName(attrSortIndex, Aggregation.MAXIMUM)).extract();
sortIndexTestSteps.remove(record.getID(parentRelation).get()).setIndices(sortIndex + 1);
}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/ODSTransaction.java b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/ODSTransaction.java
index a4bf4b9..3fe7ce2 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/ODSTransaction.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/ODSTransaction.java
@@ -1,16 +1,16 @@
-/********************************************************************************
- * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- ********************************************************************************/
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
package org.eclipse.mdm.api.odsadapter.transaction;
@@ -18,6 +18,7 @@ package org.eclipse.mdm.api.odsadapter.transaction;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -28,9 +29,13 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import org.asam.ods.AoException;
+import org.asam.ods.ElemId;
+import org.asam.ods.SetType;
+import org.asam.ods.T_LONGLONG;
import org.eclipse.mdm.api.base.Transaction;
import org.eclipse.mdm.api.base.adapter.Core;
import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.adapter.Relation;
import org.eclipse.mdm.api.base.massdata.WriteRequest;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ContextRoot;
@@ -49,7 +54,10 @@ import org.eclipse.mdm.api.dflt.model.CatalogSensor;
import org.eclipse.mdm.api.dflt.model.TemplateAttribute;
import org.eclipse.mdm.api.odsadapter.ODSContext;
import org.eclipse.mdm.api.odsadapter.filetransfer.Transfer;
+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.utils.ODSConverter;
import org.eclipse.mdm.api.odsadapter.utils.ODSUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -170,13 +178,16 @@ public final class ODSTransaction implements Transaction {
List<Measurement> measurements = (List<Measurement>) entitiesByClassType.get(Measurement.class);
if (measurements != null) {
- // use set here, since measurement sibling point to the same
- // context roots
- create(measurements.stream().map(ContextRoot::of).collect(HashSet::new, Set::addAll, Set::addAll));
+ // Use set here, since measurement siblings point to the same
+ // context roots. Only create those ContextRoots that haven't been created yet:
+ create(measurements.stream().map(ContextRoot::of)
+ .collect(HashSet<ContextRoot>::new, Set<ContextRoot>::addAll, Set<ContextRoot>::addAll)
+ .stream().filter(cr -> !ODSUtils.isValidID(cr.getID())).collect(Collectors.toSet()));
}
executeStatements(et -> new InsertStatement(this, et), entities);
-
+ processNtoMRelations(entities);
+
List<ContextRoot> roots = (List<ContextRoot>) entitiesByClassType.get(ContextRoot.class);
if (roots != null) {
roots.forEach(contextRoot -> {
@@ -224,6 +235,7 @@ public final class ODSTransaction implements Transaction {
}
}
executeStatements(et -> new UpdateStatement(this, et, false), entities);
+ processNtoMRelations(entities);
} catch (AoException e) {
throw new DataAccessException("Unable to update entities due to: " + e.reason, e);
} catch (IOException e) {
@@ -491,6 +503,55 @@ public final class ODSTransaction implements Transaction {
}
/**
+ * Processes N-to-M relations for the given entities
+ * @param entities
+ * The processed {@code Entity}s.
+ * @throws DataAccessException
+ * Thrown if the execution fails.
+ */
+ private <T extends Entity> void processNtoMRelations(Collection<T> entities) {
+ for (Entity e : entities) {
+ context.getODSModelManager().getEntityType(e)
+ .getRelations()
+ .stream()
+ .filter(Relation::isNtoM)
+ .forEach(r -> processMtoMRelation(e, r));
+ }
+ }
+
+ private void processMtoMRelation(Entity entity, Relation relation) {
+
+ List<? extends Deletable> removedRelatedEntities = ODSEntityFactory.extract(entity).getNtoMStore().getRemoved().getOrDefault(relation.getName(), Collections.emptyList());
+ List<? extends Deletable> addedRelatedEntities = ODSEntityFactory.extract(entity).getNtoMStore().getAdded().getOrDefault(relation.getName(), Collections.emptyList());
+
+ T_LONGLONG[] removedInstIds = removedRelatedEntities.stream()
+ .map(Entity::getID)
+ .map(ODSConverter::toODSID)
+ .toArray(T_LONGLONG[]::new);
+
+ T_LONGLONG[] addedInstIds = addedRelatedEntities.stream()
+ .map(Entity::getID)
+ .map(ODSConverter::toODSID)
+ .toArray(T_LONGLONG[]::new);
+
+ try {
+ if (removedInstIds.length > 0) {
+ ODSEntityType entityType = ((ODSEntityType) context.getODSModelManager().getEntityType(entity));
+ ElemId elemId = new ElemId(entityType.getODSID(), ODSConverter.toODSID(entity.getID()));
+ context.getAoSession().getApplElemAccess().setRelInst(elemId, relation.getName(), removedInstIds, SetType.REMOVE);
+ }
+
+ if (addedInstIds.length > 0) {
+ ODSEntityType entityType = ((ODSEntityType) context.getODSModelManager().getEntityType(entity));
+ ElemId elemId = new ElemId(entityType.getODSID(), ODSConverter.toODSID(entity.getID()));
+ context.getAoSession().getApplElemAccess().setRelInst(elemId, relation.getName(), addedInstIds, SetType.APPEND);
+ }
+ } catch (AoException e) {
+ throw new DataAccessException("" + e.reason, e); // TODO
+ }
+ }
+
+ /**
* Closes the co-session of this transaction.
*/
private void closeSession() {
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/UpdateStatement.java b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/UpdateStatement.java
index f6fa7c8..300fcfd 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/UpdateStatement.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/UpdateStatement.java
@@ -1,16 +1,16 @@
-/********************************************************************************
- * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- ********************************************************************************/
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
package org.eclipse.mdm.api.odsadapter.transaction;
@@ -39,6 +39,7 @@ import org.eclipse.mdm.api.base.model.FileLink;
import org.eclipse.mdm.api.base.model.FilesAttachable;
import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.base.query.DataAccessException;
+import org.eclipse.mdm.api.dflt.model.Role;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig;
import org.eclipse.mdm.api.odsadapter.query.ODSEntityFactory;
import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;
@@ -126,6 +127,10 @@ final class UpdateStatement extends BaseStatement {
// skip "empty" informative relation sequence
continue;
}
+ if (entry.getKey().equalsIgnoreCase(Role.ATTR_SUPERUSER_FLAG)) {
+ // skip superuser flag as it cannot be written through the ODS API
+ continue;
+ }
Attribute attribute = getEntityType().getAttribute(entry.getKey());
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/WriteRequestHandler.java b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/WriteRequestHandler.java
index 34c8d2c..86610a9 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/WriteRequestHandler.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/WriteRequestHandler.java
@@ -1,16 +1,16 @@
-/********************************************************************************
- * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- ********************************************************************************/
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
package org.eclipse.mdm.api.odsadapter.transaction;
@@ -127,7 +127,7 @@ public final class WriteRequestHandler {
Map<String, Value> values = core.getValues();
values.get(Entity.ATTR_NAME).set(writeRequest.getChannel().getName());
values.get(Entity.ATTR_MIMETYPE).set("application/x-asam.aolocalcolumn");
- values.get(AE_LC_ATTR_INDEPENDENT).set(ODSConverter.toODSValidFlag(writeRequest.isIndependent()));
+ values.get(AE_LC_ATTR_INDEPENDENT).set((short) (writeRequest.isIndependent() ? 1 : 0));
values.get(AE_LC_ATTR_RAWDATATYPE).set(writeRequest.getRawScalarType());
values.get(AE_LC_ATTR_REPRESENTATION).set(writeRequest.getSequenceRepresentation());
values.get(AE_LC_ATTR_AXISTYPE).set(writeRequest.getAxisType());
@@ -138,10 +138,13 @@ public final class WriteRequestHandler {
String unitName = writeRequest.getChannel().getUnit().getName();
values.put(AE_LC_ATTR_VALUES,
valueType.create(AE_LC_ATTR_VALUES, unitName, true, writeRequest.getValues()));
-
+
+ // OpenATFX issue: For "implicit" columns, if no value for the GenerationParameters attribute is present,
+ // it is attempted to transfer the local column values (through which the generation parameters are
+ // available in these cases) to the GenerationParameters attribute without converting them to the
+ // correct DS_DOUBLE data type first (unless it is a DOUBLE or LONG column), resulting in an exception.
+ // Hence, supply correctly converted generation parameters as a workaround:
if (writeRequest.getSequenceRepresentation().isImplicit()) {
- // PEAK ODS server: expects values written as generation
- // parameters
Object genParamValues = writeRequest.getValues();
double[] genParamD = new double[Array.getLength(genParamValues)];
IntStream.range(0, genParamD.length)
@@ -152,11 +155,6 @@ public final class WriteRequestHandler {
// flags
if (writeRequest.areAllValid()) {
values.get(AE_LC_ATTR_GLOBAL_FLAG).set((short) 15);
- // PEAK ODS server issue: though global flag is true a flags
- // array is expected
- short[] flags = new short[Array.getLength(writeRequest.getValues())];
- Arrays.fill(flags, (short) 15);
- values.get(AE_LC_ATTR_FLAGS).set(flags);
} else {
short[] flags = ODSConverter.toODSValidFlagSeq(writeRequest.getFlags());
values.get(AE_LC_ATTR_FLAGS).set(flags);
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 ae893ca..f0d146b 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
@@ -1,16 +1,16 @@
-/********************************************************************************
- * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- ********************************************************************************/
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
package org.eclipse.mdm.api.odsadapter.utils;
@@ -22,6 +22,7 @@ import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoField;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -50,6 +51,7 @@ import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.base.model.ValueType;
import org.eclipse.mdm.api.base.query.Aggregation;
import org.eclipse.mdm.api.base.query.DataAccessException;
+import org.eclipse.mdm.api.odsadapter.ReadRequestHandler;
import org.eclipse.mdm.api.odsadapter.query.ODSAttribute;
import com.google.common.collect.Sets;
@@ -334,15 +336,26 @@ public final class ODSConverter {
&& attribute.getValueType().isEnumerationType()
&& Sets.immutableEnumSet(Aggregation.MINIMUM, Aggregation.MAXIMUM, Aggregation.DISTINCT)
.contains(aggregation)) {
- return valueType.create(String.format("%s(%s)", aggregation.name(), attribute.getName()), unit, valid,
+ return valueType.create(getColumnName(attribute, aggregation), unit, valid,
input, attribute.getEnumObj().getName());
} else {
- return valueType.create(String.format("%s(%s)", aggregation.name(), attribute.getName()), unit, valid,
+ return valueType.create(getColumnName(attribute, aggregation), unit, valid,
input);
}
}
}
+ /**
+ * Returns the name of the attribute with its applied aggregation as returned by the ODS Server,
+ * for example: MAXIMUM(sortIndex)
+ * @param attribute
+ * @param aggregation
+ * @return the name of the attribute with the applied aggragation
+ */
+ public static String getColumnName(Attribute attribute, Aggregation aggregation) {
+ return String.format("%s(%s)", aggregation.name(), attribute.getName());
+ }
+
private static String[] toString(int[] odsValues) {
return IntStream.of(odsValues).mapToObj(Integer::toString).toArray(String[]::new);
}
@@ -652,12 +665,18 @@ public final class ODSConverter {
* @throws DataAccessException
* Thrown on conversion errors.
*/
- public static List<MeasuredValues> fromODSMeasuredValuesSeq(NameValueSeqUnit[] odsMeasuredValuesSeq)
+ public static List<MeasuredValues> fromODSMeasuredValuesSeq(NameValueSeqUnit[] odsMeasuredValuesSeq, ReadRequestHandler.ColumnAttributes[] columnAttributesArray)
throws DataAccessException {
List<MeasuredValues> measuredValues = new ArrayList<>(odsMeasuredValuesSeq.length);
+
+ Map<String, ReadRequestHandler.ColumnAttributes> mapColumnAttributes = new HashMap<>();
+ if (null != columnAttributesArray)
+ {
+ Arrays.stream(columnAttributesArray).forEach(ca -> mapColumnAttributes.put(ca.getName(), ca));
+ }
for (NameValueSeqUnit odsMeasuredValues : odsMeasuredValuesSeq) {
- measuredValues.add(fromODSMeasuredValues(odsMeasuredValues));
+ measuredValues.add(fromODSMeasuredValues(odsMeasuredValues, mapColumnAttributes.get(odsMeasuredValues.valName)));
}
return measuredValues;
@@ -672,7 +691,7 @@ public final class ODSConverter {
* @throws DataAccessException
* Thrown on conversion errors.
*/
- private static MeasuredValues fromODSMeasuredValues(NameValueSeqUnit odsMeasuredValues) throws DataAccessException {
+ private static MeasuredValues fromODSMeasuredValues(NameValueSeqUnit odsMeasuredValues, ReadRequestHandler.ColumnAttributes columnAttributes) throws DataAccessException {
TS_ValueSeq odsValueSeq = odsMeasuredValues.value;
DataType dataType = odsValueSeq.u.discriminator();
ScalarType scalarType;
@@ -721,8 +740,19 @@ public final class ODSConverter {
throw new DataAccessException(
"Conversion for ODS measured points of type '" + dataType.toString() + "' does not exist.");
}
+
+ if (null == columnAttributes)
+ {
+ columnAttributes = new ReadRequestHandler.ColumnAttributes("", null, new double[0], false, null);
+ }
- return scalarType.createMeasuredValues(odsMeasuredValues.valName, odsMeasuredValues.unit, values,
+ return scalarType.createMeasuredValues(odsMeasuredValues.valName,
+ odsMeasuredValues.unit,
+ columnAttributes.getSequenceRepresentation(),
+ columnAttributes.getGenerationParameters(),
+ columnAttributes.isIndependentColumn(),
+ columnAttributes.getAxisType(),
+ values,
fromODSValidFlagSeq(odsValueSeq.flag));
}
diff --git a/src/test/java/org/eclipse/mdm/api/odsadapter/ODSRoleTest.java b/src/test/java/org/eclipse/mdm/api/odsadapter/ODSRoleTest.java
new file mode 100644
index 0000000..88a2f31
--- /dev/null
+++ b/src/test/java/org/eclipse/mdm/api/odsadapter/ODSRoleTest.java
@@ -0,0 +1,209 @@
+/********************************************************************************
+ * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+
+package org.eclipse.mdm.api.odsadapter;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_NAMESERVICE;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_PASSWORD;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_SERVICENAME;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_USER;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.mdm.api.base.ConnectionException;
+import org.eclipse.mdm.api.base.ServiceNotProvidedException;
+import org.eclipse.mdm.api.base.Transaction;
+import org.eclipse.mdm.api.base.model.User;
+import org.eclipse.mdm.api.dflt.ApplicationContext;
+import org.eclipse.mdm.api.dflt.EntityManager;
+import org.eclipse.mdm.api.dflt.model.EntityFactory;
+import org.eclipse.mdm.api.dflt.model.Role;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+//@Ignore
+// FIXME 10.7.2017: this test needs a running ODS Server, that is not suitable for continous build in Jenkins.
+// Comment this in for local tests only.
+public class ODSRoleTest {
+
+ /*
+ * ATTENTION: ==========
+ *
+ * To run this test make sure the target service is running a MDM default
+ * model and any database constraint which enforces a relation of Test to a
+ * parent entity is deactivated!
+ */
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ODSRoleTest.class);
+
+ private static final String NAME_SERVICE = "corbaloc::1.2@%s:%s/NameService";
+
+ private static final String USER = "sa";
+ private static final String PASSWORD = "sa";
+
+ private static ApplicationContext context;
+ private static EntityManager em;
+ private static EntityFactory entityFactory;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws ConnectionException {
+ String nameServiceHost = System.getProperty("host");
+ String nameServicePort = System.getProperty("port");
+ String serviceName = System.getProperty("service");
+
+ if (nameServiceHost == null || nameServiceHost.isEmpty()) {
+ throw new IllegalArgumentException("name service host is unknown: define system property 'host'");
+ }
+
+ nameServicePort = nameServicePort == null || nameServicePort.isEmpty() ? String.valueOf(2809) : nameServicePort;
+ if (nameServicePort == null || nameServicePort.isEmpty()) {
+ throw new IllegalArgumentException("name service port is unknown: define system property 'port'");
+ }
+
+ if (serviceName == null || serviceName.isEmpty()) {
+ throw new IllegalArgumentException("service name is unknown: define system property 'service'");
+ }
+
+ Map<String, String> connectionParameters = new HashMap<>();
+ connectionParameters.put(PARAM_NAMESERVICE, String.format(NAME_SERVICE, nameServiceHost, nameServicePort));
+ connectionParameters.put(PARAM_SERVICENAME, serviceName + ".ASAM-ODS");
+ connectionParameters.put(PARAM_USER, USER);
+ connectionParameters.put(PARAM_PASSWORD, PASSWORD);
+
+ context = new ODSContextFactory().connect(connectionParameters);
+ em = context.getEntityManager()
+ .orElseThrow(() -> new ServiceNotProvidedException(EntityManager.class));
+ entityFactory = context.getEntityFactory()
+ .orElseThrow(() -> new IllegalStateException("Entity manager factory not available."));
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws ConnectionException {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ @org.junit.Test
+ public void testLoadRelatedUsers() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ User user = em.loadAll(User.class, "sa").get(0);
+ List<Role> role = em.loadRelatedEntities(user, "users2groups", Role.class);
+
+ assertThat(role).hasSize(1).extracting(Role::getName).containsExactly("MDMSystemAdministrator");
+ }
+
+ @org.junit.Test
+ public void testLoadRelatedRoles() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ Role role = em.loadAll(Role.class, "MDMSystemAdministrator").get(0);
+ List<User> user = em.loadRelatedEntities(role, "groups2users", User.class);
+
+ assertThat(user).hasSize(1).extracting(User::getName).containsExactly("sa");
+ }
+
+ @org.junit.Test
+ public void testCreateUserAndRole() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ String userName = "CreateUserAndRole";
+ String roleName = "CreateUserAndRole";
+
+ try {
+ Transaction transaction = em.startTransaction();
+ User user = entityFactory.createUser(userName, "Test", "User");
+ Role role = entityFactory.createRole(roleName);
+ role.addUser(user);
+
+ transaction.create(Arrays.asList(user, role));
+ transaction.commit();
+
+ assertThat(em.loadRelatedEntities(role, "users2groups", User.class))
+ .hasSize(1)
+ .extracting(User::getName)
+ .contains(userName);
+
+ assertThat(em.loadRelatedEntities(user, "groups2users", Role.class))
+ .hasSize(1)
+ .extracting(Role::getName)
+ .contains(roleName);
+ } finally {
+ Transaction transaction = em.startTransaction();
+ List<User> users = em.loadAll(User.class, userName);
+ transaction.delete(users);
+ List<Role> roles = em.loadAll(Role.class, roleName);
+ transaction.delete(roles);
+ transaction.commit();
+ }
+ }
+
+ @org.junit.Test
+ public void testAddMultipleUsersToNewRole() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ String roleName = "AddMultipleUsersToNewRole";
+ try {
+ Transaction transaction = em.startTransaction();
+ List<User> users = em.loadAll(User.class);
+ Role role = entityFactory.createRole(roleName);
+
+ users.forEach(u -> role.addUser(u));
+ transaction.create(Arrays.asList(role));
+ transaction.commit();
+
+ assertThat(em.loadRelatedEntities(role, "users2groups", User.class))
+ .hasSize(users.size());
+ } finally {
+ Transaction transaction = em.startTransaction();
+ List<Role> roles = em.loadAll(Role.class, roleName);
+ transaction.delete(roles);
+ transaction.commit();
+ }
+ }
+
+ @org.junit.Test
+ public void testRemoveUserFromRole() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ String userName = "RemoveUserFromRole";
+ try {
+ Transaction transaction = em.startTransaction();
+ Role role = em.load(Role.class, "1");
+ User user = entityFactory.createUser(userName, "User", "User");
+
+ role.addUser(user);
+
+ transaction.create(Arrays.asList(user));
+ transaction.update(Arrays.asList(role));
+ transaction.commit();
+
+ assertThat(em.loadRelatedEntities(role, "groups2users", User.class))
+ .hasSize(2);
+
+ Role role2 = em.load(Role.class, "1");
+ transaction = em.startTransaction();
+ role2.removeUser(user);
+ transaction.update(Arrays.asList(role2));
+ transaction.commit();
+
+ assertThat(em.loadRelatedEntities(role2, "groups2users", User.class))
+ .hasSize(1);
+ } finally {
+ Transaction transaction = em.startTransaction();
+ List<User> users = em.loadAll(User.class, userName);
+ transaction.delete(users);
+ transaction.commit();
+ }
+ }
+}

Back to the top