diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..f795e3d53aad4c5f64b49b54c912ac828973670b --- /dev/null +++ b/.gitignore @@ -0,0 +1,274 @@ + +# Created by https://www.gitignore.io/api/java,maven,macos,linux,eclipse,windows,netbeans,intellij +# Edit at https://www.gitignore.io/?templates=java,maven,macos,linux,eclipse,windows,netbeans,intellij + + +### User specific ### +.sonarlint/ +Servers/ +RemoteSystemsTempFiles/ +farFieldObstructions.txt +farFieldOcclPatchFraction.txt +/tmpdeploy/ +/SimStadtTestReports/ + +### Eclipse ### + +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Annotation Processing +.apt_generated/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +### Eclipse Patch ### + +# Annotation Processing +.apt_generated + +.sts4-cache/ + +### Intellij ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### Intellij Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +.idea/sonarlint + +### Java ### +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Maven ### +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar + +### NetBeans ### +**/nbproject/private/ +**/nbproject/Makefile-*.mk +**/nbproject/Package-*.bash +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.gitignore.io/api/java,maven,macos,linux,eclipse,windows,netbeans,intellij \ No newline at end of file diff --git a/.project b/.project new file mode 100644 index 0000000000000000000000000000000000000000..9dd72dd39bb7adb15eeb3c14677c7e8c6f4cc2e2 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>de.hft-stuttgart.cityunits.parent</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.m2e.core.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.m2e.core.maven2Nature</nature> + </natures> +</projectDescription> diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..9331e4f822390abb153462ae682fad8313db5b11 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,4 @@ +FROM maven:3.6.3-adoptopenjdk-15 +WORKDIR /home/projects +COPY ./ ./ +RUN mvn clean install diff --git a/README.md b/README.md index ecd5a377663a0848ef183b3390a855d4121d9b99..d505d252f34b27ccf82db6222e91f508f1000885 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ # de.hft-stuttgart.cityunits -Ecore types for modeling quantities with units of mesurement (JSR-385) and Indriya reference implementation. -Add also units especially useful for urban simulation. - +Create Eclipse P2 repository with Ecore data types for units based on Indriya reference implementation. Provide special units for urban simulation. \ No newline at end of file diff --git a/de.hft-stuttgart.cityunits.feature/.project b/de.hft-stuttgart.cityunits.feature/.project new file mode 100644 index 0000000000000000000000000000000000000000..1b6e2eab5586623fb8c2aaaa749a3ac8f31a567b --- /dev/null +++ b/de.hft-stuttgart.cityunits.feature/.project @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>de.hft-stuttgart.cityunits.feature</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.pde.FeatureBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.m2e.core.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.m2e.core.maven2Nature</nature> + <nature>org.eclipse.pde.FeatureNature</nature> + </natures> +</projectDescription> diff --git a/de.hft-stuttgart.cityunits.feature/build.properties b/de.hft-stuttgart.cityunits.feature/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..64f93a9f0b7328eb563aa5ad6cec7f828020e124 --- /dev/null +++ b/de.hft-stuttgart.cityunits.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/de.hft-stuttgart.cityunits.feature/feature.xml b/de.hft-stuttgart.cityunits.feature/feature.xml new file mode 100644 index 0000000000000000000000000000000000000000..cd5481b076ca6d7dc867b9f4a40a7cd020a1d65c --- /dev/null +++ b/de.hft-stuttgart.cityunits.feature/feature.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<feature + id="de.hft-stuttgart.cityunits.feature" + label="City Units" + version="1.0.0" + provider-name="HfT Stuttgart"> + + <description url="http://www.example.com/description"> + Provides Indriya reference implementation of units of masurement +(JSR 385) together with required dependencies and extensions +that introduces Ecore data types for double and long valued units. + +Certain units relevant to City simulations are also added. + </description> + + <copyright url="http://www.example.com/copyright"> + [Enter Copyright Description here.] + </copyright> + + <license url="http://www.example.com/license"> + [Enter License Description here.] + </license> + + <requires> + <import plugin="org.eclipse.emf.ecore"/> + <import plugin="de.hft-stuttgart.cityunits" version="1.0.0" match="greaterOrEqual"/> + <import plugin="org.eclipse.emf.edit" version="2.8.0" match="compatible"/> + <import plugin="org.eclipse.core.runtime" version="3.8.0" match="compatible"/> + <import plugin="org.eclipse.emf.databinding" version="1.3.0" match="compatible"/> + <import plugin="org.eclipse.jface"/> + <import plugin="javax.inject"/> + <import plugin="org.eclipse.emfforms.common"/> + <import plugin="org.eclipse.swt"/> + <import plugin="tech.units.indriya" version="2.1.1" match="compatible"/> + <import plugin="javax.measure.unit-api" version="2.1.1" match="compatible"/> + <import plugin="uom-lib-common" version="2.1.0" match="compatible"/> + <import plugin="org.eclipse.emf.ecp.edit.swt" version="1.24.0" match="compatible"/> + <import plugin="org.eclipse.emf.ecp.ui.view.swt" version="1.24.0" match="compatible"/> + <import plugin="org.eclipse.emf.ecp.view.core.swt" version="1.24.0" match="compatible"/> + <import plugin="org.eclipse.emf.ecp.view.template.model" version="1.24.0" match="compatible"/> + <import plugin="org.eclipse.emfforms.core.services.editsupport" version="1.24.0" match="compatible"/> + <import plugin="org.eclipse.emfforms.swt.core.di" version="1.24.0" match="compatible"/> + <import plugin="org.eclipse.emfforms.localization" version="1.24.0" match="compatible"/> + </requires> + + <plugin + id="de.hft-stuttgart.cityunits.model" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="de.hft-stuttgart.cityunits.ui.renderer" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + +</feature> diff --git a/de.hft-stuttgart.cityunits.feature/pom.xml b/de.hft-stuttgart.cityunits.feature/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..ac95a351fa47afef7487738d660f83d1ea5c9ee1 --- /dev/null +++ b/de.hft-stuttgart.cityunits.feature/pom.xml @@ -0,0 +1,15 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>de.hft-stuttgart.cityunits.feature</artifactId> + <packaging>eclipse-feature</packaging> + <name>City Units Feature</name> + + <parent> + <groupId>de.hft-stuttgart</groupId> + <artifactId>de.hft-stuttgart.cityunits</artifactId> + <version>1.0.0</version> + </parent> + +</project> \ No newline at end of file diff --git a/de.hft-stuttgart.cityunits.model/.classpath b/de.hft-stuttgart.cityunits.model/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..1f0469022c306ea5fefe4b29b6d0eee95d3db009 --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src/"/> + <classpathentry kind="output" path="target/classes"/> +</classpath> diff --git a/de.hft-stuttgart.cityunits.model/.project b/de.hft-stuttgart.cityunits.model/.project new file mode 100644 index 0000000000000000000000000000000000000000..6a9fbf86a4a6921fd3b0599d85229a793e3b66f0 --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/.project @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>de.hft-stuttgart.cityunits.model</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.m2e.core.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.m2e.core.maven2Nature</nature> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/de.hft-stuttgart.cityunits.model/META-INF/MANIFEST.MF b/de.hft-stuttgart.cityunits.model/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..6c4972e4fe33462ac9acb13a5cbc47b76ac1811f --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/META-INF/MANIFEST.MF @@ -0,0 +1,16 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: CityUnits +Bundle-SymbolicName: de.hft-stuttgart.cityunits.model;singleton:=true +Bundle-Version: 1.0.0 +Bundle-ClassPath: . +Bundle-Vendor: HfT Stuttgart +Bundle-Localization: plugin +Automatic-Module-Name: de.hft-stuttgart.cityunits.model +Require-Bundle: tech.units.indriya;bundle-version="[2.1.1,3.0.0)", + javax.measure.unit-api;bundle-version="[2.1.1,3.0.0)", + org.eclipse.emf.ecore;visibility:=reexport, + uom-lib-common;bundle-version="[2.1.0,3.0.0)" +Bundle-ActivationPolicy: lazy +Export-Package: de.hftstuttgart.cityunits.model;uses:="javax.measure,javax.measure.spi,tech.units.indriya", + de.hftstuttgart.cityunits.model.quantities;uses:="org.eclipse.emf.ecore" diff --git a/de.hft-stuttgart.cityunits.model/build.properties b/de.hft-stuttgart.cityunits.model/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..14543a7f6ccfc14d8248cf21d592be3b5d20636d --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/build.properties @@ -0,0 +1,10 @@ +# + +bin.includes = .,\ + model/,\ + META-INF/,\ + plugin.xml,\ + plugin.properties +jars.compile.order = . +source.. = src/ +bin.excludes = model/Quantities.genmodel diff --git a/de.hft-stuttgart.cityunits.model/model/Quantities.ecore b/de.hft-stuttgart.cityunits.model/model/Quantities.ecore new file mode 100644 index 0000000000000000000000000000000000000000..578b48ccb6110a5708eb7829c1aa99e5edd842ac --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/model/Quantities.ecore @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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.hft-stuttgart.de/quantities" + nsPrefix="quant"> + <eClassifiers xsi:type="ecore:EDataType" name="QuantityDouble" instanceClassName="de.hftstuttgart.cityunits.NullableQuantity"/> + <eClassifiers xsi:type="ecore:EDataType" name="QuantityLong" instanceClassName="de.hftstuttgart.cityunits.NullableQuantity"/> +</ecore:EPackage> diff --git a/de.hft-stuttgart.cityunits.model/model/Quantities.genmodel b/de.hft-stuttgart.cityunits.model/model/Quantities.genmodel new file mode 100644 index 0000000000000000000000000000000000000000..4a9abe2003a3219bb4cd3a07c582d1ced2c87f45 --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/model/Quantities.genmodel @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<genmodel:GenModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" + modelDirectory="/de.hft-stuttgart.cityunits/src" modelPluginID="de.hft-stuttgart.cityunits" + modelName="Quantities" rootExtendsClass="org.eclipse.emf.ecore.impl.MinimalEObjectImpl$Container" + importerID="org.eclipse.emf.importer.ecore" complianceLevel="5.0" copyrightFields="false" + operationReflection="true" importOrganizing="true"> + <foreignModel>Quantities.ecore</foreignModel> + <genPackages prefix="Quantities" basePackage="de.hftstuttgart.cityunits" disposableProviderFactory="true" + ecorePackage="Quantities.ecore#/"> + <genDataTypes ecoreDataType="Quantities.ecore#//QuantityDouble"/> + <genDataTypes ecoreDataType="Quantities.ecore#//QuantityLong"/> + </genPackages> +</genmodel:GenModel> diff --git a/de.hft-stuttgart.cityunits.model/plugin.properties b/de.hft-stuttgart.cityunits.model/plugin.properties new file mode 100644 index 0000000000000000000000000000000000000000..c0785d5f8ed1276541f0426b35f873905ab62593 --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/plugin.properties @@ -0,0 +1,4 @@ +# + +pluginName = City Units +providerName = HfT Stuttgart diff --git a/de.hft-stuttgart.cityunits.model/plugin.xml b/de.hft-stuttgart.cityunits.model/plugin.xml new file mode 100644 index 0000000000000000000000000000000000000000..c2c179f72678bf06e510ca4c9412214aba868a4f --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/plugin.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.0"?> + +<!-- +--> + +<plugin> + + <extension point="org.eclipse.emf.ecore.generated_package"> + <!-- @generated Quantities --> + <package + uri="https://www.hft-stuttgart.de/quantities" + class="de.hftstuttgart.cityunits.quantities.QuantitiesPackage" + genModel="model/Quantities.genmodel"/> + </extension> + +</plugin> diff --git a/de.hft-stuttgart.cityunits.model/pom.xml b/de.hft-stuttgart.cityunits.model/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..2b0adeea26f23efbdd9b87540818c98dec106c5c --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/pom.xml @@ -0,0 +1,15 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>de.hft-stuttgart.cityunits.model</artifactId> + <packaging>eclipse-plugin</packaging> + <name>City Units</name> + + <parent> + <groupId>de.hft-stuttgart</groupId> + <artifactId>de.hft-stuttgart.cityunits</artifactId> + <version>1.0.0</version> + </parent> + +</project> \ No newline at end of file diff --git a/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/Dollar.java b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/Dollar.java new file mode 100644 index 0000000000000000000000000000000000000000..d735681f3eca425de49a6d2ca6be44da518a0593 --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/Dollar.java @@ -0,0 +1,11 @@ +package de.hftstuttgart.cityunits.model; + +import javax.measure.Quantity; + + +/** + * This interface represents the intensity dimension. + */ +public interface Dollar extends Quantity<Dollar> +{ +} \ No newline at end of file diff --git a/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/Euro.java b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/Euro.java new file mode 100644 index 0000000000000000000000000000000000000000..b542188b04a7a4bc3e5ec90ea427f7974e481d37 --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/Euro.java @@ -0,0 +1,11 @@ +package de.hftstuttgart.cityunits.model; + +import javax.measure.Quantity; + + +/** + * This interface represents the intensity dimension. + */ +public interface Euro extends Quantity<Euro> +{ +} \ No newline at end of file diff --git a/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/Intensity.java b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/Intensity.java new file mode 100644 index 0000000000000000000000000000000000000000..699bfaf1ff2f2d9b8629da93faa99bd5ab53f7af --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/Intensity.java @@ -0,0 +1,11 @@ +package de.hftstuttgart.cityunits.model; + +import javax.measure.Quantity; + + +/** + * This interface represents the intensity dimension. + */ +public interface Intensity extends Quantity<Intensity> +{ +} \ No newline at end of file diff --git a/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/NullableQuantity.java b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/NullableQuantity.java new file mode 100644 index 0000000000000000000000000000000000000000..ae05702f88dcd2d291cdcf13711f4545499cebd1 --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/NullableQuantity.java @@ -0,0 +1,106 @@ +package de.hftstuttgart.cityunits.model; + +import java.text.NumberFormat; +import java.text.ParseException; +import java.util.Locale; +import java.util.Optional; + +import javax.measure.Quantity; +import javax.measure.Unit; + +import tech.units.indriya.format.SimpleQuantityFormat; +import tech.units.indriya.quantity.Quantities; + +/** + * A <code>NullableQuantity</code> wraps a <code>javax.measure.Quantity</code> having + * a numerical value that is either a <code>Double</code>, a <code>Long</code>, + * or <code>null</code>. The latter case represents an unknown numerical + * value of a specific unit. On the other hand, the <code>javax.measure.Unit</code> + * of the quantity is always defined. + */ +public class NullableQuantity { + + static { + // TODO Implement specific QuantityFormat to enable custom number format? + // ensure that editing, (de)serialization and default values of units all work + // with the same number format (Decimal point etc.) + Locale.setDefault(Locale.ENGLISH); + + // specific additional units for urban simulation like TON (t), PARTS_PER_MILLION (ppm), DECIBEL (dB) + UrbanSimulationUnits.getInstance(); + } + + public static NullableQuantity create(String str) { + NullableQuantity newNullableQuantity = null; + try { + NumberFormat.getInstance().parse(str); + newNullableQuantity = new NullableQuantity(str); + } catch (final ParseException ex) { // no number value present: create NullQuantity just with unit + try { + NullableQuantity dummy = new NullableQuantity("1 " + str); //$NON-NLS-1$ + newNullableQuantity = new NullQuantity(dummy.getUnit()); + } catch (final IllegalArgumentException ex1) { // Unit could not be parsed + System.out.println("Unit '" + str + "' could not be parsed!"); //TODO + ex.printStackTrace(); + } + } catch (final IllegalArgumentException ex) { // Quantity could not be parsed + System.out.println("Quantity '" + str + "' could not be parsed!"); //TODO + ex.printStackTrace(); + } + return newNullableQuantity; + } + + public static NullableQuantity create(Number number, Unit<?> unit) { + return number == null ? new NullQuantity(unit) : new NullableQuantity(number, unit); + } + + private final Quantity<?> quantity; + + private NullableQuantity(String str) { + quantity = Quantities.getQuantity(str); + } + + private NullableQuantity(Number number, Unit<?> unit) { + quantity = Quantities.getQuantity(number, unit); + } + + /** + * In case of an unknown numerical value of the quantity an empty <code>Optional</code> is returned via subclass. + * @return the wrapped <code>javax.measure.Quantity</code> if its numerical value is present + */ + public Optional<Quantity<?>> getQuantity() { + return Optional.of(quantity); + } + + /** + * @return numerical value of the wrapped <code>javax.measure.Quantity</code> if present + */ + public Optional<Number> getNumber() { + return getQuantity().map(Quantity::getValue); + } + + public Unit<?> getUnit() { + return quantity.getUnit(); + } + + @Override + public String toString() { + return SimpleQuantityFormat.getInstance().format(quantity); + } + + + private static class NullQuantity extends NullableQuantity { + public NullQuantity(Unit<?> unit) { + super(1, unit); + } + + public Optional<Quantity<?>> getQuantity() { + return Optional.empty(); + } + + @Override + public String toString() { + return "<unknown> " + getUnit().toString(); + } + } +} diff --git a/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/UrbanSimulationUnits.java b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/UrbanSimulationUnits.java new file mode 100644 index 0000000000000000000000000000000000000000..a23ca509ba516a0a66d5dc174486c828d5ab4c0b --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/UrbanSimulationUnits.java @@ -0,0 +1,88 @@ +package de.hftstuttgart.cityunits.model; + +import java.math.BigInteger; + +import javax.measure.Dimension; +import javax.measure.Quantity; +import javax.measure.Unit; +import javax.measure.quantity.Dimensionless; +import javax.measure.quantity.Mass; +import javax.measure.spi.SystemOfUnits; + +import tech.units.indriya.AbstractSystemOfUnits; +import tech.units.indriya.AbstractUnit; +import tech.units.indriya.format.SimpleUnitFormat; +import tech.units.indriya.function.LogConverter; +import tech.units.indriya.function.MultiplyConverter; +import tech.units.indriya.unit.AlternateUnit; +import tech.units.indriya.unit.BaseUnit; +import tech.units.indriya.unit.TransformedUnit; +import tech.units.indriya.unit.UnitDimension; +import tech.units.indriya.unit.Units; + +public class UrbanSimulationUnits extends AbstractSystemOfUnits +{ + private static final UrbanSimulationUnits INSTANCE = new UrbanSimulationUnits(); + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + public static final Unit<Dimensionless> PARTS_PER_MILLION = addUnit(new TransformedUnit<>(AbstractUnit.ONE, + MultiplyConverter.ofRational(BigInteger.ONE, BigInteger.valueOf(1000000)))); + public static final Unit<Dimensionless> DECIBEL = addUnit(AbstractUnit.ONE.transform( + new LogConverter(10).inverse().concatenate(MultiplyConverter.ofRational(BigInteger.ONE, BigInteger.TEN)))); + public static final Unit<Mass> TON = addUnit(Units.KILOGRAM.multiply(1000)); + + public static final Unit<Intensity> IRRADIANCE = addUnit( + new AlternateUnit<Intensity>(Units.WATT.divide(Units.SQUARE_METRE), "W/m2")); + + // To model costs I added monetary units quick and dirty as SI base units. According to JavaDoc of AbstractUnit, + // monetary units should rather be implemented in an extra type hierarchy below ComparableUnit. + public final static Dimension MONEY_DIMENSION = UnitDimension.parse('M'); + public final static Unit<Euro> EURO = new BaseUnit<Euro>("€", MONEY_DIMENSION); + public final static Unit<Dollar> DOLLAR = new BaseUnit<Dollar>("$", MONEY_DIMENSION); + + static { + SimpleUnitFormat.getInstance().label(TON, "t"); + SimpleUnitFormat.getInstance().label(DECIBEL, "dB"); + SimpleUnitFormat.getInstance().label(PARTS_PER_MILLION, "ppm"); + SimpleUnitFormat.getInstance().label(EURO, "€"); + SimpleUnitFormat.getInstance().label(DOLLAR, "$"); + } + + + /** + * Returns the unique instance of this class. + * + * @return the Units instance. + */ + public static SystemOfUnits getInstance() { + return INSTANCE; + } + + /** + * Adds a new unit not mapped to any specified quantity type. + * + * @param unit the unit being added. + * @return <code>unit</code>. + */ + private static <U extends Unit<?>> U addUnit(U unit) { + INSTANCE.units.add(unit); + return unit; + } + + /** + * Adds a new unit and maps it to the specified quantity type. + * + * @param unit the unit being added. + * @param type the quantity type. + * @return <code>unit</code>. + */ + private static <U extends AbstractUnit<?>> U addUnit(U unit, Class<? extends Quantity<?>> type) { + INSTANCE.units.add(unit); + INSTANCE.quantityToUnit.put(type, unit); + return unit; + } +} diff --git a/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/VolumetricFlowRate.java b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/VolumetricFlowRate.java new file mode 100644 index 0000000000000000000000000000000000000000..003cb6624b6b6537d30240f71d736a3fdce27998 --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/VolumetricFlowRate.java @@ -0,0 +1,11 @@ +package de.hftstuttgart.cityunits.model; + +import javax.measure.Quantity; + + +/** + * Define Volumetric Flow Rate type (basic unit is m^3/s). + */ +public interface VolumetricFlowRate extends Quantity<VolumetricFlowRate> +{ +} \ No newline at end of file diff --git a/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/QuantitiesFactory.java b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/QuantitiesFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..2ad6c3170db8d965496b376a2ad395990a6746b3 --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/QuantitiesFactory.java @@ -0,0 +1,33 @@ +/** + */ +package de.hftstuttgart.cityunits.model.quantities; + +import org.eclipse.emf.ecore.EFactory; + +/** + * <!-- begin-user-doc --> + * The <b>Factory</b> for the model. + * It provides a create method for each non-abstract class of the model. + * <!-- end-user-doc --> + * @see de.hftstuttgart.cityunits.model.quantities.QuantitiesPackage + * @generated + */ +public interface QuantitiesFactory extends EFactory { + /** + * The singleton instance of the factory. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + QuantitiesFactory eINSTANCE = de.hftstuttgart.cityunits.model.quantities.impl.QuantitiesFactoryImpl.init(); + + /** + * Returns the package supported by this factory. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the package supported by this factory. + * @generated + */ + QuantitiesPackage getQuantitiesPackage(); + +} //QuantitiesFactory diff --git a/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/QuantitiesPackage.java b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/QuantitiesPackage.java new file mode 100644 index 0000000000000000000000000000000000000000..caa925b7dce5ac26bddbab5dc863bd7c92138780 --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/QuantitiesPackage.java @@ -0,0 +1,145 @@ +/** + */ +package de.hftstuttgart.cityunits.model.quantities; + +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EPackage; + +/** + * <!-- begin-user-doc --> + * The <b>Package</b> for the model. + * It contains accessors for the meta objects to represent + * <ul> + * <li>each class,</li> + * <li>each feature of each class,</li> + * <li>each operation of each class,</li> + * <li>each enum,</li> + * <li>and each data type</li> + * </ul> + * <!-- end-user-doc --> + * @see de.hftstuttgart.cityunits.model.quantities.QuantitiesFactory + * @model kind="package" + * @generated + */ +public interface QuantitiesPackage extends EPackage { + /** + * The package name. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + String eNAME = "quantities"; + + /** + * The package namespace URI. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + String eNS_URI = "https://www.hft-stuttgart.de/quantities"; + + /** + * The package namespace name. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + String eNS_PREFIX = "quant"; + + /** + * The singleton instance of the package. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + QuantitiesPackage eINSTANCE = de.hftstuttgart.cityunits.model.quantities.impl.QuantitiesPackageImpl.init(); + + /** + * The meta object id for the '<em>Quantity Double</em>' data type. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see de.hft-stuttgart.cityunits.NullableQuantity + * @see de.hft-stuttgart.cityunits.quantities.impl.QuantitiesPackageImpl#getQuantityDouble() + * @generated + */ + int QUANTITY_DOUBLE = 0; + + /** + * The meta object id for the '<em>Quantity Long</em>' data type. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see de.hft-stuttgart.cityunits.NullableQuantity + * @see de.hft-stuttgart.cityunits.quantities.impl.QuantitiesPackageImpl#getQuantityLong() + * @generated + */ + int QUANTITY_LONG = 1; + + + /** + * Returns the meta object for data type '{@link de.hft-stuttgart.cityunits.NullableQuantity <em>Quantity Double</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for data type '<em>Quantity Double</em>'. + * @see de.hft-stuttgart.cityunits.NullableQuantity + * @model instanceClass="de.hft-stuttgart.cityunits.NullableQuantity" + * @generated + */ + EDataType getQuantityDouble(); + + /** + * Returns the meta object for data type '{@link de.hft-stuttgart.cityunits.NullableQuantity <em>Quantity Long</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for data type '<em>Quantity Long</em>'. + * @see de.hft-stuttgart.cityunits.NullableQuantity + * @model instanceClass="de.hft-stuttgart.cityunits.NullableQuantity" + * @generated + */ + EDataType getQuantityLong(); + + /** + * Returns the factory that creates the instances of the model. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the factory that creates the instances of the model. + * @generated + */ + QuantitiesFactory getQuantitiesFactory(); + + /** + * <!-- begin-user-doc --> + * Defines literals for the meta objects that represent + * <ul> + * <li>each class,</li> + * <li>each feature of each class,</li> + * <li>each operation of each class,</li> + * <li>each enum,</li> + * <li>and each data type</li> + * </ul> + * <!-- end-user-doc --> + * @generated + */ + interface Literals { + /** + * The meta object literal for the '<em>Quantity Double</em>' data type. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see de.hft-stuttgart.cityunits.NullableQuantity + * @see de.hft-stuttgart.cityunits.quantities.impl.QuantitiesPackageImpl#getQuantityDouble() + * @generated + */ + EDataType QUANTITY_DOUBLE = eINSTANCE.getQuantityDouble(); + + /** + * The meta object literal for the '<em>Quantity Long</em>' data type. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see de.hft-stuttgart.cityunits.NullableQuantity + * @see de.hft-stuttgart.cityunits.quantities.impl.QuantitiesPackageImpl#getQuantityLong() + * @generated + */ + EDataType QUANTITY_LONG = eINSTANCE.getQuantityLong(); + + } + +} //QuantitiesPackage diff --git a/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/impl/QuantitiesFactoryImpl.java b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/impl/QuantitiesFactoryImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..6f2934b5d98dc89d272b2c356cd72bb9240a36d6 --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/impl/QuantitiesFactoryImpl.java @@ -0,0 +1,157 @@ +/** + */ +package de.hftstuttgart.cityunits.model.quantities.impl; + +import de.hftstuttgart.cityunits.model.NullableQuantity; + +import de.hftstuttgart.cityunits.model.quantities.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * <!-- begin-user-doc --> + * An implementation of the model <b>Factory</b>. + * <!-- end-user-doc --> + * @generated + */ +public class QuantitiesFactoryImpl extends EFactoryImpl implements QuantitiesFactory { + /** + * Creates the default factory implementation. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public static QuantitiesFactory init() { + try { + QuantitiesFactory theQuantitiesFactory = (QuantitiesFactory)EPackage.Registry.INSTANCE.getEFactory(QuantitiesPackage.eNS_URI); + if (theQuantitiesFactory != null) { + return theQuantitiesFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new QuantitiesFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public QuantitiesFactoryImpl() { + super(); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Object createFromString(EDataType eDataType, String initialValue) { + switch (eDataType.getClassifierID()) { + case QuantitiesPackage.QUANTITY_DOUBLE: + return createQuantityDoubleFromString(eDataType, initialValue); + case QuantitiesPackage.QUANTITY_LONG: + return createQuantityLongFromString(eDataType, initialValue); + default: + throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier"); + } + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public String convertToString(EDataType eDataType, Object instanceValue) { + switch (eDataType.getClassifierID()) { + case QuantitiesPackage.QUANTITY_DOUBLE: + return convertQuantityDoubleToString(eDataType, instanceValue); + case QuantitiesPackage.QUANTITY_LONG: + return convertQuantityLongToString(eDataType, instanceValue); + default: + throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier"); + } + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public NullableQuantity createQuantityDoubleFromString(EDataType eDataType, String initialValue) { + return (NullableQuantity)super.createFromString(eDataType, initialValue); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public String convertQuantityDoubleToString(EDataType eDataType, Object instanceValue) { + return super.convertToString(eDataType, instanceValue); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public NullableQuantity createQuantityLongFromString(EDataType eDataType, String initialValue) { + return (NullableQuantity)super.createFromString(eDataType, initialValue); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public String convertQuantityLongToString(EDataType eDataType, Object instanceValue) { + return super.convertToString(eDataType, instanceValue); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public QuantitiesPackage getQuantitiesPackage() { + return (QuantitiesPackage)getEPackage(); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @deprecated + * @generated + */ + @Deprecated + public static QuantitiesPackage getPackage() { + return QuantitiesPackage.eINSTANCE; + } + +} //QuantitiesFactoryImpl diff --git a/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/impl/QuantitiesPackageImpl.java b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/impl/QuantitiesPackageImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..7978ceec36256f79efa9b648e78b5db95792d78b --- /dev/null +++ b/de.hft-stuttgart.cityunits.model/src/de/hftstuttgart/cityunits/model/quantities/impl/QuantitiesPackageImpl.java @@ -0,0 +1,178 @@ +/** + */ +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 org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * <!-- begin-user-doc --> + * An implementation of the model <b>Package</b>. + * <!-- end-user-doc --> + * @generated + */ +public class QuantitiesPackageImpl extends EPackageImpl implements QuantitiesPackage { + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private EDataType quantityDoubleEDataType = null; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private EDataType quantityLongEDataType = null; + + /** + * Creates an instance of the model <b>Package</b>, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + * <p>Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see de.hftstuttgart.cityunits.quantities.QuantitiesPackage#eNS_URI + * @see #init() + * @generated + */ + private QuantitiesPackageImpl() { + super(eNS_URI, QuantitiesFactory.eINSTANCE); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the <b>Package</b> for this model, and for any others upon which it depends. + * + * <p>This method is used to initialize {@link QuantitiesPackage#eINSTANCE} when that field is accessed. + * Clients should not invoke it directly. Instead, they should simply access that field to obtain the package. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static QuantitiesPackage init() { + if (isInited) return (QuantitiesPackage)EPackage.Registry.INSTANCE.getEPackage(QuantitiesPackage.eNS_URI); + + // Obtain or create and register package + Object registeredQuantitiesPackage = EPackage.Registry.INSTANCE.get(eNS_URI); + QuantitiesPackageImpl theQuantitiesPackage = registeredQuantitiesPackage instanceof QuantitiesPackageImpl ? (QuantitiesPackageImpl)registeredQuantitiesPackage : new QuantitiesPackageImpl(); + + isInited = true; + + // Create package meta-data objects + theQuantitiesPackage.createPackageContents(); + + // Initialize created meta-data + theQuantitiesPackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + theQuantitiesPackage.freeze(); + + // Update the registry and return the package + EPackage.Registry.INSTANCE.put(QuantitiesPackage.eNS_URI, theQuantitiesPackage); + return theQuantitiesPackage; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public EDataType getQuantityDouble() { + return quantityDoubleEDataType; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public EDataType getQuantityLong() { + return quantityLongEDataType; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public QuantitiesFactory getQuantitiesFactory() { + return (QuantitiesFactory)getEFactoryInstance(); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create data types + quantityDoubleEDataType = createEDataType(QUANTITY_DOUBLE); + quantityLongEDataType = createEDataType(QUANTITY_LONG); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Initialize data types + initEDataType(quantityDoubleEDataType, NullableQuantity.class, "QuantityDouble", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); + initEDataType(quantityLongEDataType, NullableQuantity.class, "QuantityLong", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); + + // Create resource + createResource(eNS_URI); + } + +} //QuantitiesPackageImpl diff --git a/de.hft-stuttgart.cityunits.p2site/.project b/de.hft-stuttgart.cityunits.p2site/.project new file mode 100644 index 0000000000000000000000000000000000000000..d15d10ad037ea684ea6f050ca38b037ccb073a53 --- /dev/null +++ b/de.hft-stuttgart.cityunits.p2site/.project @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>de.hft-stuttgart.cityunits.p2site</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.pde.UpdateSiteBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.m2e.core.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.m2e.core.maven2Nature</nature> + <nature>org.eclipse.pde.UpdateSiteNature</nature> + </natures> +</projectDescription> diff --git a/de.hft-stuttgart.cityunits.p2site/category.xml b/de.hft-stuttgart.cityunits.p2site/category.xml new file mode 100644 index 0000000000000000000000000000000000000000..8915acc9220b4585c639a8ee9225a19efc2875dc --- /dev/null +++ b/de.hft-stuttgart.cityunits.p2site/category.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<site> + <feature id="de.hft-stuttgart.cityunits.feature"> + <category name="de.hft-stuttgart.cityunits"/> + </feature> + <category-def name="de.hft-stuttgart.cityunits" label="HfT Stuttgart City Units"> + <description> + Introduce Ecore types for modeling quantities with units of mesurement (JSR-385). Add also units especially useful for urban simulation. + </description> + </category-def> +</site> diff --git a/de.hft-stuttgart.cityunits.p2site/pom.xml b/de.hft-stuttgart.cityunits.p2site/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..24da65c7a970467e1b23c0a93189f88213533430 --- /dev/null +++ b/de.hft-stuttgart.cityunits.p2site/pom.xml @@ -0,0 +1,11 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>de.hft-stuttgart.cityunits.p2site</artifactId> + <packaging>eclipse-repository</packaging> + <name>City Units P2 Site Generation</name> + <parent> + <groupId>de.hft-stuttgart</groupId> + <artifactId>de.hft-stuttgart.cityunits</artifactId> + <version>1.0.0</version> + </parent> +</project> \ No newline at end of file diff --git a/de.hft-stuttgart.cityunits.p2site/site.xml b/de.hft-stuttgart.cityunits.p2site/site.xml new file mode 100644 index 0000000000000000000000000000000000000000..2bcbbd2471189d6bb6c26c4831108d856bd18c40 --- /dev/null +++ b/de.hft-stuttgart.cityunits.p2site/site.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<site> + <feature url="features/de.hft-stuttgart.cityunits.feature_1.0.0.jar" id="de.hft-stuttgart.cityunits.feature" version="1.0.0"> + <category name="de.hft-stuttgart.cityunits"/> + </feature> + <category-def name="de.hft-stuttgart.cityunits" label="HfT Stuttgart City Units"> + <description> + Introduce Ecore types for modeling quantities with units of mesurement (JSR-385). Add also units especially useful for urban simulation. + </description> + </category-def> +</site> diff --git a/de.hft-stuttgart.cityunits.target/.project b/de.hft-stuttgart.cityunits.target/.project new file mode 100644 index 0000000000000000000000000000000000000000..a443490d005c4961e34e484573782e6ac8bd3ddb --- /dev/null +++ b/de.hft-stuttgart.cityunits.target/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>de.hft-stuttgart.cityunits.target</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.m2e.core.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.m2e.core.maven2Nature</nature> + </natures> +</projectDescription> diff --git "a/de.hft-stuttgart.cityunits.target/Icon\r" "b/de.hft-stuttgart.cityunits.target/Icon\r" new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/de.hft-stuttgart.cityunits.target/cityunits.target.target b/de.hft-stuttgart.cityunits.target/cityunits.target.target new file mode 100644 index 0000000000000000000000000000000000000000..7ead7b54f6e1a21820daca4f78c586b5e6e30307 --- /dev/null +++ b/de.hft-stuttgart.cityunits.target/cityunits.target.target @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?pde version="3.8"?> +<target name="RCP, EMF Forms 2020-09"> + <locations> + <location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="planner" includeSource="false" type="InstallableUnit"> + <repository location="http://download.eclipse.org/releases/2020-09"/> + <unit id="org.eclipse.equinox.sdk.feature.group" version="3.20.300.v20200828-1034"/> + <unit id="org.eclipse.e4.rcp.feature.group" version="4.17.0.v20200831-1002"/> + </location> + <location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="planner" includeSource="false" type="InstallableUnit"> + <repository location="http://download.eclipse.org/ecp/releases/releases_target_125/"/> + <unit id="org.eclipse.emf.ecp.emfforms.sdk.feature.feature.group" version="0.0.0"/> + </location> + <location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="planner" includeSource="false" type="InstallableUnit"> + <repository location="https://transfer.hft-stuttgart.de/pages/indriya-p2/release_target_211/"/> + <unit id="de.hft-stuttgart.indriya.feature.feature.group" version="1.0.0"/> + </location> + <location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="planner" includeSource="false" type="InstallableUnit"> + <repository location="https://download.eclipse.org/tools/orbit/downloads/2020-09/"/> + <unit id="org.junit" version="4.13.0.v20200204-1500"/> + <unit id="org.junit.jupiter.api" version="5.6.0.v20200203-2009"/> + </location> + </locations> +</target> \ No newline at end of file diff --git a/de.hft-stuttgart.cityunits.target/pom.xml b/de.hft-stuttgart.cityunits.target/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..752c81513ea816d1a95c5e5d01ad9c5917f71c39 --- /dev/null +++ b/de.hft-stuttgart.cityunits.target/pom.xml @@ -0,0 +1,15 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>de.hft-stuttgart.cityunits.target</artifactId> + <packaging>eclipse-target-definition</packaging> + <name>City Units Target Definition</name> + + <parent> + <groupId>de.hft-stuttgart</groupId> + <artifactId>de.hft-stuttgart.cityunits</artifactId> + <version>1.0.0</version> + </parent> + +</project> \ No newline at end of file diff --git a/de.hft-stuttgart.cityunits.tests/.classpath b/de.hft-stuttgart.cityunits.tests/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..59fdf012e1435e4d4d9e06451db0ec3f05014653 --- /dev/null +++ b/de.hft-stuttgart.cityunits.tests/.classpath @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src/"> + <attributes> + <attribute name="test" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="output" path="target/classes"/> +</classpath> diff --git a/de.hft-stuttgart.cityunits.tests/.project b/de.hft-stuttgart.cityunits.tests/.project new file mode 100644 index 0000000000000000000000000000000000000000..333fd81041a26c87ba3f18b325d976bb630bad00 --- /dev/null +++ b/de.hft-stuttgart.cityunits.tests/.project @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>de.hft-stuttgart.cityunits.tests</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.m2e.core.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.m2e.core.maven2Nature</nature> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/de.hft-stuttgart.cityunits.tests/META-INF/MANIFEST.MF b/de.hft-stuttgart.cityunits.tests/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..263f1eb5c1155fbd5795e61823ee24c05fd94ac8 --- /dev/null +++ b/de.hft-stuttgart.cityunits.tests/META-INF/MANIFEST.MF @@ -0,0 +1,11 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Tests +Bundle-SymbolicName: de.hft-stuttgart.cityunits.tests +Bundle-Version: 1.0.0 +Automatic-Module-Name: de.hft.stuttgart.cityunits.tests +Import-Package: de.hftstuttgart.cityunits.model, + org.junit;version="4.13.0", + org.junit.jupiter.api;version="5.6.0" +Require-Bundle: javax.measure.unit-api, + tech.units.indriya diff --git a/de.hft-stuttgart.cityunits.tests/build.properties b/de.hft-stuttgart.cityunits.tests/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..34d2e4d2dad529ceaeb953bfcdb63c51d69ffed2 --- /dev/null +++ b/de.hft-stuttgart.cityunits.tests/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/de.hft-stuttgart.cityunits.tests/pom.xml b/de.hft-stuttgart.cityunits.tests/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..c0f9adcf44b790709aaf9460e52d691d60d0c25a --- /dev/null +++ b/de.hft-stuttgart.cityunits.tests/pom.xml @@ -0,0 +1,15 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>de.hft-stuttgart.cityunits.tests</artifactId> + <packaging>eclipse-test-plugin</packaging> + <name>City Units Target Definition</name> + + <parent> + <groupId>de.hft-stuttgart</groupId> + <artifactId>de.hft-stuttgart.cityunits</artifactId> + <version>1.0.0</version> + </parent> + +</project> \ No newline at end of file diff --git a/de.hft-stuttgart.cityunits.tests/src/de/hftstuttgart/cityunits/tests/QuantityTest.java b/de.hft-stuttgart.cityunits.tests/src/de/hftstuttgart/cityunits/tests/QuantityTest.java new file mode 100644 index 0000000000000000000000000000000000000000..8c3317ea58cadea0d14dff476813977d584a4eb3 --- /dev/null +++ b/de.hft-stuttgart.cityunits.tests/src/de/hftstuttgart/cityunits/tests/QuantityTest.java @@ -0,0 +1,65 @@ +package de.hftstuttgart.cityunits.tests; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import javax.measure.Quantity; +import javax.measure.Unit; +import javax.measure.quantity.Area; +import javax.measure.quantity.Length; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import de.hftstuttgart.cityunits.model.UrbanSimulationUnits; +import tech.units.indriya.quantity.Quantities; +import tech.units.indriya.unit.Units; + + +class QuantityTest +{ + @BeforeAll + static void init() { + // Initialize additional units like metric ton, $ and € with their labels + UrbanSimulationUnits.getInstance(); + } + + @Test + void testTemperature() { + java.lang.String cs = "5 °C"; + Quantity<?> q = Quantities.getQuantity(cs); + + assertEquals("[Θ]", q.getUnit().getDimension().toString(), "Wrong dimension!"); + assertEquals("278.15 K", q.toSystemUnit().toString(), "Wrong calculation of Celsius to Kelvin!"); + } + + @Test + void testMetreAndArea() { + Unit<Area> sqm = Units.METRE.multiply(Units.METRE).asType(Area.class); + Quantity<Length> line = Quantities.getQuantity(2, Units.METRE); + Quantity<Area> area = line.multiply(line).asType(Area.class); + + assertEquals(sqm, area.getUnit(), "Wrong unit computation!"); + assertEquals(4, area.getValue(), "Wrong calculation of area!"); + } + + @Test + void testUrbanSimulationUnitMoney() { + Quantity<?> cost = Quantities.getQuantity("1.50 €"); + assertEquals(cost.getUnit(), UrbanSimulationUnits.EURO, "Wrong currency!"); + } + + @Test + void testUrbanSimulationUnitPPMAndTon() { + Quantity<?> q = Quantities.getQuantity("20 ppm").multiply(Quantities.getQuantity("10 t")); + + assertEquals("[M]", q.getUnit().getDimension().toString()); + assertEquals(UrbanSimulationUnits.PARTS_PER_MILLION.multiply(UrbanSimulationUnits.TON), q.getUnit()); + assertEquals(200, q.getValue()); + } + + @Test + void testkWhPerCubicMeter() { + Quantity<?> q = Quantities.getQuantity("5.2 kW*h/m³"); + assertEquals("[M]/([L]·[T]²)", q.getUnit().getDimension().toString(), "Wrong dimension!"); + assertEquals("187200000 W·s/m³", q.toSystemUnit().toString()); + } + +} diff --git a/de.hft-stuttgart.cityunits.ui.renderer/.classpath b/de.hft-stuttgart.cityunits.ui.renderer/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..423c9748708b92edc302dfc7f28ae3e0556be1ff --- /dev/null +++ b/de.hft-stuttgart.cityunits.ui.renderer/.classpath @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"> + <attributes> + <attribute name="module" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src/"/> + <classpathentry kind="output" path="target/classes"/> +</classpath> diff --git a/de.hft-stuttgart.cityunits.ui.renderer/.project b/de.hft-stuttgart.cityunits.ui.renderer/.project new file mode 100644 index 0000000000000000000000000000000000000000..b6499485709cf2f99807d690249f32c15b60e271 --- /dev/null +++ b/de.hft-stuttgart.cityunits.ui.renderer/.project @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>de.hft-stuttgart.cityunits.ui.renderer</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ds.core.builder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.m2e.core.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.m2e.core.maven2Nature</nature> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/de.hft-stuttgart.cityunits.ui.renderer/META-INF/MANIFEST.MF b/de.hft-stuttgart.cityunits.ui.renderer/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..cf2290214bc9059abbba754da1ad48b9b58e3506 --- /dev/null +++ b/de.hft-stuttgart.cityunits.ui.renderer/META-INF/MANIFEST.MF @@ -0,0 +1,28 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: QuantityControl +Bundle-SymbolicName: de.hft-stuttgart.cityunits.ui.renderer;singleton:=true +Bundle-Version: 1.0.0 +Bundle-Vendor: HfT Stuttgart +Export-Package: de.hftstuttgart.cityunits.ui.renderer;version="1.0.0" +Require-Bundle: de.hft-stuttgart.cityunits.model;bundle-version="1.0.0", + org.eclipse.emf.ecp.edit.swt;bundle-version="[1.24.0,2.0.0)", + org.eclipse.emf.ecp.ui.view.swt;bundle-version="[1.24.0,2.0.0)", + org.eclipse.emf.ecp.view.core.swt;bundle-version="[1.24.0,2.0.0)", + org.eclipse.emf.ecp.view.template.model;bundle-version="[1.24.0,2.0.0)", + org.eclipse.emf.edit;bundle-version="[2.8.0,3.0.0)", + org.eclipse.core.runtime;bundle-version="[3.8.0,4.0.0)", + org.eclipse.emfforms.core.services.editsupport;bundle-version="[1.24.0,2.0.0)", + org.eclipse.emf.databinding;bundle-version="[1.3.0,2.0.0)", + org.eclipse.emfforms.swt.core.di;bundle-version="[1.24.0,2.0.0)", + org.eclipse.emfforms.localization;bundle-version="[1.24.0,2.0.0)", + org.eclipse.jface;bundle-version="0.0.0", + javax.measure.unit-api;bundle-version="[2.1.1,3.0.0)" +Service-Component: OSGI-INF/quantityRendererService.xml +Bundle-ActivationPolicy: lazy +Import-Package: javax.inject;version="1.0.0", + org.eclipse.emfforms.spi.common.report;version="[1.24.0, 2.0.0)", + org.eclipse.jface.layout;version="0.0.0", + org.eclipse.swt;version="0.0.0", + org.eclipse.swt.widgets;version="0.0.0" +Automatic-Module-Name: de.hft-stuttgart.units.ui.eclipse.quantityrenderer diff --git a/de.hft-stuttgart.cityunits.ui.renderer/OSGI-INF/quantityRendererService.xml b/de.hft-stuttgart.cityunits.ui.renderer/OSGI-INF/quantityRendererService.xml new file mode 100644 index 0000000000000000000000000000000000000000..f628d2129e06b63e8229803797a434a907a90d83 --- /dev/null +++ b/de.hft-stuttgart.cityunits.ui.renderer/OSGI-INF/quantityRendererService.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="de.hft-stuttgart.units.ui.rendererservice"> + <implementation class="de.hftstuttgart.cityunits.ui.renderer.QuantityControlRendererService"/> + <service> + <provide interface="org.eclipse.emfforms.spi.swt.core.di.EMFFormsDIRendererService"/> + </service> + <reference bind="setEMFFormsDatabinding" cardinality="1..1" interface="org.eclipse.emfforms.spi.core.services.databinding.EMFFormsDatabinding" name="EMFFormsDatabinding" policy="static"/> + <reference bind="setReportService" cardinality="1..1" interface="org.eclipse.emfforms.spi.common.report.ReportService" name="ReportService" policy="static"/> +</scr:component> diff --git a/de.hft-stuttgart.cityunits.ui.renderer/build.properties b/de.hft-stuttgart.cityunits.ui.renderer/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..6210e849b591d26fa9e17057ad3e8d09511917b6 --- /dev/null +++ b/de.hft-stuttgart.cityunits.ui.renderer/build.properties @@ -0,0 +1,5 @@ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/ +source.. = src/ diff --git a/de.hft-stuttgart.cityunits.ui.renderer/pom.xml b/de.hft-stuttgart.cityunits.ui.renderer/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..9b0a1a310f2a21608a98d3be86eb4da4440316be --- /dev/null +++ b/de.hft-stuttgart.cityunits.ui.renderer/pom.xml @@ -0,0 +1,14 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>de.hft-stuttgart.cityunits.ui.renderer</artifactId> + <packaging>eclipse-plugin</packaging> + <name>City Units SWT Renderer</name> + + <parent> + <groupId>de.hft-stuttgart</groupId> + <artifactId>de.hft-stuttgart.cityunits</artifactId> + <version>1.0.0</version> + </parent> +</project> \ No newline at end of file diff --git a/de.hft-stuttgart.cityunits.ui.renderer/src/de/hftstuttgart/cityunits/ui/renderer/QuantityControlRenderer.java b/de.hft-stuttgart.cityunits.ui.renderer/src/de/hftstuttgart/cityunits/ui/renderer/QuantityControlRenderer.java new file mode 100644 index 0000000000000000000000000000000000000000..23797c0188aa0791b0813ce744930781c0ffb292 --- /dev/null +++ b/de.hft-stuttgart.cityunits.ui.renderer/src/de/hftstuttgart/cityunits/ui/renderer/QuantityControlRenderer.java @@ -0,0 +1,374 @@ +package de.hftstuttgart.cityunits.ui.renderer; + +import java.math.BigInteger; +import java.text.DecimalFormat; +import java.text.ParseException; +import java.text.ParsePosition; + +import javax.inject.Inject; +import javax.measure.Unit; + +import org.eclipse.core.databinding.Binding; +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.UpdateValueStrategy; +import org.eclipse.core.databinding.observable.value.IObservableValue; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecp.edit.internal.swt.controls.NumericalHelper; +import org.eclipse.emf.ecp.edit.spi.swt.util.ECPDialogExecutor; +import org.eclipse.emf.ecp.view.internal.core.swt.MessageKeys; +import org.eclipse.emf.ecp.view.spi.context.ViewModelContext; +import org.eclipse.emf.ecp.view.spi.core.swt.renderer.TextControlSWTRenderer; +import org.eclipse.emf.ecp.view.spi.model.VControl; +import org.eclipse.emf.ecp.view.spi.model.VFeaturePathDomainModelReference; +import org.eclipse.emf.ecp.view.template.model.VTViewTemplateProvider; +import org.eclipse.emf.edit.command.SetCommand; +import org.eclipse.emfforms.spi.common.locale.EMFFormsLocaleChangeListener; +import org.eclipse.emfforms.spi.common.locale.EMFFormsLocaleProvider; +import org.eclipse.emfforms.spi.common.report.ReportService; +import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException; +import org.eclipse.emfforms.spi.core.services.databinding.EMFFormsDatabinding; +import org.eclipse.emfforms.spi.core.services.editsupport.EMFFormsEditSupport; +import org.eclipse.emfforms.spi.core.services.label.EMFFormsLabelProvider; +import org.eclipse.emfforms.spi.localization.EMFFormsLocalizationService; +import org.eclipse.jface.dialogs.IDialogLabelKeys; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +import de.hftstuttgart.cityunits.model.NullableQuantity; +import de.hftstuttgart.cityunits.model.quantities.QuantitiesPackage; +// import de.hft-stuttgart.energycomponents.EnCompPackage; + +public class QuantityControlRenderer extends TextControlSWTRenderer { + + private final EMFFormsLocalizationService localizationService; + private final EMFFormsLocaleProvider localeProvider; + private EMFFormsLocaleChangeListener emfFormsLocaleChangeListener; + private Unit<?> unit; + + /** + * Default constructor. + * + * @param vElement the view model element to be rendered + * @param viewContext the view context + * @param reportService The {@link ReportService} + * @param emfFormsDatabinding The {@link EMFFormsDatabinding} + * @param emfFormsLabelProvider The {@link EMFFormsLabelProvider} + * @param vtViewTemplateProvider The {@link VTViewTemplateProvider} + * @param emfFormsEditSupport The {@link EMFFormsEditSupport} + * @param localizationService The {@link EMFFormsLocalizationService} + * @param localeProvider The {@link EMFFormsLocaleProvider} + */ + @Inject + // CHECKSTYLE.OFF: ParameterNumber + public QuantityControlRenderer(VControl vElement, ViewModelContext viewContext, ReportService reportService, + EMFFormsDatabinding emfFormsDatabinding, EMFFormsLabelProvider emfFormsLabelProvider, + VTViewTemplateProvider vtViewTemplateProvider, EMFFormsEditSupport emfFormsEditSupport, + EMFFormsLocalizationService localizationService, EMFFormsLocaleProvider localeProvider) { + // CHECKSTYLE.ON: ParameterNumber + super(vElement, viewContext, reportService, emfFormsDatabinding, emfFormsLabelProvider, vtViewTemplateProvider, + emfFormsEditSupport); + this.localizationService = localizationService; + this.localeProvider = localeProvider; + } + + @Override + protected Control createSWTControl(Composite parent) { + final VFeaturePathDomainModelReference featureRef = (VFeaturePathDomainModelReference) getVElement() + .getDomainModelReference(); + final String defaultString = featureRef.getDomainModelEFeature().getDefaultValueLiteral(); + final NullableQuantity defaultValue = NullableQuantity.create(defaultString); + unit = defaultValue.getUnit(); + + final Composite composite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite); + GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.BEGINNING).applyTo(composite); + final Control control = super.createSWTControl(composite); + final Label label = new Label(composite, SWT.PUSH); + label.setText(unit.toString()); + return control; + } + + @Override + protected int getDefaultAlignment() { + return SWT.RIGHT; + } + + /* + * (non-Javadoc) + * @see org.eclipse.emf.ecp.edit.internal.swt.controls.AbstractTextControl#getTextVariantID() + */ + @Override + protected String getTextVariantID() { + return "org_eclipse_emf_ecp_control_numerical"; //$NON-NLS-1$ + } + + @Override + protected String getTextMessage() { + return ""; //$NON-NLS-1$ + } + + @Override + protected Object convert(Text text, EDataType attributeType, String value) throws DatabindingFailedException { + final EStructuralFeature eStructuralFeature = (EStructuralFeature) getModelValue().getValueType(); + final NumericalTargetToModelUpdateStrategy converter = new NumericalTargetToModelUpdateStrategy( + eStructuralFeature, getModelValue(), getDataBindingContext(), text); + return converter.convert(value); + } + + @Override + protected Binding[] createBindings(final Control control) throws DatabindingFailedException { + final EStructuralFeature structuralFeature = (EStructuralFeature) getModelValue().getValueType(); + + final UpdateValueStrategy<?, ?> targetToModelStrategy = withPreSetValidation( + new NumericalTargetToModelUpdateStrategy(structuralFeature, getModelValue(), getDataBindingContext(), + (Text) Composite.class.cast(control).getChildren()[0])); + final NumericalModelToTargetUpdateStrategy modelToTargetStrategy = new NumericalModelToTargetUpdateStrategy( + getInstanceClass(structuralFeature), false); + final Binding binding = bindValue(control, getModelValue(), getDataBindingContext(), + targetToModelStrategy, modelToTargetStrategy); + final Binding tooltipBinding = createTooltipBinding(control, getModelValue(), getDataBindingContext(), + targetToModelStrategy, + new NumericalModelToTargetUpdateStrategy(getInstanceClass(structuralFeature), true)); + + emfFormsLocaleChangeListener = new EMFFormsLocaleChangeListener() { + + /** + * {@inheritDoc} + * + * @see org.eclipse.emfforms.spi.common.locale.EMFFormsLocaleChangeListener#notifyLocaleChange() + */ + @Override + public void notifyLocaleChange() { + ((Text) control).setMessage(getTextMessage()); + binding.updateModelToTarget(); + } + }; + localeProvider.addEMFFormsLocaleChangeListener(emfFormsLocaleChangeListener); + + return new Binding[] { binding, tooltipBinding }; + } + + private Class<?> getInstanceClass(EStructuralFeature feature) { + if (feature.getEType() == QuantitiesPackage.eINSTANCE.getQuantityDouble()) { + return Double.class; + } else if (feature.getEType() == QuantitiesPackage.eINSTANCE.getQuantityLong()) { + return Long.class; + } + assert false; + return null; + } + + @Override + protected String getTextFromTextField(Text text, EDataType attributeType) { + return text.getText().isBlank() ? null : super.getTextFromTextField(text, attributeType); + } + + /** + * Converts the numerical value from the model to the target. Locale settings are respected, + * i.e. formatting is performed according to the current locale. + */ + private class NumericalModelToTargetUpdateStrategy extends ModelToTargetUpdateStrategy { + + private final Class<?> instanceClass; + + NumericalModelToTargetUpdateStrategy(Class<?> instanceClass, boolean tooltip) { + super(tooltip); + this.instanceClass = instanceClass; + } + + @Override + public Object convertValue(Object value) { + if (value == null) { + return ""; //$NON-NLS-1$ + } + return ((NullableQuantity) value).getNumber() + .map(n -> NumericalHelper.setupFormat(localeProvider.getLocale(), instanceClass).format(n)) + .orElse(""); //$NON-NLS-1$ + } + } + + /** + * More specific target to model update strategy that convert the string + * in the text field to a number. If the string is a invalid number, + * for instance because of the current locale, the value is reset to + * the last valid value found in the mode. + */ + private class NumericalTargetToModelUpdateStrategy extends TargetToModelUpdateStrategy { + + private final Text text; + private final IObservableValue<?> modelValue; + private final EStructuralFeature eStructuralFeature; + private final DataBindingContext dataBindingContext; + + NumericalTargetToModelUpdateStrategy(EStructuralFeature eStructuralFeature, + IObservableValue<?> modelValue, DataBindingContext dataBindingContext, Text text) { + super(eStructuralFeature.isUnsettable()); + this.eStructuralFeature = eStructuralFeature; + this.modelValue = modelValue; + this.dataBindingContext = dataBindingContext; + this.text = text; + } + + @Override + protected Object convertValue(final Object value) { + final DecimalFormat format = NumericalHelper.setupFormat( + localeProvider.getLocale(), getInstanceClass(eStructuralFeature)); + + try { + Number number = null; + if (value == null) { + number = NumericalHelper.getDefaultValue(getInstanceClass(eStructuralFeature)); + } else { + final ParsePosition pp = new ParsePosition(0); + number = format.parse((String) value, pp); + if (pp.getErrorIndex() != -1 || pp.getIndex() != ((String) value).length()) { + return getOldValue(value); + } + if (isInteger(getInstanceClass(eStructuralFeature))) { + boolean maxValue = false; + boolean minValue = false; + final Class<?> instanceClass = getInstanceClass(eStructuralFeature); + if (number.doubleValue() >= getInstanceMaxValue(instanceClass)) { + maxValue = true; + } else if (number.doubleValue() <= getInstanceMinValue(instanceClass)) { + minValue = true; + } + + if (maxValue || minValue) { + return numberToQuantity(number); + } + } + } + String formatedNumber = ""; //$NON-NLS-1$ + if (number != null) { + formatedNumber = format.format(number); + } + if (formatedNumber.length() == 0) { + return null; + } + return numberToQuantity(format.parse(formatedNumber)); + } catch (final ParseException ex) { + return getOldValue(value); + } + } + + /** + * Whether the given class is an integer. + * + * @param instanceClass the class to check + * @return <code>true</code> if integer, <code>false</code> otherwise + */ + private boolean isInteger(Class<?> instanceClass) { + if (instanceClass.isPrimitive()) { + return long.class == instanceClass + || int.class == instanceClass + || short.class == instanceClass + || byte.class == instanceClass; + } + return BigInteger.class == instanceClass + || Long.class == instanceClass + || BigInteger.class == instanceClass + || Short.class == instanceClass + || Byte.class == instanceClass; + } + + private Object numberToQuantity(Number number) { + return NullableQuantity.create(number, unit); + } + + private double getInstanceMinValue(Class<?> instanceClass) { + if (Integer.class == instanceClass || int.class == instanceClass) { + return Integer.MIN_VALUE; + } + if (Long.class == instanceClass || long.class == instanceClass) { + return Long.MIN_VALUE; + } + if (Short.class == instanceClass || short.class == instanceClass) { + return Short.MIN_VALUE; + } + + return Double.NaN; + } + + private double getInstanceMaxValue(Class<?> instanceClass) { + if (Integer.class == instanceClass || int.class == instanceClass) { + return Integer.MAX_VALUE; + } + if (Long.class == instanceClass || long.class == instanceClass) { + return Long.MAX_VALUE; + } + if (Short.class == instanceClass || short.class == instanceClass) { + return Short.MAX_VALUE; + } + + return Double.NaN; + } + + @Override + protected IStatus doSet(IObservableValue observableValue, Object value) { + final IStatus status = super.doSet(observableValue, value); + // update targets after a model change triggered by the target to model databinding + dataBindingContext.updateTargets(); + return status; + } + + private Object getOldValue(final Object value) { + if (eStructuralFeature.getDefaultValue() == null && value == null || value.equals("")) { //$NON-NLS-1$ + return null; + } + final Object result = modelValue.getValue(); + + final MessageDialog messageDialog = new MessageDialog(text.getShell(), + localizationService.getString(getClass(), MessageKeys.NumericalControl_InvalidNumber), null, + localizationService.getString(getClass(), MessageKeys.NumericalControl_InvalidNumberWillBeUnset), + MessageDialog.ERROR, + new String[] { JFaceResources.getString(IDialogLabelKeys.OK_LABEL_KEY) }, 0); + + new ECPDialogExecutor(messageDialog) { + @Override + public void handleResult(int codeResult) { + + } + }.execute(); + + dataBindingContext.updateTargets(); + if (eStructuralFeature.isUnsettable() && result == null) { + // showUnsetLabel(); + return SetCommand.UNSET_VALUE; + } + return result; + } + + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.ecp.view.spi.core.swt.renderer.TextControlSWTRenderer#getUnsetText() + */ + @Override + protected String getUnsetText() { + return localizationService.getString(getClass(), MessageKeys.NumericalControl_NoNumberClickToSetNumber); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.ecp.view.spi.core.swt.SimpleControlSWTRenderer#dispose() + */ + @Override + protected void dispose() { + super.dispose(); + localeProvider.removeEMFFormsLocaleChangeListener(emfFormsLocaleChangeListener); + } + +} diff --git a/de.hft-stuttgart.cityunits.ui.renderer/src/de/hftstuttgart/cityunits/ui/renderer/QuantityControlRendererService.java b/de.hft-stuttgart.cityunits.ui.renderer/src/de/hftstuttgart/cityunits/ui/renderer/QuantityControlRendererService.java new file mode 100644 index 0000000000000000000000000000000000000000..02cbd2aa4c94d712de2bc5b7a20a107bb49ba764 --- /dev/null +++ b/de.hft-stuttgart.cityunits.ui.renderer/src/de/hftstuttgart/cityunits/ui/renderer/QuantityControlRendererService.java @@ -0,0 +1,86 @@ +package de.hftstuttgart.cityunits.ui.renderer; + +import org.eclipse.core.databinding.property.value.IValueProperty; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecp.view.spi.context.ViewModelContext; +import org.eclipse.emf.ecp.view.spi.model.VControl; +import org.eclipse.emf.ecp.view.spi.model.VElement; +import org.eclipse.emfforms.spi.common.report.ReportService; +import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException; +import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedReport; +import org.eclipse.emfforms.spi.core.services.databinding.EMFFormsDatabinding; +import org.eclipse.emfforms.spi.swt.core.AbstractSWTRenderer; +import org.eclipse.emfforms.spi.swt.core.di.EMFFormsDIRendererService; + +import de.hftstuttgart.cityunits.model.NullableQuantity; + +/** + * QuantityRendererService which provides the QuantityRenderer. + * + * @author Kai Brassel + * + */ +public class QuantityControlRendererService implements EMFFormsDIRendererService<VControl> { + + private EMFFormsDatabinding databindingService; + private ReportService reportService; + + /** + * Called by the initializer to set the EMFFormsDatabinding. + * + * @param databindingService The EMFFormsDatabinding + */ + protected void setEMFFormsDatabinding(EMFFormsDatabinding databindingService) { + this.databindingService = databindingService; + } + + /** + * Called by the initializer to set the ReportService. + * + * @param reportService The ReportService + */ + protected void setReportService(ReportService reportService) { + this.reportService = reportService; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emfforms.spi.swt.core.di.EMFFormsDIRendererService#isApplicable(VElement,ViewModelContext) + */ + @Override + public double isApplicable(VElement vElement, ViewModelContext viewModelContext) { + if (!VControl.class.isInstance(vElement)) { + return NOT_APPLICABLE; + } + final VControl control = (VControl) vElement; + if (control.getDomainModelReference() == null) { + return NOT_APPLICABLE; + } + @SuppressWarnings("rawtypes") + IValueProperty valueProperty; + try { + valueProperty = databindingService.getValueProperty(control.getDomainModelReference(), + viewModelContext.getDomainModel()); + } catch (final DatabindingFailedException ex) { + reportService.report(new DatabindingFailedReport(ex)); + return NOT_APPLICABLE; + } + final EStructuralFeature eStructuralFeature = EStructuralFeature.class.cast(valueProperty.getValueType()); + if (eStructuralFeature.getEType().getInstanceClass() == NullableQuantity.class) { + return 9; // 9 - not 10 - to avoid priority clash with multi-valued attributes + } + return NOT_APPLICABLE; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emfforms.spi.swt.core.di.EMFFormsDIRendererService#getRendererClass() + */ + @Override + public Class<? extends AbstractSWTRenderer<VControl>> getRendererClass() { + return QuantityControlRenderer.class; + } + +} diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..acff3685ccaae3f8b07adb6ee7375e87d1a45f09 --- /dev/null +++ b/pom.xml @@ -0,0 +1,80 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>de.hft-stuttgart</groupId> + <artifactId>de.hft-stuttgart.cityunits</artifactId> + <version>1.0.0</version> + <packaging>pom</packaging> + <name>City Units Parent POM</name> + + <properties> + <tycho-version>2.1.0</tycho-version> + </properties> + + <build> + <plugins> + <plugin> + <groupId>org.eclipse.tycho</groupId> + <artifactId>tycho-maven-plugin</artifactId> + <version>${tycho-version}</version> + <configuration> + <source>15</source> + <target>15</target> + <encoding>UTF-8</encoding> + </configuration> + <extensions>true</extensions> + </plugin> + + <plugin> + <groupId>org.eclipse.tycho</groupId> + <artifactId>target-platform-configuration</artifactId> + <version>${tycho-version}</version> + <configuration> + <pomDependencies>consider</pomDependencies> + <target> + <artifact> + <groupId>de.hft-stuttgart</groupId> + <artifactId>de.hft-stuttgart.cityunits.target</artifactId> + <version>1.0.0</version> + </artifact> + </target> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.22.2</version> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>tech.units</groupId> + <artifactId>indriya</artifactId> + <version>2.1.1</version> + </dependency> + <dependency> + <groupId>jakarta.inject</groupId> + <artifactId>jakarta.inject-api</artifactId> + <version>2.0.0</version> + </dependency> + <dependency> + <groupId>jakarta.annotation</groupId> + <artifactId>jakarta.annotation-api</artifactId> + <version>2.0.0</version> + </dependency> + </dependencies> + + <modules> + <module>de.hft-stuttgart.cityunits.target</module> + <module>de.hft-stuttgart.cityunits.feature</module> + <module>de.hft-stuttgart.cityunits.model</module> + <module>de.hft-stuttgart.cityunits.ui.renderer</module> + <module>de.hft-stuttgart.cityunits.p2site</module> + <module>de.hft-stuttgart.cityunits.tests</module> + </modules> + +</project> \ No newline at end of file