From 987f6d41cf470c18d33fc480e0e9b6a0ef8afdaa Mon Sep 17 00:00:00 2001
From: Kai Brassel <mail@khbrassel.de>
Date: Tue, 5 Apr 2022 17:01:53 +0200
Subject: [PATCH] Provide new (primitive) Ecore data type for time of day in
 ISO format

---
 .gitlab-ci.yml                                |  4 +--
 README.md                                     |  5 +--
 .../model/Quantities.ecore                    |  1 +
 .../model/Quantities.genmodel                 |  1 +
 .../model/quantities/QuantitiesPackage.java   | 31 ++++++++++++++++++
 .../impl/QuantitiesFactoryImpl.java           | 32 +++++++++++++++++++
 .../impl/QuantitiesPackageImpl.java           | 20 ++++++++++++
 .../META-INF/MANIFEST.MF                      |  3 +-
 .../cityunits/tests/DayOfTimeTest.java        | 25 +++++++++++++++
 9 files changed, 117 insertions(+), 5 deletions(-)
 create mode 100644 de.hftstuttgart.cityunits.tests/src/de/hftstuttgart/cityunits/tests/DayOfTimeTest.java

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 64c481a..2be7657 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,11 +1,11 @@
 variables:
-  RELEASE_DIR: "public/release_target_110"
+  RELEASE_DIR: "public/p2repo"
 
 pages:
   stage: deploy
   tags: 
     - docker # use shared runner
-  image: maven:3.8.2-adoptopenjdk-16
+  image: maven:3.8.4-eclipse-temurin-17-alpine
   script:
     - mvn --version
     - mvn clean install   # build p2 repo
diff --git a/README.md b/README.md
index b1d8f58..3da6b75 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,10 @@
 # de.hftstuttgart.cityunits
 
-Create Eclipse P2 repository with Ecore data types `QuantityDouble` and `QuantityLong` for units based on Indriya reference implementation of Units of Measurement Java specification (JSR 385) and some special units for urban simulation.
+Create Eclipse P2 repository with Ecore data type `Quantity` for units based on Indriya reference implementation of Units of Measurement Java specification (JSR 385) and some special units for urban simulation.
 
