diff --git a/.project b/.project
new file mode 100644
index 0000000..486c5b9
--- /dev/null
+++ b/.project
@@ -0,0 +1,11 @@
+
+
+ _
+
+
+
+
+
+
+
+
diff --git a/Jenkinsfile b/Jenkinsfile
index 0de2e59..245f34c 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -30,13 +30,13 @@ pipeline {
sh "cp -r cnf/release/* $JENKINS_HOME/repo.gecko/snapshot/org.gecko.persistence"
}
}
- stage('Gitlab branch release') {
+ stage('Gitlab branch Build') {
when {
branch 'gitlab'
}
steps {
echo "I am building on ${env.JOB_NAME}"
- sh "./gradlew clean build release --info --stacktrace -Dmaven.repo.local=${WORKSPACE}/.m2"
+ sh "./gradlew clean build release --info --stacktrace -Dmaven.repo.local=${WORKSPACE}/.m2 --no-daemon"
sh "mkdir -p $JENKINS_HOME/repo.gecko/snapshot/org.gecko.emf.persistence_gitlab"
sh "rm -rf $JENKINS_HOME/repo.gecko/snapshot/org.gecko.emf.persistence_gitlab/*"
sh "cp -r cnf/release/* $JENKINS_HOME/repo.gecko/snapshot/org.gecko.emf.persistence_gitlab"
diff --git a/cnf/build.bnd b/cnf/build.bnd
index 5ac3817..798b0eb 100644
--- a/cnf/build.bnd
+++ b/cnf/build.bnd
@@ -13,8 +13,8 @@
dimcBaselining: true
mavenCentral: true
github-project: org.gecko.emf.persistence
-base-version: 6.1.1
-repository-base-version: 9.3.0.${tstamp}-SNAPSHOT
+base-version: 6.2.0
+repository-base-version: 9.4.0.${tstamp}-SNAPSHOT
# Maven Central Group-Id
# For Geckoprojects the groupid must start with org.geckoprojects
diff --git a/cnf/central.mvn b/cnf/central.mvn
index 32912df..d448d0e 100644
--- a/cnf/central.mvn
+++ b/cnf/central.mvn
@@ -142,8 +142,8 @@ org.freemarker:freemarker:2.3.32
org.geckoprojects.bnd:org.gecko.bnd.dimc.library:1.5.0
org.geckoprojects.bnd:org.gecko.bnd.jacoco.library:1.5.0
org.geckoprojects.bnd:org.gecko.bnd.osgitest.library:1.5.0
-org.geckoprojects.emf:org.gecko.emf.osgi.bnd.library.workspace:6.0.2
-org.geckoprojects.emf:org.gecko.emf.osgi.example.model.basic:6.0.2
+org.geckoprojects.emf:org.gecko.emf.osgi.bnd.library.workspace:6.2.0
+org.geckoprojects.emf:org.gecko.emf.osgi.example.model.basic:6.2.0
org.geckoprojects.emf.utils:org.gecko.emf.collections:2.2.2
org.mongodb:mongo-java-driver:3.12.14
org.geckoprojects.emf:org.gecko.emf.pushstreams:1.0.15
diff --git a/org.gecko.emf.mongo/launch.bndrun b/org.gecko.emf.mongo/launch.bndrun
index e139e58..2591983 100644
--- a/org.gecko.emf.mongo/launch.bndrun
+++ b/org.gecko.emf.mongo/launch.bndrun
@@ -10,20 +10,23 @@
org.apache.felix.gogo.runtime;version='[1.1.6,1.1.7)',\
org.apache.felix.gogo.shell;version='[1.1.4,1.1.5)',\
org.apache.felix.scr;version='[2.2.6,2.2.7)',\
- org.eclipse.emf.common;version='[2.28.0,2.28.1)',\
- org.eclipse.emf.ecore;version='[2.33.0,2.33.1)',\
- org.eclipse.emf.ecore.xmi;version='[2.18.0,2.18.1)',\
- org.gecko.emf.collections;version='[2.2.0,2.2.1)',\
org.gecko.emf.mongo.api;version=snapshot,\
org.gecko.emf.mongo.component;version=snapshot,\
- org.gecko.emf.osgi.api;version='[6.0.0,6.0.1)',\
org.gecko.mongo.osgi.component;version=snapshot,\
org.mongodb.mongo-java-driver;version='[3.12.14,3.12.15)',\
org.osgi.service.component;version='[1.5.1,1.5.2)',\
org.osgi.service.log;version='[1.5.0,1.5.1)',\
org.osgi.service.metatype;version='[1.4.1,1.4.2)',\
org.osgi.util.function;version='[1.2.0,1.2.1)',\
- org.osgi.util.promise;version='[1.3.0,1.3.1)'
+ org.osgi.util.promise;version='[1.3.0,1.3.1)',\
+ org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\
+ org.eclipse.emf.common;version='[2.29.0,2.29.1)',\
+ org.eclipse.emf.ecore;version='[2.35.0,2.35.1)',\
+ org.eclipse.emf.ecore.xmi;version='[2.36.0,2.36.1)',\
+ org.gecko.emf.collections;version='[2.2.2,2.2.3)',\
+ org.gecko.emf.osgi.component.minimal;version='[6.2.0,6.2.1)',\
+ org.osgi.service.cm;version='[1.6.1,1.6.2)',\
+ org.osgi.util.converter;version='[1.0.9,1.0.10)'
-runrequires: \
osgi.identity;filter:='(osgi.identity=org.apache.felix.gogo.shell)',\
diff --git a/org.gecko.emf.mongo/src/org/gecko/emf/mongo/MongoUtils.java b/org.gecko.emf.mongo/src/org/gecko/emf/mongo/MongoUtils.java
index 6dda3b6..632e2e0 100644
--- a/org.gecko.emf.mongo/src/org/gecko/emf/mongo/MongoUtils.java
+++ b/org.gecko.emf.mongo/src/org/gecko/emf/mongo/MongoUtils.java
@@ -42,7 +42,7 @@ public static Object getID(URI uri) throws IOException {
if (uri.segmentCount() != 3) {
throw new IOException("The URI is not of the form 'mongo:/database/collection/{id}");
}
- String id = uri.segment(2);
+ String id = URI.decode(uri.segment(2));
// If the ID was specified in the URI, we first attempt to create a MongoDB ObjectId. If
// that fails, we assume that the client has specified a non ObjectId and return the raw data.
@@ -68,7 +68,7 @@ public static String getIDAsString(URI uri) throws IOException {
if (uri.segmentCount() != 3) {
throw new IOException("The URI is not of the form 'mongo:/database/collection/{id}");
}
- String id = uri.segment(2);
+ String id = URI.decode(uri.segment(2));
return id;
}
@@ -82,7 +82,7 @@ public static String getIDAsString(URI uri) throws IOException {
*/
public static Object getIDWithValidURI(URI uri) {
- String id = uri.segment(2);
+ String id = URI.decode(uri.segment(2));
// If the ID was specified in the URI, we first attempt to create a MongoDB ObjectId. If
// that fails, we assume that the client has specified a non ObjectId and return the raw data.
diff --git a/org.gecko.emf.mongo/src/org/gecko/emf/mongo/Options.java b/org.gecko.emf.mongo/src/org/gecko/emf/mongo/Options.java
index cfc6a1e..cc2d892 100644
--- a/org.gecko.emf.mongo/src/org/gecko/emf/mongo/Options.java
+++ b/org.gecko.emf.mongo/src/org/gecko/emf/mongo/Options.java
@@ -11,10 +11,12 @@
*******************************************************************************/
package org.gecko.emf.mongo;
+import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.Enumerator;
+import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
@@ -310,6 +312,23 @@ public interface Options {
*
*/
String OPTION_COLLECTION_NAME = "COLLECTION_NAME";
+
+ /**
+ * An {@link EAttribute} to use as primary key instead of the ID Attribute
+ *
+ * Value type: {@link EAttribute}
+ */
+ String OVERWRITE_PRIMARY_KEY_EATTRIBUTE = "OVERWRITE_PRIMARY_KEY_EATTRIBUTE";
+
+ /**
+ * A List of potential {@link EAttribute}s to use as primary key instead of the ID Attribute.
+ * The first {@link EAttribute} that fits the {@link EClass} to store will be used.
+ *
+ * If OVERWRITE_PRIMARY_KEY_EATTRIBUTE is set at the same time, it will be evaluated first.
+ *
+ * Value type: {@link List} of {@link EAttribute}
+ */
+ String OVERWRITE_PRIMARY_KEY_EATTRIBUTES = "OVERWRITE_PRIMARY_KEY_EATTRIBUTES";
/**
* Returns true
, if the {@link Options#OPTION_USE_EXTENDED_METADATA}
@@ -433,4 +452,46 @@ public static String getCollectionName(Map, ?> options) {
return alias == null ? null : alias.toString();
}
+ public static EAttribute getIDAttribute(EClass eClass, Map, ?> options) {
+ if(options == null) {
+ return eClass.getEIDAttribute();
+ }
+
+ EAttribute idAttribute = (EAttribute) options.getOrDefault(OVERWRITE_PRIMARY_KEY_EATTRIBUTE, null);
+ if(idAttribute != null && idAttribute.getEContainingClass().isSuperTypeOf(eClass)) {
+ return idAttribute;
+ }
+
+ Object attributesObject = options.getOrDefault(OVERWRITE_PRIMARY_KEY_EATTRIBUTES, null);
+ if(attributesObject != null) {
+ @SuppressWarnings("unchecked")
+ List attributes = (List) attributesObject;
+ int firstHit = -1;
+ for (int i = 0; i < attributes.size(); i++) {
+ EAttribute eAttribute = attributes.get(i);
+ EClass containingEClass = eAttribute.getEContainingClass();
+ if(containingEClass == eClass) {
+ return eAttribute;
+ }
+ if(firstHit != -1 && eAttribute.getEContainingClass().isSuperTypeOf(eClass)) {
+ firstHit = i;
+ }
+ }
+ if(firstHit != -1) {
+ return attributes.get(firstHit);
+ }
+ }
+
+ return eClass.getEIDAttribute();
+ }
+
+ public static boolean useIdAttributeAsPrimaryKey(Map, ?> options) {
+ Object value = options.getOrDefault(OPTION_USE_ID_ATTRIBUTE_AS_PRIMARY_KEY, null);
+ if(value == null) {
+ return false;
+ } else if(value instanceof String) {
+ return Boolean.parseBoolean((String) value);
+ }
+ return (boolean) value;
+ }
}
diff --git a/org.gecko.emf.mongo/src/org/gecko/emf/mongo/codecs/builder/DBObjectBuilderImpl.java b/org.gecko.emf.mongo/src/org/gecko/emf/mongo/codecs/builder/DBObjectBuilderImpl.java
index f04cbda..7f82001 100644
--- a/org.gecko.emf.mongo/src/org/gecko/emf/mongo/codecs/builder/DBObjectBuilderImpl.java
+++ b/org.gecko.emf.mongo/src/org/gecko/emf/mongo/codecs/builder/DBObjectBuilderImpl.java
@@ -226,7 +226,7 @@ private void writeMongoIdAttribute(BsonWriter writer, EObject eObject){
Boolean useIdAttributeAsPrimaryKey = (Boolean) options.get(Options.OPTION_USE_ID_ATTRIBUTE_AS_PRIMARY_KEY);
Object id = null;
if (useIdAttributeAsPrimaryKey == null || useIdAttributeAsPrimaryKey) {
- EAttribute idAttribute = eObject.eClass().getEIDAttribute();
+ EAttribute idAttribute = Options.getIDAttribute(eObject.eClass(), options);
if (idAttribute != null) {
id = eObject.eGet(idAttribute);
}
diff --git a/org.gecko.emf.mongo/src/org/gecko/emf/mongo/codecs/builder/EObjectBuilderImpl.java b/org.gecko.emf.mongo/src/org/gecko/emf/mongo/codecs/builder/EObjectBuilderImpl.java
index 5698502..ce78fd1 100644
--- a/org.gecko.emf.mongo/src/org/gecko/emf/mongo/codecs/builder/EObjectBuilderImpl.java
+++ b/org.gecko.emf.mongo/src/org/gecko/emf/mongo/codecs/builder/EObjectBuilderImpl.java
@@ -272,7 +272,7 @@ public EObject decodeObject(BsonReader reader, DecoderContext context, Resource
}
oid = oidValue.toString();
reader.readBsonType(); //set the reader to the state requried by the next step.
- URI uri = baseUri.trimSegments(1).appendSegment(oid).trimQuery();
+ URI uri = baseUri.trimSegments(1).appendSegment(URI.encodeSegment(oid, true)).trimQuery();
if(!resource.getURI().equals(uri)){
loadResource = factory.createResource(uri);
if(resourceCache != null){
diff --git a/org.gecko.emf.mongo/src/org/gecko/emf/mongo/package-info.java b/org.gecko.emf.mongo/src/org/gecko/emf/mongo/package-info.java
index 3853005..86c313a 100644
--- a/org.gecko.emf.mongo/src/org/gecko/emf/mongo/package-info.java
+++ b/org.gecko.emf.mongo/src/org/gecko/emf/mongo/package-info.java
@@ -1,3 +1,3 @@
-@org.osgi.annotation.versioning.Version("5.0.0")
+@org.osgi.annotation.versioning.Version("5.1.0")
@org.gecko.emf.mongo.annotations.RequireMongoEMF
package org.gecko.emf.mongo;
diff --git a/org.gecko.emf.mongo/src/org/gecko/emf/mongo/streams/MongoOutputStream.java b/org.gecko.emf.mongo/src/org/gecko/emf/mongo/streams/MongoOutputStream.java
index 7231998..3d121ac 100644
--- a/org.gecko.emf.mongo/src/org/gecko/emf/mongo/streams/MongoOutputStream.java
+++ b/org.gecko.emf.mongo/src/org/gecko/emf/mongo/streams/MongoOutputStream.java
@@ -84,8 +84,7 @@ public MongoOutputStream(ConverterService converterService, MongoCollection collection) throws IOE
List> bulk = new ArrayList<>(contents.size());
for (EObject eObject : contents) {
- EAttribute idAttribute = eObject.eClass().getEIDAttribute();
+ EAttribute idAttribute = Options.getIDAttribute(eObject.eClass(), mergedOptions);
if(idAttribute == null && useIdAttributeAsPrimaryKey){
throw new IllegalStateException("EObjects have no ID Attribute to be used together with option " + Options.OPTION_USE_ID_ATTRIBUTE_AS_PRIMARY_KEY);
@@ -186,7 +185,7 @@ private void saveMultipleObjects(MongoCollection collection) throws IOE
if(forceInsert){
bulk.add(new InsertOneModel(eObject));
} else {
- Bson updateFilter = createUpdateFilter(eObject);
+ Bson updateFilter = createUpdateFilter(eObject, idAttribute);
bulk.add(new ReplaceOneModel(updateFilter, eObject, ReplaceOptions.createReplaceOptions(UPDATE_OPTIONS)));
}
}
@@ -216,14 +215,13 @@ private void saveMultipleObjects(MongoCollection collection) throws IOE
* @param collection the collection to save the object for
* @throws IOException thrown on errors during saving
*/
- private void saveSingleObject(MongoCollection collection) throws IOException {
+ private void saveSingleObject(MongoCollection collection, EAttribute idAttribute) throws IOException {
EObject eObject = resource.getContents().get(0);
if(forceInsert){
collection.insertOne(eObject);
} else {
- Bson updateFilter = createUpdateFilter(eObject);
+ Bson updateFilter = createUpdateFilter(eObject, idAttribute);
FindOneAndReplaceOptions farOptions = new FindOneAndReplaceOptions().upsert(true).returnDocument(ReturnDocument.AFTER);
- EAttribute idAttribute = eObject.eClass().getEIDAttribute();
// Minimize the load by just adding projection for minimum set of attributes
if (idAttribute != null) {
String eClassKey = Options.getEClassKey((Map, ?>) mergedOptions);
@@ -244,7 +242,7 @@ private void saveSingleObject(MongoCollection collection) throws IOExce
}
}
- private Bson createUpdateFilter(EObject eObject) throws IOException {
+ private Bson createUpdateFilter(EObject eObject, EAttribute idAttribute) throws IOException {
String idKey = "_id";
Object id = null;
if (!useIdAttributeAsPrimaryKey) {
@@ -252,7 +250,6 @@ private Bson createUpdateFilter(EObject eObject) throws IOException {
if (pkId != null && !pkId.isEmpty()) {
id = normalizeMongoId(pkId);
} else {
- EAttribute idAttribute = eObject.eClass().getEIDAttribute();
idKey = idAttribute == null ? "_id" : idAttribute.getName();
id = EcoreUtil.getID(eObject);
}
diff --git a/org.gecko.emf.repository.mongo.tests/src/org/gecko/emf/repository/mongo/tests/MongoConfiguratorIntegrationTest.java b/org.gecko.emf.repository.mongo.tests/src/org/gecko/emf/repository/mongo/tests/MongoConfiguratorIntegrationTest.java
index 021c1dd..1ecece4 100644
--- a/org.gecko.emf.repository.mongo.tests/src/org/gecko/emf/repository/mongo/tests/MongoConfiguratorIntegrationTest.java
+++ b/org.gecko.emf.repository.mongo.tests/src/org/gecko/emf/repository/mongo/tests/MongoConfiguratorIntegrationTest.java
@@ -19,15 +19,20 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
+import java.util.Collections;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.impl.EPackageImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.gecko.emf.mongo.Options;
import org.gecko.emf.osgi.ResourceSetFactory;
import org.gecko.emf.osgi.constants.EMFNamespaces;
import org.gecko.emf.osgi.example.model.basic.BasicFactory;
@@ -159,6 +164,66 @@ public void testEMFMongoRepository(@InjectService(cardinality = 0) ServiceAware<
assertTrue(mdpAware.isEmpty());
assertTrue(rsfAware.isEmpty());
}
+
+ @Test
+ public void testEMFMongoRepositoryOptionOverwritePrimaryKey(@InjectService(cardinality = 0) ServiceAware mcpAware,
+ @InjectService(cardinality = 0) ServiceAware mdpAware,
+ @InjectService(cardinality = 0, filter = "(" + EMFRepository.PROP_ID + "=test1.test)") ServiceAware repoAware,
+ @InjectService(cardinality = 0, filter = "(&(" + EMFNamespaces.EMF_CONFIGURATOR_NAME + "=mongo)(" + EMFNamespaces.EMF_CONFIGURATOR_NAME + "=test1.test))") ServiceAware rsfAware) throws BundleException, InvalidSyntaxException, IOException, InterruptedException {
+ /**
+ * mongo.instances=test1
+ * test1.baseUris=mongodb://localhost
+ * test1.databases=test
+ */
+
+ Dictionary configProperties = new Hashtable<>();
+ configProperties.put("mongo.instances", "test1");
+ configProperties.put("test1.baseUris", "mongodb://" + mongoHost);
+ configProperties.put("test1.databases", "test");
+
+// String clientId = "test1.test";
+
+// defaultCheck();
+
+ assertTrue(repoAware.isEmpty());
+ assertTrue(mcpAware.isEmpty());
+ assertTrue(mdpAware.isEmpty());
+ assertTrue(rsfAware.isEmpty());
+
+ Configuration repositoryConfig = configAdmin.createFactoryConfiguration(EMFMongoConfiguratorConstants.EMF_MONGO_REPOSITORY_CONFIGURATOR_CONFIGURATION_NAME, "?");
+ repositoryConfig.update(configProperties);
+
+ rsfAware.waitForService(2000l);
+ mcpAware.waitForService(2000l);
+ mdpAware.waitForService(2000l);
+
+ EMFRepository repository = repoAware.waitForService(2000l);
+ URI expected = URI.createURI("mongodb://test1/test/EPackage").appendSegment(URI.encodeSegment(BasicPackage.eINSTANCE.getNsURI(), true)).appendFragment(URI.encodeFragment(BasicPackage.eINSTANCE.getNsURI(), true));
+
+ URI uri = repository.createUri(BasicPackage.eINSTANCE, Collections.singletonMap(Options.OVERWRITE_PRIMARY_KEY_EATTRIBUTE, EcorePackage.Literals.EPACKAGE__NS_URI));
+ System.out.println("EAttribute URI");
+ System.out.println("=========================================================");
+ System.out.println(uri);
+ assertEquals(expected, uri);
+
+ uri = repository.createUri(BasicPackage.eINSTANCE, Collections.singletonMap(Options.OVERWRITE_PRIMARY_KEY_EATTRIBUTES, Collections.singletonList(EcorePackage.Literals.EPACKAGE__NS_URI)));
+ System.out.println("EAttribute URI2");
+ System.out.println("=========================================================");
+ System.out.println(uri);
+ assertEquals(expected, uri);
+
+ EObject basicPackage = EcoreUtil.copy(BasicPackage.eINSTANCE);
+ repository.save(basicPackage, Collections.singletonMap(Options.OVERWRITE_PRIMARY_KEY_EATTRIBUTE, EcorePackage.Literals.EPACKAGE__NS_URI));
+ repository.detach(basicPackage);
+
+ EObject eObject = repository.getEObject(EcorePackage.Literals.EPACKAGE, BasicPackage.eINSTANCE.getNsURI(), Collections.singletonMap(Options.OVERWRITE_PRIMARY_KEY_EATTRIBUTE, EcorePackage.Literals.EPACKAGE__NS_URI));
+
+ assertNotNull(eObject);
+ assertEquals(EcorePackage.Literals.EPACKAGE, eObject.eClass());
+ assertEquals(BasicPackage.eINSTANCE.getNsURI(), ((EPackageImpl) eObject).getNsURI());
+ assertNotEquals(basicPackage, eObject);
+ assertNotEquals(BasicPackage.eINSTANCE, eObject);
+ }
// @Test
// public void testEMFMongoRepositoryPrototypeInstance() throws BundleException, InvalidSyntaxException, IOException, InterruptedException {
diff --git a/org.gecko.emf.repository.mongo.tests/test.bndrun b/org.gecko.emf.repository.mongo.tests/test.bndrun
index fc44f3d..b764fba 100644
--- a/org.gecko.emf.repository.mongo.tests/test.bndrun
+++ b/org.gecko.emf.repository.mongo.tests/test.bndrun
@@ -21,10 +21,6 @@
org.osgi.util.function;version='[1.2.0,1.2.1)',\
org.osgi.util.promise;version='[1.3.0,1.3.1)',\
org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\
- org.apache.felix.metatype;version='[1.2.4,1.2.5)',\
- org.eclipse.emf.common;version='[2.28.0,2.28.1)',\
- org.eclipse.emf.ecore;version='[2.33.0,2.33.1)',\
- org.eclipse.emf.ecore.xmi;version='[2.18.0,2.18.1)',\
org.gecko.emf.collections;version='[2.2.2,2.2.3)',\
org.gecko.emf.mongo.component;version=snapshot,\
org.gecko.emf.repository.api;version=snapshot,\
@@ -36,13 +32,15 @@
net.bytebuddy.byte-buddy;version='[1.14.9,1.14.10)',\
net.bytebuddy.byte-buddy-agent;version='[1.14.9,1.14.10)',\
org.gecko.emf.repository.mongo.tests;version=snapshot,\
- org.gecko.mongo.osgi.api;version=snapshot,\
org.mockito.junit-jupiter;version='[4.11.0,4.11.1)',\
org.mockito.mockito-core;version='[4.11.0,4.11.1)',\
org.objenesis;version='[3.3.0,3.3.1)',\
org.opentest4j;version='[1.3.0,1.3.1)',\
org.osgi.test.common;version='[1.2.1,1.2.2)',\
org.osgi.test.junit5;version='[1.2.1,1.2.2)',\
- org.gecko.emf.osgi.api;version='[6.0.2,6.0.3)',\
- org.gecko.emf.osgi.component;version='[6.0.2,6.0.3)',\
- org.gecko.emf.osgi.example.model.basic;version='[6.0.2,6.0.3)'
\ No newline at end of file
+ org.eclipse.emf.common;version='[2.29.0,2.29.1)',\
+ org.eclipse.emf.ecore;version='[2.35.0,2.35.1)',\
+ org.eclipse.emf.ecore.xmi;version='[2.36.0,2.36.1)',\
+ org.gecko.emf.osgi.component.minimal;version='[6.2.0,6.2.1)',\
+ org.gecko.emf.osgi.example.model.basic;version='[6.2.0,6.2.1)',\
+ org.osgi.service.metatype;version='[1.4.1,1.4.2)'
\ No newline at end of file
diff --git a/org.gecko.emf.repository.mongo/bnd.bnd b/org.gecko.emf.repository.mongo/bnd.bnd
index 52cba32..ae224c5 100644
--- a/org.gecko.emf.repository.mongo/bnd.bnd
+++ b/org.gecko.emf.repository.mongo/bnd.bnd
@@ -18,7 +18,7 @@
Bundle-Name: EMF Repository Mongo
Bundle-Description: EMF Mongo Repository Implementation
-Bundle-Version: 3.2.0.${tstamp}-SNAPSHOT
+Bundle-Version: 3.3.0.${tstamp}-SNAPSHOT
Provide-Capability: emf.repository;emf.repository=mongo
Require-Capability: org.gecko.osgi.emf.persistence;filter:='(org.gecko.osgi.emf.persistence=mongo)'
Private-Package: \
diff --git a/org.gecko.emf.repository.mongo/src/org/gecko/emf/repository/mongo/impl/AbstractEMFMongoRepository.java b/org.gecko.emf.repository.mongo/src/org/gecko/emf/repository/mongo/impl/AbstractEMFMongoRepository.java
index 0f6186d..ed4da50 100644
--- a/org.gecko.emf.repository.mongo/src/org/gecko/emf/repository/mongo/impl/AbstractEMFMongoRepository.java
+++ b/org.gecko.emf.repository.mongo/src/org/gecko/emf/repository/mongo/impl/AbstractEMFMongoRepository.java
@@ -19,15 +19,16 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bson.types.ObjectId;
import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.util.EcoreUtil;
import org.gecko.collection.EReferenceCollection;
import org.gecko.emf.mongo.Options;
import org.gecko.emf.osgi.ResourceSetFactory;
@@ -127,7 +128,12 @@ public T getEObject(EClass eClass, Object id, Map, ?> opti
return null;
}
String eclassAlias = getCollectionName(eClass, options);
- return getEObject(eclassAlias, id, options);
+ URI uri = createEClassUri(eclassAlias, options).appendSegment(URI.encodeSegment(id.toString(), true));
+ EAttribute idAttribute = Options.getIDAttribute(eClass, options);
+ if(idAttribute.isID()) {
+ uri = uri.appendFragment(URI.encodeFragment(id.toString(), true));
+ }
+ return getEObject(uri, options);
}
/*
@@ -159,7 +165,10 @@ public URI createUri(EObject object, Map, ?> options) {
if (object == null) {
return null;
}
- String id = EcoreUtil.getID(object);
+
+ EAttribute idAttribute = Options.getIDAttribute(object.eClass(), options);
+
+ String id = idAttribute != null ? Objects.toString(object.eGet(idAttribute)) : null;
URI uri = createMongoURI(object.eClass(), options);
Object useId = options.get(Options.OPTION_USE_ID_ATTRIBUTE_AS_PRIMARY_KEY);
@@ -173,12 +182,12 @@ public URI createUri(EObject object, Map, ?> options) {
* the _id will be generated from the MongoDB
*/
if (useId == null || Boolean.TRUE.equals(useId)) {
- uri = uri.appendSegment(id);
+ uri = uri.appendSegment(URI.encodeSegment(id, true));
} else {
uri = uri.appendSegment("");
}
if (id != null) {
- uri = uri.appendFragment(id);
+ uri = uri.appendFragment(URI.encodeFragment(id, true));
}
return uri;
}
diff --git a/org.gecko.emf.repository.tests/test.bndrun b/org.gecko.emf.repository.tests/test.bndrun
index d46cb18..d8a9265 100644
--- a/org.gecko.emf.repository.tests/test.bndrun
+++ b/org.gecko.emf.repository.tests/test.bndrun
@@ -17,15 +17,12 @@
org.osgi.util.function;version='[1.2.0,1.2.1)',\
org.osgi.util.promise;version='[1.3.0,1.3.1)',\
org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\
- org.eclipse.emf.common;version='[2.28.0,2.28.1)',\
- org.eclipse.emf.ecore;version='[2.33.0,2.33.1)',\
org.gecko.emf.repository.api;version=snapshot,\
junit-jupiter-api;version='[5.10.1,5.10.2)',\
junit-jupiter-params;version='[5.10.1,5.10.2)',\
junit-platform-commons;version='[1.10.1,1.10.2)',\
net.bytebuddy.byte-buddy;version='[1.14.9,1.14.10)',\
net.bytebuddy.byte-buddy-agent;version='[1.14.9,1.14.10)',\
- org.eclipse.emf.ecore.xmi;version='[2.18.0,2.18.1)',\
org.gecko.emf.repository.tests;version=snapshot,\
org.mockito.junit-jupiter;version='[4.11.0,4.11.1)',\
org.mockito.mockito-core;version='[4.11.0,4.11.1)',\
@@ -33,10 +30,10 @@
org.opentest4j;version='[1.3.0,1.3.1)',\
org.osgi.test.common;version='[1.2.1,1.2.2)',\
org.osgi.test.junit5;version='[1.2.1,1.2.2)',\
- org.apache.felix.metatype;version='[1.2.4,1.2.5)',\
- org.osgi.service.log;version='[1.5.0,1.5.1)',\
org.osgi.util.converter;version='[1.0.9,1.0.10)',\
org.gecko.emf.repository.file;version=snapshot,\
- org.gecko.emf.osgi.api;version='[6.0.2,6.0.3)',\
- org.gecko.emf.osgi.component;version='[6.0.2,6.0.3)',\
- org.gecko.emf.osgi.example.model.basic;version='[6.0.2,6.0.3)'
\ No newline at end of file
+ org.eclipse.emf.common;version='[2.29.0,2.29.1)',\
+ org.eclipse.emf.ecore;version='[2.35.0,2.35.1)',\
+ org.eclipse.emf.ecore.xmi;version='[2.36.0,2.36.1)',\
+ org.gecko.emf.osgi.component.minimal;version='[6.2.0,6.2.1)',\
+ org.gecko.emf.osgi.example.model.basic;version='[6.2.0,6.2.1)'
\ No newline at end of file
diff --git a/org.gecko.emf.repository/src/org/gecko/emf/repository/DefaultEMFRepository.java b/org.gecko.emf.repository/src/org/gecko/emf/repository/DefaultEMFRepository.java
index e157b58..c13bb2c 100644
--- a/org.gecko.emf.repository/src/org/gecko/emf/repository/DefaultEMFRepository.java
+++ b/org.gecko.emf.repository/src/org/gecko/emf/repository/DefaultEMFRepository.java
@@ -677,7 +677,7 @@ public T getEObject(String eClassName, Object id, Map, ?>
logger.log(Level.SEVERE, "Error getting EObject without class name or id parameters");
return null;
}
- URI uri = createEClassUri(eClassName, options).appendSegment(id.toString()).appendFragment(id.toString());
+ URI uri = createEClassUri(eClassName, options).appendSegment(URI.encodeSegment(id.toString(), true)).appendFragment(URI.encodeFragment(id.toString(), true));
return getEObject(uri, options);
}
diff --git a/org.gecko.emf.repository/src/org/gecko/emf/repository/helper/RepositoryHelper.java b/org.gecko.emf.repository/src/org/gecko/emf/repository/helper/RepositoryHelper.java
index 8061898..191834f 100644
--- a/org.gecko.emf.repository/src/org/gecko/emf/repository/helper/RepositoryHelper.java
+++ b/org.gecko.emf.repository/src/org/gecko/emf/repository/helper/RepositoryHelper.java
@@ -22,6 +22,7 @@
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.ecore.util.InternalEList;
import org.gecko.emf.repository.exception.ConstraintValidationException;
/**
@@ -75,7 +76,7 @@ private static Diagnostic checkForAttachedNonContainmentRefs(EObject eObject) {
private static Diagnostic checkForAttachedNonContainmentRefs(EObject eObject, EReference reference) {
if(reference != null && !reference.isContainment()) {
- if(eObject.eIsProxy() || (eObject.eResource() != null && eObject.eResource().getResourceSet() != null)){
+ if(eObject.eIsProxy() || (eObject.eResource() != null && eObject.eResource().getResourceSet() != null )){
return OK_INSTANCE;
} else {
return new BasicDiagnostic(Diagnostic.ERROR, eObject.toString() + " for reference " + reference.getName(), 42, "The Object is no Proxy and is not attached to any Resource/ResourceSet", null);
@@ -96,11 +97,20 @@ private static Diagnostic checkForAttachedNonContainmentRefs(EObject eObject, ER
if(r.isContainment()) {
eos.stream().map(eo -> checkForAttachedNonContainmentRefs(eo, r)).map(eo->(Diagnostic) eo).forEach(chain::add);
} else {
- BasicEList list = (BasicEList) eos;
- for(int i = 0 ; i < list.size(); i++) {
- EObject eo = list.basicGet(i);
- chain.add(checkForAttachedNonContainmentRefs(eo, r));
+ if(eos instanceof BasicEList) {
+ BasicEList list = (BasicEList) eos;
+ for(int i = 0 ; i < list.size(); i++) {
+ EObject eo = list.basicGet(i);
+ chain.add(checkForAttachedNonContainmentRefs(eo, r));
+ }
+ } else if(eos instanceof InternalEList) {
+ InternalEList list = (InternalEList) eos;
+ for(int i = 0 ; i < list.size(); i++) {
+ EObject eo = list.basicGet(i);
+ chain.add(checkForAttachedNonContainmentRefs(eo, r));
+ }
}
+
}
return chain;
} else {