diff --git a/cnf/central.mvn b/cnf/central.mvn index aea14f72..8bc55e4c 100644 --- a/cnf/central.mvn +++ b/cnf/central.mvn @@ -144,7 +144,7 @@ org.geckoprojects.bnd:org.gecko.bnd.osgitest.library:1.5.0 org.geckoprojects.bnd:org.gecko.bnd.jacoco.library:1.5.0 org.geckoprojects.utils:org.gecko.util.bnd.library.workspace:1.0.0 -org.geckoprojects.emf:org.gecko.emf.osgi.bnd.library.workspace:6.1.1 +org.geckoprojects.emf:org.gecko.emf.osgi.bnd.library.workspace:6.2.0 com.fasterxml.jackson.core:jackson-core:2.14.1 com.fasterxml.jackson.core:jackson-databind:2.14.1 diff --git a/cnf/local/index.xml b/cnf/local/index.xml index bf313e36..13c6ef26 100644 --- a/cnf/local/index.xml +++ b/cnf/local/index.xml @@ -1,5 +1,5 @@ - + diff --git a/org.gecko.emf.bson.tests/test.bndrun b/org.gecko.emf.bson.tests/test.bndrun index 6dcb3b1a..3fddfe1a 100644 --- a/org.gecko.emf.bson.tests/test.bndrun +++ b/org.gecko.emf.bson.tests/test.bndrun @@ -49,14 +49,12 @@ org.yaml.snakeyaml;version='[1.33.0,1.33.1)',\ org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ org.osgi.service.component;version='[1.5.1,1.5.2)',\ - org.osgi.util.converter;version='[1.0.9,1.0.10)',\ org.osgi.util.function;version='[1.2.0,1.2.1)',\ org.osgi.util.promise;version='[1.3.0,1.3.1)',\ 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.api;version='[6.1.1,6.1.2)',\ - org.gecko.emf.osgi.component.config;version='[6.1.1,6.1.2)',\ org.gecko.emf.osgi.component.minimal;version='[6.1.1,6.1.2)',\ org.gecko.emf.osgi.example.model.basic;version='[6.1.0,6.1.1)',\ - org.osgi.service.cm;version='[1.6.1,1.6.2)' \ No newline at end of file + org.osgi.service.cm;version='[1.6.1,1.6.2)',\ + org.osgi.util.converter;version='[1.0.9,1.0.10)' \ No newline at end of file diff --git a/org.gecko.emf.converter.model/.classpath b/org.gecko.emf.converter.model/.classpath new file mode 100644 index 00000000..66e477cd --- /dev/null +++ b/org.gecko.emf.converter.model/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/org.gecko.emf.converter.model/.gitignore b/org.gecko.emf.converter.model/.gitignore new file mode 100644 index 00000000..568876fd --- /dev/null +++ b/org.gecko.emf.converter.model/.gitignore @@ -0,0 +1,4 @@ +/bin/ +/bin_test/ +/generated/ +/src/ diff --git a/org.gecko.emf.converter.model/.project b/org.gecko.emf.converter.model/.project new file mode 100644 index 00000000..268c8730 --- /dev/null +++ b/org.gecko.emf.converter.model/.project @@ -0,0 +1,23 @@ + + + org.gecko.emf.converter.model + + + + + + org.eclipse.jdt.core.javabuilder + + + + + bndtools.core.bndbuilder + + + + + + org.eclipse.jdt.core.javanature + bndtools.core.bndnature + + diff --git a/org.gecko.emf.converter.model/.settings/org.eclipse.core.resources.prefs b/org.gecko.emf.converter.model/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000..8b0a4028 --- /dev/null +++ b/org.gecko.emf.converter.model/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,8 @@ +eclipse.preferences.version=1 +encoding//.settings/org.eclipse.core.resources.prefs=UTF-8 +encoding//.settings/org.eclipse.jdt.core.prefs=UTF-8 +encoding//.settings/org.eclipse.jdt.ui.prefs=UTF-8 +encoding//model/converter.ecore=UTF-8 +encoding//model/converter.genmodel=UTF-8 +encoding/=UTF-8 +encoding/bnd.bnd=UTF-8 diff --git a/org.gecko.emf.converter.model/.settings/org.eclipse.jdt.core.prefs b/org.gecko.emf.converter.model/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..cd8d089a --- /dev/null +++ b/org.gecko.emf.converter.model/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,15 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/org.gecko.emf.converter.model/.settings/org.eclipse.jdt.ui.prefs b/org.gecko.emf.converter.model/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 00000000..05331f3e --- /dev/null +++ b/org.gecko.emf.converter.model/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,8 @@ +content_assist_proposals_background=255,255,255 +content_assist_proposals_foreground=0,0,0 +eclipse.preferences.version=1 +org.eclipse.jdt.ui.formatterprofiles.version=13 +org.eclipse.jdt.ui.javadoc=true +spelling_locale_initialized=true +useAnnotationsPrefPage=true +useQuickDiffPrefPage=true diff --git a/org.gecko.emf.converter.model/bnd.bnd b/org.gecko.emf.converter.model/bnd.bnd new file mode 100644 index 00000000..b664f845 --- /dev/null +++ b/org.gecko.emf.converter.model/bnd.bnd @@ -0,0 +1,19 @@ +# sets the usually required buildpath using the bnd library, you can extend it with the normal -buildpath to your liking +-library: enable-emf + +# The code generation takes a bit of time and makes the build a bit slower. +# It might be a good idea to put comments around it, when you don't need it + +-generate:\ + model/converter.genmodel;\ + generate=geckoEMF;\ + genmodel=model/converter.genmodel;\ + output=src;\ + logfile=converter-genmodel.log;\ + +# If this is not done with a instruction namespace, bnd would think you like +# to take full control over whats exported and imported and will ignore @Export +# Bundle Annotations +-includeresource.model: model=model + +Bundle-Version: 1.0.0.SNAPSHOT diff --git a/org.gecko.emf.converter.model/model/converter.ecore b/org.gecko.emf.converter.model/model/converter.ecore new file mode 100644 index 00000000..9dc97c9d --- /dev/null +++ b/org.gecko.emf.converter.model/model/converter.ecore @@ -0,0 +1,24 @@ + + + +
+ + + + + + + + + + + + + + + + + + + diff --git a/org.gecko.emf.converter.model/model/converter.genmodel b/org.gecko.emf.converter.model/model/converter.genmodel new file mode 100644 index 00000000..b27c365b --- /dev/null +++ b/org.gecko.emf.converter.model/model/converter.genmodel @@ -0,0 +1,28 @@ + + + converter.ecore + + + + + + + + + + + + + + + + + + + + diff --git a/org.gecko.emf.converter.tests/.classpath b/org.gecko.emf.converter.tests/.classpath new file mode 100644 index 00000000..66e477cd --- /dev/null +++ b/org.gecko.emf.converter.tests/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/org.gecko.emf.converter.tests/.gitignore b/org.gecko.emf.converter.tests/.gitignore new file mode 100644 index 00000000..7fdbdef7 --- /dev/null +++ b/org.gecko.emf.converter.tests/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/bin_test/ diff --git a/org.gecko.emf.converter.tests/.project b/org.gecko.emf.converter.tests/.project new file mode 100644 index 00000000..2f06f8c3 --- /dev/null +++ b/org.gecko.emf.converter.tests/.project @@ -0,0 +1,23 @@ + + + org.gecko.emf.csv.tests + + + + + + org.eclipse.jdt.core.javabuilder + + + + + bndtools.core.bndbuilder + + + + + + org.eclipse.jdt.core.javanature + bndtools.core.bndnature + + diff --git a/org.gecko.emf.converter.tests/.settings/org.eclipse.core.resources.prefs b/org.gecko.emf.converter.tests/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000..5b8f3173 --- /dev/null +++ b/org.gecko.emf.converter.tests/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 +encoding/bnd.bnd=UTF-8 +encoding/test.bndrun=UTF-8 diff --git a/org.gecko.emf.converter.tests/.settings/org.eclipse.jdt.core.prefs b/org.gecko.emf.converter.tests/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..f2525a8b --- /dev/null +++ b/org.gecko.emf.converter.tests/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,14 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/org.gecko.emf.converter.tests/bnd.bnd b/org.gecko.emf.converter.tests/bnd.bnd new file mode 100644 index 00000000..a96aaa2f --- /dev/null +++ b/org.gecko.emf.converter.tests/bnd.bnd @@ -0,0 +1,15 @@ +-library: enable-emf,\ + enableOSGi-Test + +javac.source: 11 +javac.target: 11 + +Bundle-Version: 1.0.0.SNAPSHOT + +-buildpath: \ + org.gecko.emf.converter;version=snapshot,\ + org.osgi.dto,\ + org.osgi.util.converter;version=latest,\ + org.osgi.util.function;version=latest + +-dependson: org.gecko.emf.converter diff --git a/org.gecko.emf.converter.tests/src/org/gecko/emf/converter/tests/DTOToEObjectConverterTest.java b/org.gecko.emf.converter.tests/src/org/gecko/emf/converter/tests/DTOToEObjectConverterTest.java new file mode 100644 index 00000000..296ec5a8 --- /dev/null +++ b/org.gecko.emf.converter.tests/src/org/gecko/emf/converter/tests/DTOToEObjectConverterTest.java @@ -0,0 +1,136 @@ +/** + * Copyright (c) 2012 - 2022 Data In Motion and others. + * All rights reserved. + * + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Data In Motion - initial API and implementation + */ +package org.gecko.emf.converter.tests; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.gecko.emf.converter.DTOToEObjectConverters; +import org.gecko.emf.converter.DTOToEPackageConverter; +import org.gecko.emf.converter.tests.helper.DTOToEMFConverterTestHelper.ConverterTestBasicDTO; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.platform.commons.annotation.Testable; +import org.osgi.test.junit5.context.BundleContextExtension; +import org.osgi.test.junit5.service.ServiceExtension; +import org.osgi.util.converter.Converter; +import org.osgi.util.converter.ConverterBuilder; +import org.osgi.util.function.Function; + +/** + * Integration test for {@link org.gecko.emf.converter.DTOToEObjectConverters} + * + * @author Michal H. Siemaszko + */ +@Testable +@ExtendWith(BundleContextExtension.class) +@ExtendWith(ServiceExtension.class) +public class DTOToEObjectConverterTest { + private static final String PACKAGE_NAME = "org.gecko.emf.converter"; + private static final String NS_URI = "http://gecko.org/test/model/converter/1.0"; + private static final String NS_PREFIX = "tests"; + + @Test + public void testDTO2EObjectConverterWithBuiltInTypeRule() { + + ConverterTestBasicDTO dto = new ConverterTestBasicDTO(); + dto.longPrimitiveField = Long.MIN_VALUE; + dto.booleanPrimitiveField = true; + dto.stringField = "hello"; + + EPackage dynamicEPackageFromDTOs = DTOToEPackageConverter.convert(PACKAGE_NAME, NS_URI, NS_PREFIX, + dto.getClass()); + assertNotNull(dynamicEPackageFromDTOs); + + EPackage.Registry.INSTANCE.put(dynamicEPackageFromDTOs.getNsURI(), dynamicEPackageFromDTOs); + + Converter dto2EObjectConverter = DTOToEObjectConverters.customConverter(dynamicEPackageFromDTOs); + + EObject mySimpleEObject = dto2EObjectConverter.convert(dto).to(EObject.class); + assertNotNull(mySimpleEObject); + } + + @Test + public void testDTO2EObjectConverterBuilderWithBuiltInTypeRule() { + + ConverterTestBasicDTO dto = new ConverterTestBasicDTO(); + dto.longPrimitiveField = Long.MIN_VALUE; + dto.booleanPrimitiveField = true; + dto.stringField = "hello"; + + EPackage dynamicEPackageFromDTOs = DTOToEPackageConverter.convert(PACKAGE_NAME, NS_URI, NS_PREFIX, + dto.getClass()); + assertNotNull(dynamicEPackageFromDTOs); + + EPackage.Registry.INSTANCE.put(dynamicEPackageFromDTOs.getNsURI(), dynamicEPackageFromDTOs); + + ConverterBuilder dto2EObjectConverterBuilder = DTOToEObjectConverters + .newCustomConverterBuilder(dynamicEPackageFromDTOs); + + // .. add some more custom rules as needed + + Converter dto2EObjectConverter = dto2EObjectConverterBuilder.build(); + + EObject mySimpleEObject = dto2EObjectConverter.convert(dto).to(EObject.class); + assertNotNull(mySimpleEObject); + } + + @Test + public void testDTO2EObjectConverterWithBuiltInFunction() throws Exception { + + ConverterTestBasicDTO dto = new ConverterTestBasicDTO(); + dto.longPrimitiveField = Long.MIN_VALUE; + dto.booleanPrimitiveField = true; + dto.stringField = "hello"; + + EPackage dynamicEPackageFromDTOs = DTOToEPackageConverter.convert(PACKAGE_NAME, NS_URI, NS_PREFIX, + dto.getClass()); + assertNotNull(dynamicEPackageFromDTOs); + + EPackage.Registry.INSTANCE.put(dynamicEPackageFromDTOs.getNsURI(), dynamicEPackageFromDTOs); + + Converter dto2EObjectConverter = DTOToEObjectConverters.customConverter(dynamicEPackageFromDTOs); + + Function cf = dto2EObjectConverter.function().to(EObject.class); + + EObject mySimpleEObject = cf.apply(dto); + assertNotNull(mySimpleEObject); + } + + @Test + public void testDTO2EObjectConverterBuilderWithBuiltInFunction() throws Exception { + + ConverterTestBasicDTO dto = new ConverterTestBasicDTO(); + dto.longPrimitiveField = Long.MIN_VALUE; + dto.booleanPrimitiveField = true; + dto.stringField = "hello"; + + EPackage dynamicEPackageFromDTOs = DTOToEPackageConverter.convert(PACKAGE_NAME, NS_URI, NS_PREFIX, + dto.getClass()); + assertNotNull(dynamicEPackageFromDTOs); + + EPackage.Registry.INSTANCE.put(dynamicEPackageFromDTOs.getNsURI(), dynamicEPackageFromDTOs); + + ConverterBuilder dto2EObjectConverterBuilder = DTOToEObjectConverters + .newCustomConverterBuilder(dynamicEPackageFromDTOs); + + // .. add some more custom rules as needed + + Converter dto2EObjectConverter = dto2EObjectConverterBuilder.build(); + + Function cf = dto2EObjectConverter.function().to(EObject.class); + + EObject mySimpleEObject = cf.apply(dto); + assertNotNull(mySimpleEObject); + } +} diff --git a/org.gecko.emf.converter.tests/src/org/gecko/emf/converter/tests/DTOToEPackageConverterTest.java b/org.gecko.emf.converter.tests/src/org/gecko/emf/converter/tests/DTOToEPackageConverterTest.java new file mode 100644 index 00000000..8e03e321 --- /dev/null +++ b/org.gecko.emf.converter.tests/src/org/gecko/emf/converter/tests/DTOToEPackageConverterTest.java @@ -0,0 +1,501 @@ +/** + * Copyright (c) 2012 - 2022 Data In Motion and others. + * All rights reserved. + * + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Data In Motion - initial API and implementation + */ +package org.gecko.emf.converter.tests; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.gecko.emf.converter.DTOToEPackageConverter; +import org.gecko.emf.converter.tests.helper.DTOToEMFConverterTestHelper.ConverterTestAllSupportedTypesDTO; +import org.gecko.emf.converter.tests.helper.DTOToEMFConverterTestHelper.ConverterTestBasicDTO; +import org.gecko.emf.converter.tests.helper.DTOToEMFConverterTestHelper.ConverterTestInheritingDTO; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.platform.commons.annotation.Testable; +import org.osgi.framework.dto.FrameworkDTO; +import org.osgi.test.junit5.context.BundleContextExtension; +import org.osgi.test.junit5.service.ServiceExtension; + +/** + * Integration test for {@link org.gecko.emf.converter.DTOToEPackageConverter} + * + * @author Michal H. Siemaszko + */ +@Testable +@ExtendWith(BundleContextExtension.class) +@ExtendWith(ServiceExtension.class) +public class DTOToEPackageConverterTest { + private static final String PACKAGE_NAME = "org.gecko.emf.converter"; + private static final String NS_URI = "http://gecko.org/test/model/converter/1.0"; + private static final String NS_PREFIX = "tests"; + + @Test + public void testConvertBasicDTO() throws Exception { + Class dtoClass = ConverterTestBasicDTO.class; + + EPackage dynamicEPackageFromDTOs = DTOToEPackageConverter.convert(PACKAGE_NAME, NS_URI, NS_PREFIX, dtoClass); + assertNotNull(dynamicEPackageFromDTOs); + + assertEquals(PACKAGE_NAME, dynamicEPackageFromDTOs.getName()); + assertEquals(NS_URI, dynamicEPackageFromDTOs.getNsURI()); + assertEquals(NS_PREFIX, dynamicEPackageFromDTOs.getNsPrefix()); + + EPackage.Registry.INSTANCE.put(dynamicEPackageFromDTOs.getNsURI(), dynamicEPackageFromDTOs); + + assertThat(dynamicEPackageFromDTOs.getEClassifiers()).hasSize(1); + + assertNotNull(dynamicEPackageFromDTOs.getEClassifier(dtoClass.getSimpleName())); + assertTrue(dynamicEPackageFromDTOs.getEClassifier(dtoClass.getSimpleName()) instanceof EClass); + assertThat( + ((EClass) dynamicEPackageFromDTOs.getEClassifier(dtoClass.getSimpleName())).getEAllStructuralFeatures()) + .hasSize(3); + + List eAllStructuralFeatures = ((EClass) dynamicEPackageFromDTOs + .getEClassifier(dtoClass.getSimpleName())).getEAllStructuralFeatures(); + + boolean hasLongPrimitiveEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "longPrimitiveField".equals(((EAttribute) f).getName()) + && (long.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasLongPrimitiveEAttribute); + + boolean hasBooleanPrimitiveEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "booleanPrimitiveField".equals(((EAttribute) f).getName()) + && (boolean.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasBooleanPrimitiveEAttribute); + + boolean hasStringEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "stringField".equals(((EAttribute) f).getName()) + && (String.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasStringEAttribute); + } + + @Test + public void testConvertInheritingDTO() throws Exception { + Class dtoClass = ConverterTestInheritingDTO.class; + + EPackage dynamicEPackageFromDTOs = DTOToEPackageConverter.convert(PACKAGE_NAME, NS_URI, NS_PREFIX, dtoClass); + assertNotNull(dynamicEPackageFromDTOs); + + assertEquals(PACKAGE_NAME, dynamicEPackageFromDTOs.getName()); + assertEquals(NS_URI, dynamicEPackageFromDTOs.getNsURI()); + assertEquals(NS_PREFIX, dynamicEPackageFromDTOs.getNsPrefix()); + + EPackage.Registry.INSTANCE.put(dynamicEPackageFromDTOs.getNsURI(), dynamicEPackageFromDTOs); + + assertThat(dynamicEPackageFromDTOs.getEClassifiers()).hasSize(1); + + assertNotNull(dynamicEPackageFromDTOs.getEClassifier(dtoClass.getSimpleName())); + assertTrue(dynamicEPackageFromDTOs.getEClassifier(dtoClass.getSimpleName()) instanceof EClass); + assertThat( + ((EClass) dynamicEPackageFromDTOs.getEClassifier(dtoClass.getSimpleName())).getEAllStructuralFeatures()) + .hasSize(9); + + List eAllStructuralFeatures = ((EClass) dynamicEPackageFromDTOs + .getEClassifier(dtoClass.getSimpleName())).getEAllStructuralFeatures(); + + boolean hasBytePrimitiveEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "bytePrimitiveField".equals(((EAttribute) f).getName()) + && (byte.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasBytePrimitiveEAttribute); + + boolean hasShortPrimitiveEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "shortPrimitiveField".equals(((EAttribute) f).getName()) + && (short.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasShortPrimitiveEAttribute); + + boolean hasIntPrimitiveEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "intPrimitiveField".equals(((EAttribute) f).getName()) + && (int.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasIntPrimitiveEAttribute); + + boolean hasLongPrimitiveEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "longPrimitiveField".equals(((EAttribute) f).getName()) + && (long.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasLongPrimitiveEAttribute); + + boolean hasFloatPrimitiveEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "floatPrimitiveField".equals(((EAttribute) f).getName()) + && (float.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasFloatPrimitiveEAttribute); + + boolean hasDoublePrimitiveEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "doublePrimitiveField".equals(((EAttribute) f).getName()) + && (double.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasDoublePrimitiveEAttribute); + + boolean hasBooleanPrimitiveEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "booleanPrimitiveField".equals(((EAttribute) f).getName()) + && (boolean.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasBooleanPrimitiveEAttribute); + + boolean hasCharPrimitiveEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "charPrimitiveField".equals(((EAttribute) f).getName()) + && (char.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasCharPrimitiveEAttribute); + } + + @Test + public void testConvertAllSupportedTypesDTO() throws Exception { + Class dtoClass = ConverterTestAllSupportedTypesDTO.class; + + EPackage dynamicEPackageFromDTOs = DTOToEPackageConverter.convert(PACKAGE_NAME, NS_URI, NS_PREFIX, dtoClass); + assertNotNull(dynamicEPackageFromDTOs); + + assertEquals(PACKAGE_NAME, dynamicEPackageFromDTOs.getName()); + assertEquals(NS_URI, dynamicEPackageFromDTOs.getNsURI()); + assertEquals(NS_PREFIX, dynamicEPackageFromDTOs.getNsPrefix()); + + EPackage.Registry.INSTANCE.put(dynamicEPackageFromDTOs.getNsURI(), dynamicEPackageFromDTOs); + + assertThat(dynamicEPackageFromDTOs.getEClassifiers()).hasSize(8); + + assertNotNull(dynamicEPackageFromDTOs.getEClassifier(dtoClass.getSimpleName())); + assertTrue(dynamicEPackageFromDTOs.getEClassifier(dtoClass.getSimpleName()) instanceof EClass); + + assertThat( + ((EClass) dynamicEPackageFromDTOs.getEClassifier(dtoClass.getSimpleName())).getEAllStructuralFeatures()) + .hasSize(44); + + List eAllStructuralFeatures = ((EClass) dynamicEPackageFromDTOs + .getEClassifier(dtoClass.getSimpleName())).getEAllStructuralFeatures(); + + // Primitive types + boolean hasBytePrimitiveEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "bytePrimitiveField".equals(((EAttribute) f).getName()) + && (byte.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasBytePrimitiveEAttribute); + + boolean hasShortPrimitiveEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "shortPrimitiveField".equals(((EAttribute) f).getName()) + && (short.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasShortPrimitiveEAttribute); + + boolean hasIntPrimitiveEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "intPrimitiveField".equals(((EAttribute) f).getName()) + && (int.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasIntPrimitiveEAttribute); + + boolean hasLongPrimitiveEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "longPrimitiveField".equals(((EAttribute) f).getName()) + && (long.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasLongPrimitiveEAttribute); + + boolean hasFloatPrimitiveEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "floatPrimitiveField".equals(((EAttribute) f).getName()) + && (float.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasFloatPrimitiveEAttribute); + + boolean hasDoublePrimitiveEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "doublePrimitiveField".equals(((EAttribute) f).getName()) + && (double.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasDoublePrimitiveEAttribute); + + boolean hasBooleanPrimitiveEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "booleanPrimitiveField".equals(((EAttribute) f).getName()) + && (boolean.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasBooleanPrimitiveEAttribute); + + boolean hasCharPrimitiveEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "charPrimitiveField".equals(((EAttribute) f).getName()) + && (char.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasCharPrimitiveEAttribute); + + // Wrapper classes for the primitive types + boolean hasByteWrapperEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "byteWrapperField".equals(((EAttribute) f).getName()) + && (Byte.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasByteWrapperEAttribute); + + boolean hasShortWrapperEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "shortWrapperField".equals(((EAttribute) f).getName()) + && (Short.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasShortWrapperEAttribute); + + boolean hasIntWrapperEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "intWrapperField".equals(((EAttribute) f).getName()) + && (Integer.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasIntWrapperEAttribute); + + boolean hasLongWrapperEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "longWrapperField".equals(((EAttribute) f).getName()) + && (Long.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasLongWrapperEAttribute); + + boolean hasFloatWrapperEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "floatWrapperField".equals(((EAttribute) f).getName()) + && (Float.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasFloatWrapperEAttribute); + + boolean hasDoubleWrapperEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "doubleWrapperField".equals(((EAttribute) f).getName()) + && (Double.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasDoubleWrapperEAttribute); + + boolean hasBooleanWrapperEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "booleanWrapperField".equals(((EAttribute) f).getName()) + && (Boolean.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasBooleanWrapperEAttribute); + + boolean hasCharWrapperEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "charWrapperField".equals(((EAttribute) f).getName()) + && (Character.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasCharWrapperEAttribute); + + // String + boolean hasStringEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "stringField".equals(((EAttribute) f).getName()) + && (String.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasStringEAttribute); + + // enum + boolean hasEnumEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "enumField".equals(((EAttribute) f).getName()) + && ("ConverterTestSampleEnum".equals(((EAttribute) f).getEType().getName())))); + assertTrue(hasEnumEAttribute); + + // Version + boolean hasVersionFieldEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "versionField".equals(((EAttribute) f).getName()) + && (org.osgi.framework.Version.class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasVersionFieldEAttribute); + + // Reference to other Data Transfer Objects + boolean hasDtoEReference = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EReference) && "dtoField".equals(((EReference) f).getName()) + && ("ConverterTestBasicDTO".equals(((EReference) f).getEType().getName())))); + assertTrue(hasDtoEReference); + + // List + boolean hasListEReference = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EReference) && "listField".equals(((EReference) f).getName()) + && ("ConverterTestBasicDTO".equals(((EReference) f).getEType().getName())) + && (0 == ((EReference) f).getLowerBound()) && (-1 == ((EReference) f).getUpperBound()))); + assertTrue(hasListEReference); + + // Set + boolean hasSetEReference = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EReference) && "setField".equals(((EReference) f).getName()) + && ("ConverterTestBasicDTO".equals(((EReference) f).getEType().getName())) + && (0 == ((EReference) f).getLowerBound()) && (-1 == ((EReference) f).getUpperBound()))); + assertTrue(hasSetEReference); + + // Map + boolean hasMapWithStringKeysEReference = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EReference) && "mapWithStringKeysField".equals(((EReference) f).getName()) + && ("StringToConverterTestBasicDTOMap".equals(((EReference) f).getEType().getName())) + && (-1 == ((EReference) f).getUpperBound()) + && (2 == ((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().size()) + && ("key".equals( + ((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().get(0).getName())) + && ("EString".equals(((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().get(0) + .getEType().getName())) + && ("value".equals( + ((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().get(1).getName())) + && ("ConverterTestBasicDTO".equals(((EClass) ((EReference) f).getEType()) + .getEAllStructuralFeatures().get(1).getEType().getName())))); + assertTrue(hasMapWithStringKeysEReference); + + boolean mapWithPrimitiveWrapperKeysEReference = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EReference) + && "mapWithPrimitiveWrapperKeysField".equals(((EReference) f).getName()) + && ("IntegerToConverterTestBasicDTOMap".equals(((EReference) f).getEType().getName())) + && (-1 == ((EReference) f).getUpperBound()) + && (2 == ((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().size()) + && ("key".equals( + ((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().get(0).getName())) + && ("EIntegerObject".equals(((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures() + .get(0).getEType().getName())) + && ("value".equals( + ((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().get(1).getName())) + && ("ConverterTestBasicDTO".equals(((EClass) ((EReference) f).getEType()) + .getEAllStructuralFeatures().get(1).getEType().getName())))); + assertTrue(mapWithPrimitiveWrapperKeysEReference); + + boolean mapWithEnumKeysEReference = eAllStructuralFeatures.stream().anyMatch(f -> ((f instanceof EReference) + && "mapWithEnumKeysField".equals(((EReference) f).getName()) + && ("ConverterTestSampleEnumToConverterTestBasicDTOMap".equals(((EReference) f).getEType().getName())) + && (-1 == ((EReference) f).getUpperBound()) + && (2 == ((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().size()) + && ("key".equals(((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().get(0).getName())) + && ("ConverterTestSampleEnum".equals( + ((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().get(0).getEType().getName())) + && ("value".equals(((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().get(1).getName())) + && ("ConverterTestBasicDTO".equals(((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures() + .get(1).getEType().getName())))); + assertTrue(mapWithEnumKeysEReference); + + boolean mapWithVersionKeysEReference = eAllStructuralFeatures.stream().anyMatch(f -> ((f instanceof EReference) + && "mapWithVersionKeysField".equals(((EReference) f).getName()) + && ("VersionToConverterTestBasicDTOMap".equals(((EReference) f).getEType().getName())) + && (-1 == ((EReference) f).getUpperBound()) + && (2 == ((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().size()) + && ("key".equals(((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().get(0).getName())) + && ("EOSGiFrameworkVersion".equals( + ((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().get(0).getEType().getName())) + && ("value".equals(((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().get(1).getName())) + && ("ConverterTestBasicDTO".equals(((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures() + .get(1).getEType().getName())))); + assertTrue(mapWithVersionKeysEReference); + + // array + boolean hasBytePrimitiveArrayEAttribute = eAllStructuralFeatures.stream().anyMatch( + f -> ((f instanceof EAttribute) && "bytePrimitiveArrayField".equals(((EAttribute) f).getName()) + && (byte[].class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasBytePrimitiveArrayEAttribute); + + boolean hasShortPrimitiveArrayEAttribute = eAllStructuralFeatures.stream().anyMatch( + f -> ((f instanceof EAttribute) && "shortPrimitiveArrayField".equals(((EAttribute) f).getName()) + && (short[].class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasShortPrimitiveArrayEAttribute); + + boolean hasIntPrimitiveArrayEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "intPrimitiveArrayField".equals(((EAttribute) f).getName()) + && (int[].class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasIntPrimitiveArrayEAttribute); + + boolean hasLongPrimitiveArrayEAttribute = eAllStructuralFeatures.stream().anyMatch( + f -> ((f instanceof EAttribute) && "longPrimitiveArrayField".equals(((EAttribute) f).getName()) + && (long[].class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasLongPrimitiveArrayEAttribute); + + boolean hasFloatPrimitiveArrayEAttribute = eAllStructuralFeatures.stream().anyMatch( + f -> ((f instanceof EAttribute) && "floatPrimitiveArrayField".equals(((EAttribute) f).getName()) + && (float[].class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasFloatPrimitiveArrayEAttribute); + + boolean hasDoublePrimitiveArrayEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) + && "doublePrimitiveArrayField".equals(((EAttribute) f).getName()) + && (double[].class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasDoublePrimitiveArrayEAttribute); + + boolean hasBooleanPrimitiveArrayEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) + && "booleanPrimitiveArrayField".equals(((EAttribute) f).getName()) + && (boolean[].class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasBooleanPrimitiveArrayEAttribute); + + boolean hasCharPrimitiveArrayEAttribute = eAllStructuralFeatures.stream().anyMatch( + f -> ((f instanceof EAttribute) && "charPrimitiveArrayField".equals(((EAttribute) f).getName()) + && (char[].class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasCharPrimitiveArrayEAttribute); + + boolean hasByteWrapperArrayEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "byteWrapperArrayField".equals(((EAttribute) f).getName()) + && (Byte[].class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasByteWrapperArrayEAttribute); + + boolean hasShortWrapperArrayEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "shortWrapperArrayField".equals(((EAttribute) f).getName()) + && (Short[].class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasShortWrapperArrayEAttribute); + + boolean hasIntWrapperArrayEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "intWrapperArrayField".equals(((EAttribute) f).getName()) + && (Integer[].class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasIntWrapperArrayEAttribute); + + boolean hasLongWrapperArrayEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "longWrapperArrayField".equals(((EAttribute) f).getName()) + && (Long[].class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasLongWrapperArrayEAttribute); + + boolean hasFloatWrapperArrayEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "floatWrapperArrayField".equals(((EAttribute) f).getName()) + && (Float[].class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasFloatWrapperArrayEAttribute); + + boolean hasDoubleWrapperArrayEAttribute = eAllStructuralFeatures.stream().anyMatch( + f -> ((f instanceof EAttribute) && "doubleWrapperArrayField".equals(((EAttribute) f).getName()) + && (Double[].class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasDoubleWrapperArrayEAttribute); + + boolean hasBooleanWrapperArrayEAttribute = eAllStructuralFeatures.stream().anyMatch( + f -> ((f instanceof EAttribute) && "booleanWrapperArrayField".equals(((EAttribute) f).getName()) + && (Boolean[].class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasBooleanWrapperArrayEAttribute); + + boolean hasCharWrapperArrayEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "charWrapperArrayField".equals(((EAttribute) f).getName()) + && (Character[].class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasCharWrapperArrayEAttribute); + + boolean hasStringArrayEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "stringArrayField".equals(((EAttribute) f).getName()) + && (String[].class == ((EAttribute) f).getEType().getInstanceClass()))); + assertTrue(hasStringArrayEAttribute); + + boolean hasDtoArrayEAttribute = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EAttribute) && "dtoArrayField".equals(((EAttribute) f).getName()) + && ("ConverterTestBasicDTOArray".equals(((EAttribute) f).getEType().getName())))); + assertTrue(hasDtoArrayEAttribute); + } + + @Test + public void testConvertOSGiFrameworkDTO() throws Exception { + Class dtoClass = FrameworkDTO.class; + + EPackage dynamicEPackageFromDTOs = DTOToEPackageConverter.convert(PACKAGE_NAME, NS_URI, NS_PREFIX, dtoClass); + assertNotNull(dynamicEPackageFromDTOs); + + assertEquals(PACKAGE_NAME, dynamicEPackageFromDTOs.getName()); + assertEquals(NS_URI, dynamicEPackageFromDTOs.getNsURI()); + assertEquals(NS_PREFIX, dynamicEPackageFromDTOs.getNsPrefix()); + + EPackage.Registry.INSTANCE.put(dynamicEPackageFromDTOs.getNsURI(), dynamicEPackageFromDTOs); + + assertThat(dynamicEPackageFromDTOs.getEClassifiers()).hasSize(4); + + assertNotNull(dynamicEPackageFromDTOs.getEClassifier(dtoClass.getSimpleName())); + assertTrue(dynamicEPackageFromDTOs.getEClassifier(dtoClass.getSimpleName()) instanceof EClass); + assertThat( + ((EClass) dynamicEPackageFromDTOs.getEClassifier(dtoClass.getSimpleName())).getEAllStructuralFeatures()) + .hasSize(3); + + List eAllStructuralFeatures = ((EClass) dynamicEPackageFromDTOs + .getEClassifier(dtoClass.getSimpleName())).getEAllStructuralFeatures(); + + boolean hasBundlesEReference = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EReference) && "bundles".equals(((EReference) f).getName()) + && ("BundleDTO".equals(((EReference) f).getEType().getName())) + && (0 == ((EReference) f).getLowerBound()) && (-1 == ((EReference) f).getUpperBound()))); + assertTrue(hasBundlesEReference); + + boolean hasPropertiesEReference = eAllStructuralFeatures.stream().anyMatch(f -> ((f instanceof EReference) + && "properties".equals(((EReference) f).getName()) + && ("StringToObjectMap".equals(((EReference) f).getEType().getName())) + && (-1 == ((EReference) f).getUpperBound()) + && (2 == ((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().size()) + && ("key".equals(((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().get(0).getName())) + && ("EString".equals( + ((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().get(0).getEType().getName())) + && ("value".equals(((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().get(1).getName())) + && ("EJavaObject".equals(((EClass) ((EReference) f).getEType()).getEAllStructuralFeatures().get(1) + .getEType().getName())))); + assertTrue(hasPropertiesEReference); + + boolean hasServicesEReference = eAllStructuralFeatures.stream() + .anyMatch(f -> ((f instanceof EReference) && "services".equals(((EReference) f).getName()) + && ("ServiceReferenceDTO".equals(((EReference) f).getEType().getName())) + && (0 == ((EReference) f).getLowerBound()) && (-1 == ((EReference) f).getUpperBound()))); + assertTrue(hasServicesEReference); + } +} diff --git a/org.gecko.emf.converter.tests/src/org/gecko/emf/converter/tests/helper/DTOToEMFConverterTestHelper.java b/org.gecko.emf.converter.tests/src/org/gecko/emf/converter/tests/helper/DTOToEMFConverterTestHelper.java new file mode 100644 index 00000000..2c7ac9ab --- /dev/null +++ b/org.gecko.emf.converter.tests/src/org/gecko/emf/converter/tests/helper/DTOToEMFConverterTestHelper.java @@ -0,0 +1,117 @@ +/** + * Copyright (c) 2012 - 2023 Data In Motion and others. + * All rights reserved. + * + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Data In Motion - initial API and implementation + */ +package org.gecko.emf.converter.tests.helper; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.osgi.dto.DTO; +import org.osgi.framework.Version; + +/** + * Helper for + * {@link org.gecko.emf.converter.tests.DTOToEObjectConverterTest} + * + * @author Michal H. Siemaszko + */ +public class DTOToEMFConverterTestHelper { + + public static class ConverterTestBasicDTO extends DTO { + public long longPrimitiveField; + public boolean booleanPrimitiveField; + public String stringField; + } + + public static class ConverterTestInheritingDTO extends ConverterTestBasicDTO { + public byte bytePrimitiveField; + public short shortPrimitiveField; + public int intPrimitiveField; + public float floatPrimitiveField; + public double doublePrimitiveField; + public char charPrimitiveField; + } + + public static class ConverterTestAllSupportedTypesDTO extends DTO { + + // Primitive types + public byte bytePrimitiveField; + public short shortPrimitiveField; + public int intPrimitiveField; + public long longPrimitiveField; + public float floatPrimitiveField; + public double doublePrimitiveField; + public boolean booleanPrimitiveField; + public char charPrimitiveField; + + // Wrapper classes for the primitive types + public Byte byteWrapperField; + public Short shortWrapperField; + public Integer intWrapperField; + public Long longWrapperField; + public Float floatWrapperField; + public Double doubleWrapperField; + public Boolean booleanWrapperField; + public Character charWrapperField; + + // String + public String stringField; + + // enum + public ConverterTestSampleEnum enumField; + + // Version + public Version versionField; + + // Data Transfer Objects + public ConverterTestBasicDTO dtoField; + + // List + public List listField; + + // Set + public Set setField; + + // Map + public Map mapWithPrimitiveWrapperKeysField; + public Map mapWithStringKeysField; + public Map mapWithEnumKeysField; + public Map mapWithVersionKeysField; + + // array + public byte[] bytePrimitiveArrayField; + public short[] shortPrimitiveArrayField; + public int[] intPrimitiveArrayField; + public long[] longPrimitiveArrayField; + public float[] floatPrimitiveArrayField; + public double[] doublePrimitiveArrayField; + public boolean[] booleanPrimitiveArrayField; + public char[] charPrimitiveArrayField; + + public Byte[] byteWrapperArrayField; + public Short[] shortWrapperArrayField; + public Integer[] intWrapperArrayField; + public Long[] longWrapperArrayField; + public Float[] floatWrapperArrayField; + public Double[] doubleWrapperArrayField; + public Boolean[] booleanWrapperArrayField; + public Character[] charWrapperArrayField; + + public String[] stringArrayField; + + public ConverterTestBasicDTO[] dtoArrayField; + } + + public enum ConverterTestSampleEnum { + ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE; + } +} diff --git a/org.gecko.emf.converter.tests/test.bndrun b/org.gecko.emf.converter.tests/test.bndrun new file mode 100644 index 00000000..ad6207c6 --- /dev/null +++ b/org.gecko.emf.converter.tests/test.bndrun @@ -0,0 +1,56 @@ + +-runfw: org.apache.felix.framework;version='[7.0.1,7.0.1]' +-runprovidedcapabilities: ${native_capability} + +-resolve.effective: active + +-library: enableOSGi-Test + +-runrepos: \ + Central,\ + Local,\ + Temp,\ + GeckoEMF Dependencies,\ + Jacoco Dependencies,\ + Workspace,\ + OSGi-Test Dependencies + +-runee: JavaSE-17 + +-runtrace: true + +-runproperties.debug: \ + felix.log.level=4,\ + org.osgi.service.log.admin.loglevel=DEBUG + +-runrequires: \ + bnd.identity;id='org.gecko.emf.converter.tests',\ + bnd.identity;id='org.gecko.emf.converter.model' + +-runbundles: \ + junit-jupiter-api;version='[5.10.1,5.10.2)',\ + junit-jupiter-engine;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)',\ + junit-platform-engine;version='[1.10.1,1.10.2)',\ + junit-platform-launcher;version='[1.10.1,1.10.2)',\ + 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.osgi.util.function;version='[1.2.0,1.2.1)',\ + org.eclipse.emf.common;version='[2.29.0,2.29.1)',\ + org.eclipse.emf.ecore;version='[2.35.0,2.35.1)',\ + org.gecko.emf.converter;version=snapshot,\ + org.gecko.emf.converter.tests;version=snapshot,\ + assertj-core;version='[3.24.2,3.24.3)',\ + net.bytebuddy.byte-buddy;version='[1.14.9,1.14.10)',\ + slf4j.api;version='[1.7.36,1.7.37)',\ + slf4j.simple;version='[1.7.36,1.7.37)',\ + org.apache.felix.scr;version='[2.2.6,2.2.7)',\ + org.eclipse.emf.ecore.xmi;version='[2.36.0,2.36.1)',\ + org.gecko.emf.converter.model;version=snapshot,\ + org.gecko.emf.osgi.component.minimal;version='[6.1.1,6.1.2)',\ + org.osgi.service.cm;version='[1.6.1,1.6.2)',\ + org.osgi.service.component;version='[1.5.1,1.5.2)',\ + org.osgi.util.promise;version='[1.3.0,1.3.1)',\ + org.osgi.util.converter;version='[1.0.9,1.0.10)' diff --git a/org.gecko.emf.converter/.classpath b/org.gecko.emf.converter/.classpath new file mode 100644 index 00000000..67ed681e --- /dev/null +++ b/org.gecko.emf.converter/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/org.gecko.emf.converter/.gitignore b/org.gecko.emf.converter/.gitignore new file mode 100644 index 00000000..90dde36e --- /dev/null +++ b/org.gecko.emf.converter/.gitignore @@ -0,0 +1,3 @@ +/bin/ +/bin_test/ +/generated/ diff --git a/org.gecko.emf.converter/.project b/org.gecko.emf.converter/.project new file mode 100644 index 00000000..cc87cbf6 --- /dev/null +++ b/org.gecko.emf.converter/.project @@ -0,0 +1,23 @@ + + + org.gecko.qvt.osgi + + + + + + org.eclipse.jdt.core.javabuilder + + + + + bndtools.core.bndbuilder + + + + + + org.eclipse.jdt.core.javanature + bndtools.core.bndnature + + diff --git a/org.gecko.emf.converter/.settings/org.eclipse.core.resources.prefs b/org.gecko.emf.converter/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000..e055c8ab --- /dev/null +++ b/org.gecko.emf.converter/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +encoding//.settings/org.eclipse.core.resources.prefs=UTF-8 +encoding//.settings/org.eclipse.jdt.core.prefs=UTF-8 +encoding//.settings/org.eclipse.jdt.ui.prefs=UTF-8 +encoding/=UTF-8 +encoding/bnd.bnd=UTF-8 diff --git a/org.gecko.emf.converter/.settings/org.eclipse.jdt.core.prefs b/org.gecko.emf.converter/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..f2525a8b --- /dev/null +++ b/org.gecko.emf.converter/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,14 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/org.gecko.emf.converter/bnd.bnd b/org.gecko.emf.converter/bnd.bnd new file mode 100644 index 00000000..65aaa9de --- /dev/null +++ b/org.gecko.emf.converter/bnd.bnd @@ -0,0 +1,12 @@ +-library: enable-emf + +-buildpath: \ + org.gecko.emf.converter.model;version=project,\ + org.osgi.service.component,\ + org.osgi.util.converter;version=latest,\ + org.osgi.dto,\ + org.osgi.util.function;version=latest,\ + slf4j.api,\ + org.apache.felix.converter + +-dependson: org.gecko.emf.converter.model diff --git a/org.gecko.emf.converter/src/org/gecko/emf/converter/DTOToEObjectConverterFunction.java b/org.gecko.emf.converter/src/org/gecko/emf/converter/DTOToEObjectConverterFunction.java new file mode 100644 index 00000000..490392a6 --- /dev/null +++ b/org.gecko.emf.converter/src/org/gecko/emf/converter/DTOToEObjectConverterFunction.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2012 - 2024 Data In Motion and others. + * All rights reserved. + * + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Data In Motion - initial API and implementation + */ +package org.gecko.emf.converter; + +import java.lang.reflect.Type; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.osgi.util.converter.ConverterFunction; + +/** + * DTO to EObject {@link org.osgi.util.converter.ConverterFunction} + * + * @author Michal H. Siemaszko + */ +class DTOToEObjectConverterFunction implements ConverterFunction { + private EPackage[] dynamicEPackages; + + public DTOToEObjectConverterFunction(EPackage... dynamicEPackages) { + this.dynamicEPackages = dynamicEPackages; + } + + @Override + public Object apply(Object obj, Type targetType) throws Exception { + if ((targetType instanceof Class) && EObject.class.isAssignableFrom((Class) targetType)) { + return DTOToEObjectConverterUtil.convertDTO2EObject(obj, dynamicEPackages); + } + + return ConverterFunction.CANNOT_HANDLE; + } +} diff --git a/org.gecko.emf.converter/src/org/gecko/emf/converter/DTOToEObjectConverterTypeRuleFunction.java b/org.gecko.emf.converter/src/org/gecko/emf/converter/DTOToEObjectConverterTypeRuleFunction.java new file mode 100644 index 00000000..3a2aae5a --- /dev/null +++ b/org.gecko.emf.converter/src/org/gecko/emf/converter/DTOToEObjectConverterTypeRuleFunction.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2012 - 2024 Data In Motion and others. + * All rights reserved. + * + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Data In Motion - initial API and implementation + */ +package org.gecko.emf.converter; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.osgi.util.function.Function; + +/** + * DTO to EObject {@link org.osgi.util.function.Function} used with + * {@link org.osgi.util.converter.TypeRule} + * + * @author Michal H. Siemaszko + */ +class DTOToEObjectConverterTypeRuleFunction implements Function { + private EPackage[] dynamicEPackages; + + public DTOToEObjectConverterTypeRuleFunction(EPackage... dynamicEPackages) { + this.dynamicEPackages = dynamicEPackages; + } + + @Override + public EObject apply(Object dtoObject) throws Exception { + return DTOToEObjectConverterUtil.convertDTO2EObject(dtoObject, dynamicEPackages); + } +} diff --git a/org.gecko.emf.converter/src/org/gecko/emf/converter/DTOToEObjectConverterUtil.java b/org.gecko.emf.converter/src/org/gecko/emf/converter/DTOToEObjectConverterUtil.java new file mode 100644 index 00000000..19094f3d --- /dev/null +++ b/org.gecko.emf.converter/src/org/gecko/emf/converter/DTOToEObjectConverterUtil.java @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2012 - 2024 Data In Motion and others. + * All rights reserved. + * + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Data In Motion - initial API and implementation + */ +package org.gecko.emf.converter; + +import java.util.Arrays; +import java.util.Map; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EFactory; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.osgi.util.converter.Converters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * DTO to EObject utility methods + * + * @author Michal H. Siemaszko + */ +class DTOToEObjectConverterUtil { + private final static Logger LOG = LoggerFactory.getLogger(DTOToEObjectConverterUtil.class); + + public final static EObject convertDTO2EObject(Object dtoObject, EPackage... dynamicEPackages) { + String eClassifierName = dtoObject.getClass().getSimpleName(); + + if (!DTOUtil.isDTOType(dtoObject.getClass(), true, true)) { + LOG.warn(" {} is not DTO-like !", eClassifierName); + return null; + } + + EPackage containingEPackage = findContainingEPackage(eClassifierName, dynamicEPackages); + if (containingEPackage == null) { + LOG.warn(" Could not find any EPackage containing EClassifier {} !", eClassifierName); + return null; + } + + EClassifier eClassifier = findEClassifier(eClassifierName, containingEPackage); + if (eClassifier == null) { + LOG.warn(" Could not find any EClassifier {} !", eClassifierName); + return null; + } + + Map dtoAsMap = Converters.standardConverter().convert(dtoObject).sourceAsDTO().to(Map.class); + + EClass eClass = (EClass) eClassifier; + + EFactory eFactory = containingEPackage.getEFactoryInstance(); + + EObject eObject = eFactory.create(eClass); + + for (EStructuralFeature eStructuralFeature : eClass.getEAllStructuralFeatures()) { + String eStructuralFeatureName = eStructuralFeature.getName(); + + if (dtoAsMap.containsKey(eStructuralFeatureName)) { + Object dtoFieldValue = dtoAsMap.get(eStructuralFeatureName); + + eObject.eSet(eStructuralFeature, dtoFieldValue); + } + } + + return eObject; + } + + private static EPackage findContainingEPackage(String eClassifierName, EPackage... dynamicEPackages) { + // @formatter:off + return Arrays.asList(dynamicEPackages).stream() + .filter(p -> ( p.getEClassifier(eClassifierName) != null ) ) + .findFirst() + .orElse(null); + // @formatter:on + } + + private static EClassifier findEClassifier(String name, EPackage dynamicEPackage) { + // @formatter:off + return dynamicEPackage.getEClassifiers().stream() + .filter(c -> name.equalsIgnoreCase(c.getName())) + .findFirst() + .orElse(null); + // @formatter:on + } + + @SuppressWarnings("unused") + private static EClassifier findEClassifier(String name, EPackage... dynamicEPackages) { + // @formatter:off + return Arrays.asList(dynamicEPackages).stream() + .flatMap(p -> p.getEClassifiers().stream()) + .filter(c -> name.equalsIgnoreCase(c.getName())) + .findFirst() + .orElse(null); + // @formatter:on + } +} diff --git a/org.gecko.emf.converter/src/org/gecko/emf/converter/DTOToEObjectConverters.java b/org.gecko.emf.converter/src/org/gecko/emf/converter/DTOToEObjectConverters.java new file mode 100644 index 00000000..4f40d87b --- /dev/null +++ b/org.gecko.emf.converter/src/org/gecko/emf/converter/DTOToEObjectConverters.java @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2012 - 2024 Data In Motion and others. + * All rights reserved. + * + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Data In Motion - initial API and implementation + */ +package org.gecko.emf.converter; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.osgi.util.converter.Converter; +import org.osgi.util.converter.ConverterBuilder; +import org.osgi.util.converter.Converters; +import org.osgi.util.converter.TypeRule; + +/** + * Factory class to obtain a preconfigured DTO to EObject Converter as well as + * the standard converter or a new standard converter builder. + * + * Based on {@link org.osgi.util.converter.Converters} + * + * @author Michal H. Siemaszko + */ +public class DTOToEObjectConverters { + private DTOToEObjectConverters() { + } + + public static Converter customConverter(EPackage... dynamicEPackages) { + return newCustomConverterBuilder(dynamicEPackages).build(); + } + + public static ConverterBuilder newCustomConverterBuilder(EPackage... dynamicEPackages) { + ConverterBuilder cb = Converters.newConverterBuilder(); + + cb.rule(new DTOToEObjectConverterFunction(dynamicEPackages)); + + cb.rule(new TypeRule(Object.class, EObject.class, + new DTOToEObjectConverterTypeRuleFunction(dynamicEPackages))); + + return cb; + } +} diff --git a/org.gecko.emf.converter/src/org/gecko/emf/converter/DTOToEPackageConverter.java b/org.gecko.emf.converter/src/org/gecko/emf/converter/DTOToEPackageConverter.java new file mode 100644 index 00000000..e6be3d23 --- /dev/null +++ b/org.gecko.emf.converter/src/org/gecko/emf/converter/DTOToEPackageConverter.java @@ -0,0 +1,448 @@ +/** + * Copyright (c) 2012 - 2024 Data In Motion and others. + * All rights reserved. + * + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Data In Motion - initial API and implementation + */ +package org.gecko.emf.converter; + +import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EEnum; +import org.eclipse.emf.ecore.EEnumLiteral; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.ETypedElement; +import org.eclipse.emf.ecore.EcoreFactory; +import org.eclipse.emf.ecore.EcorePackage; +import org.gecko.emf.converter.model.ConverterPackage; +import org.osgi.dto.DTO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * DTO to EPackge converter + * + * @author Michal H. Siemaszko + */ +public class DTOToEPackageConverter { + private final static Logger LOG = LoggerFactory.getLogger(DTOToEPackageConverter.class); + + private final static Map, Field[]> CACHED_FIELDS = Collections + .synchronizedMap(new WeakHashMap, Field[]>()); + + private final static Map, EDataType> JAVATYPE_TO_EDATATYPE = new HashMap<>(); + static { + // @formatter:off + EcorePackage.eINSTANCE.getEClassifiers().stream() + .filter(EDataType.class::isInstance) + .map(EDataType.class::cast) + .forEach(dt -> JAVATYPE_TO_EDATATYPE.put(dt.getInstanceClass(), dt)); + // @formatter:on + + // @formatter:off + ConverterPackage.eINSTANCE.getEClassifiers().stream() + .filter(EDataType.class::isInstance) + .map(EDataType.class::cast) + .forEach(dt -> JAVATYPE_TO_EDATATYPE.put(dt.getInstanceClass(), dt)); + // @formatter:on + } + + // @formatter:off + private final static List> ATTRIBUTE_TYPES = List.of( + byte.class, + byte[].class, + java.lang.Byte.class, + java.lang.Byte[].class, + + short.class, + short[].class, + java.lang.Short.class, + java.lang.Short[].class, + + int.class, + int[].class, + java.lang.Integer.class, + java.lang.Integer[].class, + + long.class, + long[].class, + java.lang.Long.class, + java.lang.Long[].class, + + float.class, + float[].class, + java.lang.Float.class, + java.lang.Float[].class, + + double.class, + double[].class, + java.lang.Double.class, + java.lang.Double[].class, + + boolean.class, + boolean[].class, + java.lang.Boolean.class, + java.lang.Boolean[].class, + + char.class, + char[].class, + java.lang.Character.class, + java.lang.Character[].class, + + java.lang.String.class, + java.lang.String[].class, + + org.osgi.framework.Version.class); + // @formatter:on + + private DTOToEPackageConverter() { + // Do not instantiate. This is a utility class. + } + + @SafeVarargs + public final static EPackage convert(String packageName, String nsURI, String nsPrefix, + Class... dtoClasses) { + + final EcoreFactory eFactory = EcoreFactory.eINSTANCE; + + EPackage dynamicEPackage = eFactory.createEPackage(); + dynamicEPackage.setName(packageName); + dynamicEPackage.setNsURI(nsURI); + dynamicEPackage.setNsPrefix(nsPrefix); + + for (Class dtoClass : dtoClasses) { + createEClass(eFactory, dynamicEPackage, dtoClass); + } + + return dynamicEPackage; + } + + private static EClass createEClass(EcoreFactory eFactory, EPackage ePackage, Class javaType) { + if (dynamicEClassifierExists(ePackage, javaType.getSimpleName())) { + LOG.debug(" EClassifier {} already exists!", javaType.getSimpleName()); + return (EClass) ePackage.getEClassifier(javaType.getSimpleName()); + } + + Field[] fields = getFields(javaType); + + EClass eClass = eFactory.createEClass(); + eClass.setName(javaType.getSimpleName()); + + for (Field field : fields) { + createEStructuralFeature(eFactory, ePackage, eClass, field); + } + + ePackage.getEClassifiers().add(eClass); + + return eClass; + } + + private static void createEStructuralFeature(EcoreFactory eFactory, EPackage ePackage, EClass eClass, Field field) { + if (isAttributeType(field.getType())) { + + createEAttribute(eFactory, eClass, field); + + } else if (isEnumType(field.getType())) { + + createEEnum(eFactory, ePackage, eClass, field); + + } else if (isArrayType(field.getType())) { + + createArray(eFactory, ePackage, eClass, field); + + } else if (isCollectionType(field.getType())) { + + Class collectionActualType = getCollectionActualType(field.getGenericType()); + if (collectionActualType == null) { + LOG.error(" Could not determine actual type for collection specified in field {}! Skipping..", + field.getName()); + return; + } + + createEReference(eFactory, ePackage, eClass, collectionActualType, field.getName(), + ETypedElement.UNBOUNDED_MULTIPLICITY); + + } else if (isMapType(field.getType())) { + + Class mapKeyActualType = getMapKeyActualType(field.getGenericType()); + Class mapValueActualType = getMapValueActualType(field.getGenericType()); + if ((mapKeyActualType == null) || (mapValueActualType == null)) { + LOG.error(" Could not determine actual type for map {} specified in field {}! Skipping..", + ((mapKeyActualType == null) ? "key" : "value"), field.getName()); + return; + } + + createEMap(eFactory, ePackage, eClass, field, mapKeyActualType, mapValueActualType); + + } else { + + createEReference(eFactory, ePackage, eClass, field, ETypedElement.UNSPECIFIED_MULTIPLICITY); + } + } + + private static void createEAttribute(EcoreFactory eFactory, EClass eClass, Field field) { + createEAttribute(eFactory, eClass, getEDataTypeForJavaType(field.getType()), field); + } + + private static void createEAttribute(EcoreFactory eFactory, EClass eClass, EDataType eType, Field field) { + EAttribute eAttribute = eFactory.createEAttribute(); + eAttribute.setName(field.getName()); + eAttribute.setEType(eType); + + eClass.getEStructuralFeatures().add(eAttribute); + } + + private static void createEReference(EcoreFactory eFactory, EPackage ePackage, EClass eClass, Field field, + int upperBound) { + createEReference(eFactory, ePackage, eClass, field.getType(), field.getName(), upperBound); + } + + private static void createEReference(EcoreFactory eFactory, EPackage ePackage, EClass eClass, Class javaType, + String fieldName, int upperBound) { + createEReference(eFactory, ePackage, eClass, getEClassifierForJavaType(eFactory, ePackage, javaType), fieldName, + upperBound); + } + + private static void createEReference(EcoreFactory eFactory, EPackage ePackage, EClass eClass, EClassifier eType, + String fieldName, int upperBound) { + EReference eReference = eFactory.createEReference(); + eReference.setName(fieldName); + eReference.setEType(eType); + eReference.setContainment(true); + eReference.setUpperBound(upperBound); + + eClass.getEStructuralFeatures().add(eReference); + } + + private static void createEEnum(EcoreFactory eFactory, EPackage ePackage, EClass eClass, Field field) { + EEnum eEnum = null; + + if (!dynamicEClassifierExists(ePackage, field.getType().getSimpleName())) { + eEnum = createEEnum(eFactory, ePackage, field.getType()); + } else { + eEnum = (EEnum) ePackage.getEClassifier(field.getType().getSimpleName()); + } + + createEAttribute(eFactory, eClass, eEnum, field); + } + + private static EEnum createEEnum(EcoreFactory eFactory, EPackage ePackage, Class javaType) { + Field[] enumTypeFields = getFields(javaType); + + EEnum eEnum = eFactory.createEEnum(); + eEnum.setName(javaType.getSimpleName()); + + for (Field enumTypeField : enumTypeFields) { + EEnumLiteral eEnumLiteral = eFactory.createEEnumLiteral(); + eEnumLiteral.setName(enumTypeField.getName()); + eEnumLiteral.setLiteral(enumTypeField.getName()); + + eEnum.getELiterals().add(eEnumLiteral); + } + + ePackage.getEClassifiers().add(eEnum); + return eEnum; + } + + private static void createArray(EcoreFactory eFactory, EPackage ePackage, EClass eClass, Field field) { + String arrayTypeName = constructArrayTypeName(field); + + EDataType arrayType = null; + + if (!dynamicEClassifierExists(ePackage, arrayTypeName)) { + arrayType = EcoreFactory.eINSTANCE.createEDataType(); + arrayType.setName(arrayTypeName); + + ePackage.getEClassifiers().add(arrayType); + } else { + arrayType = (EDataType) ePackage.getEClassifier(arrayTypeName); + } + + createEAttribute(eFactory, eClass, arrayType, field); + } + + private static String constructArrayTypeName(Field field) { + StringBuilder sb = new StringBuilder(); + sb.append(field.getType().getComponentType().getSimpleName()); + sb.append("Array"); + return sb.toString(); + } + + private static void createEMap(EcoreFactory eFactory, EPackage ePackage, EClass eClass, Field field, + Class mapKeyActualType, Class mapValueActualType) { + String mapEntryEClassName = constructMapEntryEClassName(mapKeyActualType, mapValueActualType); + + EClass mapEntryEClass = null; + + if (!dynamicEClassifierExists(ePackage, mapEntryEClassName)) { + mapEntryEClass = eFactory.createEClass(); + mapEntryEClass.setName(mapEntryEClassName); + mapEntryEClass.setInstanceClassName("java.util.Map$Entry"); + + // key + EReference dynamicMapEntryKeyEReference = eFactory.createEReference(); + dynamicMapEntryKeyEReference.setName("key"); + dynamicMapEntryKeyEReference.setEType(getEClassifierForJavaType(eFactory, ePackage, mapKeyActualType)); + mapEntryEClass.getEStructuralFeatures().add(dynamicMapEntryKeyEReference); + + // value + EReference dynamicMapEntryValueEReference = eFactory.createEReference(); + dynamicMapEntryValueEReference.setName("value"); + dynamicMapEntryValueEReference.setEType(getEClassifierForJavaType(eFactory, ePackage, mapValueActualType)); + mapEntryEClass.getEStructuralFeatures().add(dynamicMapEntryValueEReference); + + ePackage.getEClassifiers().add(mapEntryEClass); + + } else { + mapEntryEClass = (EClass) ePackage.getEClassifier(mapEntryEClassName); + } + + // reference to map entry class + createEReference(eFactory, ePackage, eClass, mapEntryEClass, field.getName(), + ETypedElement.UNBOUNDED_MULTIPLICITY); + } + + private static String constructMapEntryEClassName(Class mapKeyActualType, Class mapValueActualType) { + StringBuilder sb = new StringBuilder(); + sb.append(mapKeyActualType.getSimpleName()); + sb.append("To"); + sb.append(mapValueActualType.getSimpleName()); + sb.append("Map"); + return sb.toString(); + } + + private static boolean dynamicEClassifierExists(EPackage ePackage, String eClassName) { + return ePackage.getEClassifiers().stream().anyMatch(e -> eClassName.equals(e.getName())); + } + + private static boolean dynamicEClassifierExists(EPackage ePackage, Class eClass) { + return dynamicEClassifierExists(ePackage, eClass.getSimpleName()); + } + + private static EClassifier getEClassifierForJavaType(EcoreFactory eFactory, EPackage ePackage, Class javaType) { + if (JAVATYPE_TO_EDATATYPE.containsKey(javaType)) { + return JAVATYPE_TO_EDATATYPE.get(javaType); + } else if (dynamicEClassifierExists(ePackage, javaType)) { + if (isEnumType(javaType)) { + return (EEnum) ePackage.getEClassifier(javaType.getSimpleName()); + } else { + return (EClass) ePackage.getEClassifier(javaType.getSimpleName()); + } + } else { + if (isEnumType(javaType)) { + return createEEnum(eFactory, ePackage, javaType); + } else { + return createEClass(eFactory, ePackage, javaType); + } + } + } + + private static EDataType getEDataTypeForJavaType(Class javaType) { + if (JAVATYPE_TO_EDATATYPE.containsKey(javaType)) { + return JAVATYPE_TO_EDATATYPE.get(javaType); + } else { + throw new IllegalArgumentException(String.format("Type %s is not supported!", javaType.getName())); + } + } + + private static boolean isAttributeType(Class javaType) { + return ATTRIBUTE_TYPES.contains(javaType); + } + + private static boolean isArrayType(Class javaType) { + return javaType.isArray(); + } + + private static boolean isEnumType(Class javaType) { + return javaType.isEnum(); + } + + private static boolean isCollectionType(Class javaType) { + return (javaType.isAssignableFrom(java.util.List.class) || javaType.isAssignableFrom(java.util.Set.class)); + } + + private static boolean isMapType(Class javaType) { + return (javaType.isAssignableFrom(java.util.Map.class)); + } + + @SuppressWarnings("unchecked") + private static Class getCollectionActualType(Type genericType) { + Type[] typeArguments = getActualTypes(genericType); + if (typeArguments.length > 0) { + return ((Class) typeArguments[0]); + } else { + return null; + } + } + + @SuppressWarnings("unchecked") + private static Class getMapKeyActualType(Type genericType) { + Type[] typeArguments = getActualTypes(genericType); + if (typeArguments.length > 1) { + return ((Class) typeArguments[0]); + } else { + return null; + } + } + + @SuppressWarnings("unchecked") + private static Class getMapValueActualType(Type genericType) { + Type[] typeArguments = getActualTypes(genericType); + if (typeArguments.length > 1) { + return ((Class) typeArguments[1]); + } else { + return null; + } + } + + private static Type[] getActualTypes(Type genericType) { + return ((java.lang.reflect.ParameterizedType) genericType).getActualTypeArguments(); + } + + /** + * based on + * {@link osgi.enroute.dtos.bndlib.provider.DTOsProvider.getFields(Class)} + **/ + private static Field[] getFields(Class c) { + Field fields[] = CACHED_FIELDS.get(c); + if (fields == null) { + List publicFields = new ArrayList<>(); + + for (Field field : c.getFields()) { + if (field.isSynthetic()) { + continue; + } + + publicFields.add(field); + } + Collections.sort(publicFields, new Comparator() { + + @Override + public int compare(Field o1, Field o2) { + return o1.getName().compareTo(o2.getName()); + } + }); + + CACHED_FIELDS.put(c.getClass(), fields = publicFields.toArray(new Field[publicFields.size()])); + } + return fields; + } +} diff --git a/org.gecko.emf.converter/src/org/gecko/emf/converter/DTOUtil.java b/org.gecko.emf.converter/src/org/gecko/emf/converter/DTOUtil.java new file mode 100644 index 00000000..1187bd34 --- /dev/null +++ b/org.gecko.emf.converter/src/org/gecko/emf/converter/DTOUtil.java @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2012 - 2024 Data In Motion and others. + * All rights reserved. + * + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Data In Motion - initial API and implementation + */ +package org.gecko.emf.converter; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Arrays; + +/** + * Based on {@link org.osgi.util.converter.DTOUtil}, as currently it is + * package-private. + * + * @author Michal H. Siemaszko + */ +class DTOUtil { + private static final Method[] OBJECT_CLASS_METHODS = Object.class.getMethods(); + + private DTOUtil() { + // Do not instantiate. This is a utility class. + } + + static boolean isDTOType(Class cls, boolean ignorePublicNoArgsCtor, boolean allowStaticMethods) { + if (!ignorePublicNoArgsCtor) { + if (Arrays.stream(cls.getConstructors()).noneMatch(ctor -> ctor.getParameterCount() == 0)) { + // No public zero-arg constructor, not a DTO + return false; + } + } + + for (Method m : cls.getMethods()) { + if ((!allowStaticMethods && isNotObjectClassMethod(m)) + || (allowStaticMethods && isNotObjectClassMethod(m) && !Modifier.isStatic(m.getModifiers()))) { + return false; + } + } + + boolean foundField = false; + for (Field f : cls.getFields()) { + int modifiers = f.getModifiers(); + if (Modifier.isStatic(modifiers)) { + // ignore static fields + continue; + } + + if (!Modifier.isPublic(modifiers)) { + return false; + } + foundField = true; + } + return foundField; + } + + private static boolean isNotObjectClassMethod(Method m) { + return (Arrays.stream(OBJECT_CLASS_METHODS).noneMatch(om -> om.getName().equals(m.getName()) + && Arrays.equals(om.getParameterTypes(), m.getParameterTypes()))); + } +} diff --git a/org.gecko.emf.converter/src/org/gecko/emf/converter/package-info.java b/org.gecko.emf.converter/src/org/gecko/emf/converter/package-info.java new file mode 100644 index 00000000..d2d5d317 --- /dev/null +++ b/org.gecko.emf.converter/src/org/gecko/emf/converter/package-info.java @@ -0,0 +1,2 @@ +@org.osgi.annotation.bundle.Export +package org.gecko.emf.converter; diff --git a/org.gecko.emf.converter/test/.keep b/org.gecko.emf.converter/test/.keep new file mode 100644 index 00000000..e69de29b diff --git a/org.gecko.emf.csv.tests/src/org/gecko/emf/csv/tests/EMFCSVResourceTest.java b/org.gecko.emf.csv.tests/src/org/gecko/emf/csv/tests/EMFCSVResourceTest.java index 64270bcb..4001f5eb 100644 --- a/org.gecko.emf.csv.tests/src/org/gecko/emf/csv/tests/EMFCSVResourceTest.java +++ b/org.gecko.emf.csv.tests/src/org/gecko/emf/csv/tests/EMFCSVResourceTest.java @@ -35,9 +35,12 @@ import org.gecko.emf.osgi.example.model.basic.BasicFactory; import org.gecko.emf.osgi.example.model.basic.BusinessPerson; import org.gecko.emf.osgi.example.model.basic.Family; +import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.platform.commons.annotation.Testable; import org.osgi.framework.ServiceReference; import org.osgi.test.common.annotation.InjectService; import org.osgi.test.common.service.ServiceAware; @@ -49,8 +52,10 @@ * * @author Michal H. Siemaszko */ +@Testable @ExtendWith(BundleContextExtension.class) @ExtendWith(ServiceExtension.class) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) @RequireEMFCSV public class EMFCSVResourceTest { diff --git a/org.gecko.emf.csv.tests/test.bndrun b/org.gecko.emf.csv.tests/test.bndrun index 107ba0cb..836fde18 100644 --- a/org.gecko.emf.csv.tests/test.bndrun +++ b/org.gecko.emf.csv.tests/test.bndrun @@ -33,13 +33,8 @@ org.gecko.emf.exporter.csv.api;version=snapshot,\ com.google.guava;version='[32.1.2,32.1.3)',\ com.google.guava.failureaccess;version='[1.0.1,1.0.2)',\ - org.osgi.service.cm;version='[1.6.0,1.6.1)',\ 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)',\ assertj-core;version='[3.24.2,3.24.3)',\ - de.siegmar.fastcsv;version='[2.2.2,2.2.3)',\ junit-jupiter-api;version='[5.10.1,5.10.2)',\ junit-jupiter-engine;version='[5.10.1,5.10.2)',\ junit-jupiter-params;version='[5.10.1,5.10.2)',\ @@ -53,16 +48,17 @@ org.osgi.test.junit5;version='[1.2.1,1.2.2)',\ org.gecko.emf.csv;version=snapshot,\ org.gecko.emf.csv.tests;version=snapshot,\ - org.apache.commons.logging;version='[1.2.0,1.2.1)',\ - com.github.miachm.sods;version='[1.6.2,1.6.3)',\ - org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ - org.apache.felix.metatype;version='[1.2.4,1.2.5)',\ - org.gecko.emf.exporter.ods;version=snapshot,\ - org.gecko.emf.osgi.component;version='[6.0.1,6.0.2)',\ - org.gecko.emf.osgi.example.model.basic;version='[6.0.0,6.0.1)',\ org.osgi.service.component;version='[1.5.1,1.5.2)',\ - org.osgi.service.log;version='[1.5.0,1.5.1)',\ - org.osgi.util.converter;version='[1.0.9,1.0.10)',\ org.osgi.util.function;version='[1.2.0,1.2.1)',\ org.osgi.util.promise;version='[1.3.0,1.3.1)',\ - slf4j.jcl;version='[1.7.36,1.7.37)' + de.siegmar.fastcsv;version='[3.0.0,3.0.1)',\ + org.apache.commons.commons-compress;version='[1.21.0,1.21.1)',\ + org.apache.servicemix.bundles.poi;version='[5.2.2,5.2.3)',\ + 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.1.1,6.1.2)',\ + org.gecko.emf.osgi.example.model.basic;version='[6.1.0,6.1.1)',\ + org.osgi.service.cm;version='[1.6.1,1.6.2)',\ + slf4j.simple;version='[1.7.36,1.7.37)',\ + org.osgi.util.converter;version='[1.0.9,1.0.10)' diff --git a/org.gecko.emf.exporter.csv.tests/test.bndrun b/org.gecko.emf.exporter.csv.tests/test.bndrun index 88778927..8c751bd1 100644 --- a/org.gecko.emf.exporter.csv.tests/test.bndrun +++ b/org.gecko.emf.exporter.csv.tests/test.bndrun @@ -51,20 +51,16 @@ 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.util.model;version=snapshot,\ - de.siegmar.fastcsv;version='[2.2.2,2.2.3)',\ org.gecko.emf.exporter.csv;version=snapshot,\ - org.apache.commons.logging;version='[1.2.0,1.2.1)',\ org.osgi.service.component;version='[1.5.1,1.5.2)',\ org.osgi.util.function;version='[1.2.0,1.2.1)',\ org.osgi.util.promise;version='[1.3.0,1.3.1)',\ - slf4j.jcl;version='[1.7.36,1.7.37)',\ - org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ - org.osgi.util.converter;version='[1.0.9,1.0.10)',\ 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.api;version='[6.1.1,6.1.2)',\ - org.gecko.emf.osgi.component.config;version='[6.1.1,6.1.2)',\ org.gecko.emf.osgi.component.minimal;version='[6.1.1,6.1.2)',\ org.gecko.emf.osgi.example.model.basic;version='[6.1.0,6.1.1)',\ - org.osgi.service.cm;version='[1.6.1,1.6.2)' + org.osgi.service.cm;version='[1.6.1,1.6.2)',\ + de.siegmar.fastcsv;version='[3.0.0,3.0.1)',\ + slf4j.simple;version='[1.7.36,1.7.37)',\ + org.osgi.util.converter;version='[1.0.9,1.0.10)' diff --git a/org.gecko.emf.exporter.ods.tests/test.bndrun b/org.gecko.emf.exporter.ods.tests/test.bndrun index e78713e1..948bb6dc 100644 --- a/org.gecko.emf.exporter.ods.tests/test.bndrun +++ b/org.gecko.emf.exporter.ods.tests/test.bndrun @@ -33,7 +33,6 @@ org.gecko.emf.exporter.ods.tests;version=snapshot,\ org.apache.commons.commons-text;version='[1.10.0,1.10.1)',\ org.apache.commons.lang3;version='[3.12.0,3.12.1)',\ - com.github.miachm.sods;version='[1.6.2,1.6.3)',\ slf4j.api;version='[1.7.36,1.7.37)',\ com.google.guava;version='[32.1.2,32.1.3)',\ com.google.guava.failureaccess;version='[1.0.1,1.0.2)',\ @@ -52,19 +51,16 @@ 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.util.model;version=snapshot,\ - org.apache.commons.logging;version='[1.2.0,1.2.1)',\ org.osgi.service.component;version='[1.5.1,1.5.2)',\ org.osgi.util.function;version='[1.2.0,1.2.1)',\ org.osgi.util.promise;version='[1.3.0,1.3.1)',\ - slf4j.jcl;version='[1.7.36,1.7.37)',\ - org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ - org.osgi.util.converter;version='[1.0.9,1.0.10)',\ 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.api;version='[6.1.1,6.1.2)',\ - org.gecko.emf.osgi.component.config;version='[6.1.1,6.1.2)',\ org.gecko.emf.osgi.component.minimal;version='[6.1.1,6.1.2)',\ org.gecko.emf.osgi.example.model.basic;version='[6.1.0,6.1.1)',\ - org.osgi.service.cm;version='[1.6.1,1.6.2)' + org.osgi.service.cm;version='[1.6.1,1.6.2)',\ + org.gecko.com.github.miachm.sods;version=snapshot,\ + slf4j.simple;version='[1.7.36,1.7.37)',\ + org.osgi.util.converter;version='[1.0.9,1.0.10)' -resolve: auto \ No newline at end of file diff --git a/org.gecko.emf.exporter.r_lang.tests/test.bndrun b/org.gecko.emf.exporter.r_lang.tests/test.bndrun index 5dec2430..8bc78869 100644 --- a/org.gecko.emf.exporter.r_lang.tests/test.bndrun +++ b/org.gecko.emf.exporter.r_lang.tests/test.bndrun @@ -59,17 +59,15 @@ 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.util.model;version=snapshot,\ - org.apache.commons.logging;version='[1.2.0,1.2.1)',\ org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ org.osgi.service.component;version='[1.5.1,1.5.2)',\ org.osgi.util.function;version='[1.2.0,1.2.1)',\ org.osgi.util.promise;version='[1.3.0,1.3.1)',\ - slf4j.jcl;version='[1.7.36,1.7.37)',\ - org.osgi.util.converter;version='[1.0.9,1.0.10)',\ 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.api;version='[6.1.1,6.1.2)',\ - org.gecko.emf.osgi.component.config;version='[6.1.1,6.1.2)',\ org.gecko.emf.osgi.component.minimal;version='[6.1.1,6.1.2)',\ - org.gecko.emf.osgi.example.model.basic;version='[6.1.0,6.1.1)' + org.gecko.emf.osgi.example.model.basic;version='[6.1.0,6.1.1)',\ + org.osgi.service.cm;version='[1.6.1,1.6.2)',\ + slf4j.simple;version='[1.7.36,1.7.37)',\ + org.osgi.util.converter;version='[1.0.9,1.0.10)' diff --git a/org.gecko.emf.exporter.xlsx.tests/test.bndrun b/org.gecko.emf.exporter.xlsx.tests/test.bndrun index a1bee3d1..95a078f7 100644 --- a/org.gecko.emf.exporter.xlsx.tests/test.bndrun +++ b/org.gecko.emf.exporter.xlsx.tests/test.bndrun @@ -56,18 +56,14 @@ 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.commons.logging;version='[1.2.0,1.2.1)',\ org.osgi.service.component;version='[1.5.1,1.5.2)',\ org.osgi.util.function;version='[1.2.0,1.2.1)',\ org.osgi.util.promise;version='[1.3.0,1.3.1)',\ - slf4j.jcl;version='[1.7.36,1.7.37)',\ - org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ - org.osgi.util.converter;version='[1.0.9,1.0.10)',\ 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.api;version='[6.1.1,6.1.2)',\ - org.gecko.emf.osgi.component.config;version='[6.1.1,6.1.2)',\ org.gecko.emf.osgi.component.minimal;version='[6.1.1,6.1.2)',\ org.gecko.emf.osgi.example.model.basic;version='[6.1.0,6.1.1)',\ - org.osgi.service.cm;version='[1.6.1,1.6.2)' + org.osgi.service.cm;version='[1.6.1,1.6.2)',\ + slf4j.simple;version='[1.7.36,1.7.37)',\ + org.osgi.util.converter;version='[1.0.9,1.0.10)' diff --git a/org.gecko.emf.json.tests/test.bndrun b/org.gecko.emf.json.tests/test.bndrun index a25d73c7..8500d0a2 100644 --- a/org.gecko.emf.json.tests/test.bndrun +++ b/org.gecko.emf.json.tests/test.bndrun @@ -50,16 +50,13 @@ 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.json.tests;version=snapshot,\ - org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ org.osgi.service.component;version='[1.5.1,1.5.2)',\ - org.osgi.util.converter;version='[1.0.9,1.0.10)',\ org.osgi.util.function;version='[1.2.0,1.2.1)',\ org.osgi.util.promise;version='[1.3.0,1.3.1)',\ 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.api;version='[6.1.1,6.1.2)',\ - org.gecko.emf.osgi.component.config;version='[6.1.1,6.1.2)',\ org.gecko.emf.osgi.component.minimal;version='[6.1.1,6.1.2)',\ org.gecko.emf.osgi.example.model.basic;version='[6.1.0,6.1.1)',\ - org.osgi.service.cm;version='[1.6.1,1.6.2)' + org.osgi.service.cm;version='[1.6.1,1.6.2)',\ + org.osgi.util.converter;version='[1.0.9,1.0.10)' diff --git a/org.gecko.emf.ods.tests/src/org/gecko/emf/ods/tests/EMFODSResourceTest.java b/org.gecko.emf.ods.tests/src/org/gecko/emf/ods/tests/EMFODSResourceTest.java index 0ec61c59..0cb23dcd 100644 --- a/org.gecko.emf.ods.tests/src/org/gecko/emf/ods/tests/EMFODSResourceTest.java +++ b/org.gecko.emf.ods.tests/src/org/gecko/emf/ods/tests/EMFODSResourceTest.java @@ -33,9 +33,12 @@ import org.gecko.emf.osgi.example.model.basic.BasicFactory; import org.gecko.emf.osgi.example.model.basic.BusinessPerson; import org.gecko.emf.osgi.example.model.basic.Family; +import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.platform.commons.annotation.Testable; import org.osgi.framework.ServiceReference; import org.osgi.test.common.annotation.InjectService; import org.osgi.test.common.service.ServiceAware; @@ -47,8 +50,10 @@ * * @author Michal H. Siemaszko */ +@Testable @ExtendWith(BundleContextExtension.class) @ExtendWith(ServiceExtension.class) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) @RequireEMFODS public class EMFODSResourceTest { diff --git a/org.gecko.emf.ods.tests/test.bndrun b/org.gecko.emf.ods.tests/test.bndrun index b6ce253f..5d446227 100644 --- a/org.gecko.emf.ods.tests/test.bndrun +++ b/org.gecko.emf.ods.tests/test.bndrun @@ -31,7 +31,6 @@ slf4j.api;version='[1.7.36,1.7.37)',\ com.google.guava;version='[32.1.2,32.1.3)',\ com.google.guava.failureaccess;version='[1.0.1,1.0.2)',\ - com.github.miachm.sods;version='[1.6.2,1.6.3)',\ org.gecko.emf.exporter.ods;version=snapshot,\ org.apache.felix.scr;version='[2.2.6,2.2.7)',\ org.gecko.emf.ods;version=snapshot,\ @@ -47,18 +46,17 @@ 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.ods.tests;version=snapshot,\ - org.apache.commons.logging;version='[1.2.0,1.2.1)',\ - org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ org.osgi.service.component;version='[1.5.1,1.5.2)',\ - org.osgi.util.converter;version='[1.0.9,1.0.10)',\ org.osgi.util.function;version='[1.2.0,1.2.1)',\ org.osgi.util.promise;version='[1.3.0,1.3.1)',\ - slf4j.jcl;version='[1.7.36,1.7.37)',\ 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.api;version='[6.1.1,6.1.2)',\ - org.gecko.emf.osgi.component.config;version='[6.1.1,6.1.2)',\ org.gecko.emf.osgi.component.minimal;version='[6.1.1,6.1.2)',\ org.gecko.emf.osgi.example.model.basic;version='[6.1.0,6.1.1)',\ - org.osgi.service.cm;version='[1.6.1,1.6.2)' + org.osgi.service.cm;version='[1.6.1,1.6.2)',\ + org.apache.commons.commons-compress;version='[1.21.0,1.21.1)',\ + org.apache.servicemix.bundles.poi;version='[5.2.2,5.2.3)',\ + org.gecko.com.github.miachm.sods;version=snapshot,\ + slf4j.simple;version='[1.7.36,1.7.37)',\ + org.osgi.util.converter;version='[1.0.9,1.0.10)' diff --git a/org.gecko.emf.r_lang.tests/src/org/gecko/emf/r_lang/tests/EMFRLangResourceTest.java b/org.gecko.emf.r_lang.tests/src/org/gecko/emf/r_lang/tests/EMFRLangResourceTest.java index 6b1ed9b0..467a6f42 100644 --- a/org.gecko.emf.r_lang.tests/src/org/gecko/emf/r_lang/tests/EMFRLangResourceTest.java +++ b/org.gecko.emf.r_lang.tests/src/org/gecko/emf/r_lang/tests/EMFRLangResourceTest.java @@ -34,9 +34,12 @@ import org.gecko.emf.osgi.example.model.basic.Family; import org.gecko.emf.r_lang.annotation.RequireEMFRLang; import org.gecko.emf.r_lang.configuration.EMFRLangResource; +import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.platform.commons.annotation.Testable; import org.osgi.framework.ServiceReference; import org.osgi.test.common.annotation.InjectService; import org.osgi.test.common.service.ServiceAware; @@ -48,8 +51,10 @@ * * @author Michal H. Siemaszko */ +@Testable @ExtendWith(BundleContextExtension.class) @ExtendWith(ServiceExtension.class) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) @RequireEMFRLang public class EMFRLangResourceTest { diff --git a/org.gecko.emf.r_lang.tests/test.bndrun b/org.gecko.emf.r_lang.tests/test.bndrun index 327b9385..2056ac6e 100644 --- a/org.gecko.emf.r_lang.tests/test.bndrun +++ b/org.gecko.emf.r_lang.tests/test.bndrun @@ -51,18 +51,14 @@ 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.commons.logging;version='[1.2.0,1.2.1)',\ - org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ org.osgi.service.component;version='[1.5.1,1.5.2)',\ - org.osgi.util.converter;version='[1.0.9,1.0.10)',\ org.osgi.util.function;version='[1.2.0,1.2.1)',\ org.osgi.util.promise;version='[1.3.0,1.3.1)',\ - slf4j.jcl;version='[1.7.36,1.7.37)',\ 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.api;version='[6.1.1,6.1.2)',\ - org.gecko.emf.osgi.component.config;version='[6.1.1,6.1.2)',\ org.gecko.emf.osgi.component.minimal;version='[6.1.1,6.1.2)',\ org.gecko.emf.osgi.example.model.basic;version='[6.1.0,6.1.1)',\ - org.osgi.service.cm;version='[1.6.1,1.6.2)' + org.osgi.service.cm;version='[1.6.1,1.6.2)',\ + slf4j.simple;version='[1.7.36,1.7.37)',\ + org.osgi.util.converter;version='[1.0.9,1.0.10)' diff --git a/org.gecko.emf.util.jakartars.bnd.library.workspace/required.bndrun b/org.gecko.emf.util.jakartars.bnd.library.workspace/required.bndrun index 6604cea7..9110f993 100644 --- a/org.gecko.emf.util.jakartars.bnd.library.workspace/required.bndrun +++ b/org.gecko.emf.util.jakartars.bnd.library.workspace/required.bndrun @@ -63,8 +63,19 @@ 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.api;version='[6.1.1,6.1.2)',\ - org.gecko.emf.osgi.component.config;version='[6.1.1,6.1.2)',\ - org.gecko.emf.osgi.component.minimal;version='[6.1.1,6.1.2)',\ org.osgi.service.cm;version='[1.6.1,1.6.2)',\ - de.siegmar.fastcsv;version='[3.0.0,3.0.1)' + de.siegmar.fastcsv;version='[3.0.0,3.0.1)',\ + org.gecko.emf.osgi.component.minimal;version='[6.2.0,6.2.1)' +-runrepos: \ + Workspace,\ + Central,\ + Local,\ + Release,\ + Temp,\ + DIM_Release,\ + DIM Eclipse Runtime Shade,\ + GeckoEMF Dependencies - 6.2.0.SNAPSHOT,\ + GeckoUtil Dependencies,\ + Jacoco Dependencies,\ + OSGi-Test Dependencies,\ + Targetdefinition \ No newline at end of file diff --git a/org.gecko.emf.util.jaxrs.bnd.library.workspace/required.bndrun b/org.gecko.emf.util.jaxrs.bnd.library.workspace/required.bndrun index 5cd553c8..178688d9 100644 --- a/org.gecko.emf.util.jaxrs.bnd.library.workspace/required.bndrun +++ b/org.gecko.emf.util.jaxrs.bnd.library.workspace/required.bndrun @@ -63,11 +63,9 @@ 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.api;version='[6.1.1,6.1.2)',\ - org.gecko.emf.osgi.component.config;version='[6.1.1,6.1.2)',\ - org.gecko.emf.osgi.component.minimal;version='[6.1.1,6.1.2)',\ org.osgi.service.cm;version='[1.6.1,1.6.2)',\ - de.siegmar.fastcsv;version='[3.0.0,3.0.1)' + de.siegmar.fastcsv;version='[3.0.0,3.0.1)',\ + org.gecko.emf.osgi.component.minimal;version='[6.2.0,6.2.1)' -runrepos: \ Workspace,\ Central,\ @@ -75,6 +73,6 @@ Release,\ Temp,\ DIM_Release,\ - GeckoEMF Dependencies,\ Jacoco Dependencies,\ - OSGi-Test Dependencies \ No newline at end of file + OSGi-Test Dependencies,\ + GeckoEMF Dependencies - 6.2.0.SNAPSHOT \ No newline at end of file diff --git a/org.gecko.emf.xlsx.tests/src/org/gecko/emf/xlsx/tests/EMFXLSXResourceTest.java b/org.gecko.emf.xlsx.tests/src/org/gecko/emf/xlsx/tests/EMFXLSXResourceTest.java index ede823f3..9691be09 100644 --- a/org.gecko.emf.xlsx.tests/src/org/gecko/emf/xlsx/tests/EMFXLSXResourceTest.java +++ b/org.gecko.emf.xlsx.tests/src/org/gecko/emf/xlsx/tests/EMFXLSXResourceTest.java @@ -33,9 +33,12 @@ import org.gecko.emf.osgi.example.model.basic.Family; import org.gecko.emf.xlsx.annotation.RequireEMFXLSX; import org.gecko.emf.xlsx.configuration.EMFXLSXResource; +import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.platform.commons.annotation.Testable; import org.osgi.framework.ServiceReference; import org.osgi.test.common.annotation.InjectService; import org.osgi.test.common.service.ServiceAware; @@ -47,8 +50,10 @@ * * @author Michal H. Siemaszko */ +@Testable @ExtendWith(BundleContextExtension.class) @ExtendWith(ServiceExtension.class) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) @RequireEMFXLSX public class EMFXLSXResourceTest { diff --git a/org.gecko.emf.xlsx.tests/test.bndrun b/org.gecko.emf.xlsx.tests/test.bndrun index fdbc4a9d..8c65bd60 100644 --- a/org.gecko.emf.xlsx.tests/test.bndrun +++ b/org.gecko.emf.xlsx.tests/test.bndrun @@ -51,19 +51,14 @@ 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.xlsx.tests;version=snapshot,\ - com.github.miachm.sods;version='[1.6.2,1.6.3)',\ - org.apache.commons.logging;version='[1.2.0,1.2.1)',\ - org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ org.osgi.service.component;version='[1.5.1,1.5.2)',\ - org.osgi.util.converter;version='[1.0.9,1.0.10)',\ org.osgi.util.function;version='[1.2.0,1.2.1)',\ org.osgi.util.promise;version='[1.3.0,1.3.1)',\ - slf4j.jcl;version='[1.7.36,1.7.37)',\ 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.api;version='[6.1.1,6.1.2)',\ - org.gecko.emf.osgi.component.config;version='[6.1.1,6.1.2)',\ org.gecko.emf.osgi.component.minimal;version='[6.1.1,6.1.2)',\ org.gecko.emf.osgi.example.model.basic;version='[6.1.0,6.1.1)',\ - org.osgi.service.cm;version='[1.6.1,1.6.2)' \ No newline at end of file + org.osgi.service.cm;version='[1.6.1,1.6.2)',\ + slf4j.simple;version='[1.7.36,1.7.37)',\ + org.osgi.util.converter;version='[1.0.9,1.0.10)' \ No newline at end of file