-To add OSGi bundles published in this P2 repository add site [https://transfer.hft-stuttgart.de/pages/neqmodplus/de.hft-stuttgart.cityunits/release_target_102/]() to a running Eclipse instance via `Eclipse -> Preferences -> Install/Update -> Available Software Sites -> Add...` or to a target platform definition via `Eclipse -> Preferences -> Plug-in Development -> Target Platform -> Edit...`.
+Also adds another Ecore data type `TimeOfDay` useful to model schedules and the like.
 
+To install this feature in an Eclipse application add site [https://transfer.hft-stuttgart.de/pages/neqmodplus/de.hft-stuttgart.cityunits/p2repo]() via `Eclipse -> Help -> Install New Software...` and select _City Units_ (If nothing can be selected, ensure that _Group items by category_ is ticked.)
 
 For an introduction on dealing with units in Java, see
 [Baeldung: Introduction to javax.measure](https://www.baeldung.com/javax-measure).
diff --git a/de.hftstuttgart.cityunits.model/model/Quantities.ecore b/de.hftstuttgart.cityunits.model/model/Quantities.ecore
index 254886a..bb15245 100644
--- a/de.hftstuttgart.cityunits.model/model/Quantities.ecore
+++ b/de.hftstuttgart.cityunits.model/model/Quantities.ecore
@@ -2,4 +2,5 @@
 <ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="quantities" nsURI="https://www.hftstuttgart.de/quantities" nsPrefix="quant">
   <eClassifiers xsi:type="ecore:EDataType" name="Quantity" instanceClassName="de.hftstuttgart.cityunits.model.NullableQuantity"/>
+  <eClassifiers xsi:type="ecore:EDataType" name="LocalTime" instanceClassName="java.time.LocalTime"/>
 </ecore:EPackage>
diff --git a/de.hftstuttgart.cityunits.model/model/Quantities.genmodel b/de.hftstuttgart.cityunits.model/model/Quantities.genmodel
index 765791c..478fbdc 100644
--- a/de.hftstuttgart.cityunits.model/model/Quantities.genmodel
+++ b/de.hftstuttgart.cityunits.model/model/Quantities.genmodel
@@ -8,5 +8,6 @@
   <genPackages prefix="Quantities" basePackage="de.hftstuttgart.cityunits.model" disposableProviderFactory="true"
       ecorePackage="Quantities.ecore#/">
     <genDataTypes ecoreDataType="Quantities.ecore#//Quantity" create="return de.hftstuttgart.cityunits.model.NullableQuantity.create(it);"/>
+    <genDataTypes ecoreDataType="Quantities.ecore#//LocalTime" create="return java.time.LocalTime.parse(it);"/>
   </genPackages>
 </genmodel:GenModel>
diff --git a/de.hftstuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/QuantitiesPackage.java b/de.hftstuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/QuantitiesPackage.java
index 73bea74..64c9bbe 100644
--- a/de.hftstuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/QuantitiesPackage.java
+++ b/de.hftstuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/QuantitiesPackage.java
@@ -65,6 +65,17 @@ public interface QuantitiesPackage extends EPackage {
 	int QUANTITY = 0;
 
 
+	/**
+	 * The meta object id for the '<em>Local Time</em>' data type.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see java.time.LocalTime
+	 * @see de.hftstuttgart.cityunits.model.quantities.impl.QuantitiesPackageImpl#getLocalTime()
+	 * @generated
+	 */
+	int LOCAL_TIME = 1;
+
+
 	/**
 	 * Returns the meta object for data type '{@link de.hftstuttgart.cityunits.model.NullableQuantity <em>Quantity</em>}'.
 	 * <!-- begin-user-doc -->
@@ -76,6 +87,17 @@ public interface QuantitiesPackage extends EPackage {
 	 */
 	EDataType getQuantity();
 
+	/**
+	 * Returns the meta object for data type '{@link java.time.LocalTime <em>Local Time</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for data type '<em>Local Time</em>'.
+	 * @see java.time.LocalTime
+	 * @model instanceClass="java.time.LocalTime"
+	 * @generated
+	 */
+	EDataType getLocalTime();
+
 	/**
 	 * Returns the factory that creates the instances of the model.
 	 * <!-- begin-user-doc -->
@@ -108,6 +130,15 @@ public interface QuantitiesPackage extends EPackage {
 		 * @generated
 		 */
 		EDataType QUANTITY = eINSTANCE.getQuantity();
+		/**
+		 * The meta object literal for the '<em>Local Time</em>' data type.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @see java.time.LocalTime
+		 * @see de.hftstuttgart.cityunits.model.quantities.impl.QuantitiesPackageImpl#getLocalTime()
+		 * @generated
+		 */
+		EDataType LOCAL_TIME = eINSTANCE.getLocalTime();
 
 	}
 
diff --git a/de.hftstuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/impl/QuantitiesFactoryImpl.java b/de.hftstuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/impl/QuantitiesFactoryImpl.java
index 61b1404..5addccc 100644
--- a/de.hftstuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/impl/QuantitiesFactoryImpl.java
+++ b/de.hftstuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/impl/QuantitiesFactoryImpl.java
@@ -5,6 +5,7 @@ package de.hftstuttgart.cityunits.model.quantities.impl;
 import de.hftstuttgart.cityunits.model.NullableQuantity;
 import de.hftstuttgart.cityunits.model.quantities.*;
 
+import java.time.LocalTime;
 import org.eclipse.emf.ecore.EClass;
 import org.eclipse.emf.ecore.EDataType;
 import org.eclipse.emf.ecore.EObject;
@@ -73,6 +74,8 @@ public class QuantitiesFactoryImpl extends EFactoryImpl implements QuantitiesFac
 		switch (eDataType.getClassifierID()) {
 			case QuantitiesPackage.QUANTITY:
 				return createQuantityFromString(eDataType, initialValue);
+			case QuantitiesPackage.LOCAL_TIME:
+				return createLocalTimeFromString(eDataType, initialValue);
 			default:
 				throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier");
 		}
@@ -88,6 +91,8 @@ public class QuantitiesFactoryImpl extends EFactoryImpl implements QuantitiesFac
 		switch (eDataType.getClassifierID()) {
 			case QuantitiesPackage.QUANTITY:
 				return convertQuantityToString(eDataType, instanceValue);
+			case QuantitiesPackage.LOCAL_TIME:
+				return convertLocalTimeToString(eDataType, instanceValue);
 			default:
 				throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier");
 		}
@@ -120,6 +125,33 @@ public class QuantitiesFactoryImpl extends EFactoryImpl implements QuantitiesFac
 		return super.convertToString(eDataType, instanceValue);
 	}
 
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public LocalTime createLocalTime(final String it) {
+		return java.time.LocalTime.parse(it);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public LocalTime createLocalTimeFromString(EDataType eDataType, String initialValue) {
+		return createLocalTime(initialValue);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public String convertLocalTimeToString(EDataType eDataType, Object instanceValue) {
+		return super.convertToString(eDataType, instanceValue);
+	}
+
 	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
diff --git a/de.hftstuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/impl/QuantitiesPackageImpl.java b/de.hftstuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/impl/QuantitiesPackageImpl.java
index 4fa3ed1..02a6158 100644
--- a/de.hftstuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/impl/QuantitiesPackageImpl.java
+++ b/de.hftstuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/impl/QuantitiesPackageImpl.java
@@ -5,6 +5,7 @@ package de.hftstuttgart.cityunits.model.quantities.impl;
 import de.hftstuttgart.cityunits.model.NullableQuantity;
 import de.hftstuttgart.cityunits.model.quantities.QuantitiesFactory;
 import de.hftstuttgart.cityunits.model.quantities.QuantitiesPackage;
+import java.time.LocalTime;
 import org.eclipse.emf.ecore.EDataType;
 import org.eclipse.emf.ecore.EPackage;
 import org.eclipse.emf.ecore.impl.EPackageImpl;
@@ -23,6 +24,13 @@ public class QuantitiesPackageImpl extends EPackageImpl implements QuantitiesPac
 	 */
 	private EDataType quantityEDataType = null;
 
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private EDataType localTimeEDataType = null;
+
 	/**
 	 * Creates an instance of the model <b>Package</b>, registered with
 	 * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package
@@ -94,6 +102,16 @@ public class QuantitiesPackageImpl extends EPackageImpl implements QuantitiesPac
 		return quantityEDataType;
 	}
 
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public EDataType getLocalTime() {
+		return localTimeEDataType;
+	}
+
 	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -124,6 +142,7 @@ public class QuantitiesPackageImpl extends EPackageImpl implements QuantitiesPac
 
 		// Create data types
 		quantityEDataType = createEDataType(QUANTITY);
+		localTimeEDataType = createEDataType(LOCAL_TIME);
 	}
 
 	/**
@@ -151,6 +170,7 @@ public class QuantitiesPackageImpl extends EPackageImpl implements QuantitiesPac
 
 		// Initialize data types
 		initEDataType(quantityEDataType, NullableQuantity.class, "Quantity", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS);
+		initEDataType(localTimeEDataType, LocalTime.class, "LocalTime", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS);
 
 		// Create resource
 		createResource(eNS_URI);
diff --git a/de.hftstuttgart.cityunits.tests/META-INF/MANIFEST.MF b/de.hftstuttgart.cityunits.tests/META-INF/MANIFEST.MF
index 658b625..4b19220 100644
--- a/de.hftstuttgart.cityunits.tests/META-INF/MANIFEST.MF
+++ b/de.hftstuttgart.cityunits.tests/META-INF/MANIFEST.MF
@@ -10,4 +10,5 @@ Import-Package: de.hftstuttgart.cityunits.model,
 Require-Bundle: javax.measure.unit-api,
  tech.units.indriya,
  uom-lib-common;bundle-version="[2.1.0,3.0.0)",
- org.eclipse.emf.ecore
+ org.eclipse.emf.ecore,
+ org.junit.jupiter.api
diff --git a/de.hftstuttgart.cityunits.tests/src/de/hftstuttgart/cityunits/tests/DayOfTimeTest.java b/de.hftstuttgart.cityunits.tests/src/de/hftstuttgart/cityunits/tests/DayOfTimeTest.java
new file mode 100644
index 0000000..9be33a2
--- /dev/null
+++ b/de.hftstuttgart.cityunits.tests/src/de/hftstuttgart/cityunits/tests/DayOfTimeTest.java
@@ -0,0 +1,25 @@
+package de.hftstuttgart.cityunits.tests;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.time.LocalTime;
+import java.time.format.DateTimeParseException;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+
+class DayOfTimeTest {
+
+	@Test
+	void testCreationFromString() {
+		var time = LocalTime.parse("12:34:11");
+		assertEquals("12:34:11", time.toString(), "LocalTime conversion to and from ISO format not working!");
+	}
+
+	@Test
+	void testWrongString() {
+		Assertions.assertThrowsExactly(DateTimeParseException.class, () -> LocalTime.parse("12:34:60"),
+				"DateTimeParseException was expected!");
+	}
+}
-- 
GitLab