├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml ├── mergify.yml ├── pr-branch-labeler.yml └── workflows │ ├── cd-release.yml │ ├── ci-codacy-analysis.yaml │ ├── ci-main.yml │ ├── ci-pr.yml │ ├── labeler.yml │ └── update-gradle-wrapper.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── build.gradle ├── buildSrc ├── build.gradle.kts └── src │ └── main │ └── kotlin │ ├── unit-api.java-conventions.gradle.kts │ ├── unit-api.javadoc.gradle.kts │ ├── unit-api.publishing.gradle.kts │ ├── unit-api.spring-conventions.gradle.kts │ ├── unit-api.test.gradle.kts │ └── unit-api.version-class.gradle.kts ├── docs ├── _dep │ ├── modules │ │ ├── jackson-module.md │ │ ├── jackson-starter.md │ │ ├── jpa-starter.md │ │ ├── kotlin-module.md │ │ └── springdoc-starter.md │ └── quickstart │ │ ├── custom-units.md │ │ ├── jackson.md │ │ └── spring-boot.md ├── assets │ ├── logo.ico │ ├── logo.png │ ├── logo.svg │ ├── springdoc │ │ └── springdoc-properties.png │ └── test.svg ├── contribution.md ├── examples.md ├── index.md ├── java │ ├── index.md │ └── jackson.md ├── javadoc-ref.md ├── kotlin │ └── index.md └── spring-boot │ ├── index.md │ ├── jackson.md │ ├── jpa.md │ └── springdoc.md ├── gradle.properties ├── gradle ├── config │ ├── checkstyle.xml │ └── dependency-check-suppression.xml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── jitpack.yml ├── mkdocs.yml ├── requirements.txt ├── settings.gradle ├── spring-boot-core-starter ├── build.gradle └── src │ └── main │ ├── java │ └── com │ │ └── raynigon │ │ └── unit │ │ └── api │ │ └── core │ │ └── UnitApiCoreConfiguration.java │ └── resources │ └── META-INF │ └── spring │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports ├── spring-boot-jackson-starter ├── build.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── raynigon │ │ │ └── unit │ │ │ └── api │ │ │ └── jackson │ │ │ ├── UnitApiJacksonConfiguration.java │ │ │ └── UnitApiJacksonProperties.java │ └── resources │ │ └── META-INF │ │ └── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── test │ └── groovy │ └── com │ └── raynigon │ └── unit │ └── api │ └── jackson │ ├── JacksonStarterApplicationSpec.groovy │ ├── UnitApiJacksonConfigurationSpec.groovy │ ├── UnitApiJacksonPropertiesSpec.groovy │ └── helpers │ ├── BasicApplicationConfig.groovy │ ├── BasicEntity.groovy │ ├── BasicRestController.groovy │ ├── BasicService.groovy │ ├── CelsiusReader.groovy │ ├── PercentWriter.groovy │ └── WeatherEntity.groovy ├── spring-boot-jpa-starter ├── build.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── raynigon │ │ │ └── unit │ │ │ └── api │ │ │ └── jpa │ │ │ ├── annotation │ │ │ ├── JpaUnit.java │ │ │ ├── JpaUnitHelper.java │ │ │ └── NoneQuantity.java │ │ │ ├── cache │ │ │ └── CachedQuantity.java │ │ │ ├── configuration │ │ │ └── QuantityTypeRegistration.java │ │ │ ├── exception │ │ │ └── MissingUnitAnnotationException.java │ │ │ └── type │ │ │ └── QuantityType.java │ └── resources │ │ └── META-INF │ │ ├── services │ │ └── org.hibernate.boot.model.TypeContributor │ │ └── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── test │ ├── groovy │ └── com │ │ └── raynigon │ │ └── unit │ │ └── api │ │ └── jpa │ │ ├── JpaStarterApplicationSpec.groovy │ │ ├── annotation │ │ └── JpaUnitHelperSpec.groovy │ │ ├── helpers │ │ ├── BasicApplicationConfig.groovy │ │ ├── BasicEntity.groovy │ │ └── BasicRepository.groovy │ │ └── type │ │ └── QuantityTypeSpec.groovy │ └── resources │ └── import.sql ├── spring-boot-springdoc-starter ├── build.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── raynigon │ │ │ └── unit │ │ │ └── api │ │ │ └── springdoc │ │ │ ├── UnitApiPropertyCustomizer.java │ │ │ └── UnitApiSpringdocConfiguration.java │ └── resources │ │ └── META-INF │ │ └── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── test │ └── groovy │ └── com │ └── raynigon │ └── unit │ └── api │ └── springdoc │ ├── SpringdocStarterApplicationSpec.groovy │ ├── UnitApiPropertyCustomizerSpec.groovy │ └── helpers │ └── BasicApplicationConfig.groovy ├── unit-api-core ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── raynigon │ │ └── unit │ │ └── api │ │ └── core │ │ ├── annotation │ │ └── QuantityShape.java │ │ ├── exception │ │ └── UnitNotFoundException.java │ │ ├── function │ │ ├── Calculator.java │ │ ├── CalculusUtils.java │ │ ├── CompositionTask.java │ │ ├── CompositionTaskArrayAdapter.java │ │ ├── CompositionTaskBitScanner.java │ │ ├── Converter.java │ │ ├── ConverterCompositionHandler.java │ │ ├── DimensionalModel.java │ │ ├── FactorSupplier.java │ │ ├── IntBaseSupplier.java │ │ ├── IntExponentSupplier.java │ │ ├── Lazy.java │ │ ├── Nameable.java │ │ ├── NumberSystem.java │ │ ├── PrefixOperator.java │ │ ├── QuantityConverter.java │ │ ├── RationalNumber.java │ │ ├── ScaleHelper.java │ │ ├── StandardModel.java │ │ ├── SymbolSupplier.java │ │ ├── UnitComparator.java │ │ ├── UnitCompositionHandlerYieldingNormalForm.java │ │ ├── UnitConverterSupplier.java │ │ ├── UnitSupplier.java │ │ ├── ValueSupplier.java │ │ ├── numbersystem │ │ │ ├── DefaultNumberSystem.java │ │ │ ├── DefaultNumberType.java │ │ │ ├── exception │ │ │ │ ├── UnexpectedCodeReachException.java │ │ │ │ ├── UnsupportedNumberTypeException.java │ │ │ │ └── UnsupportedNumberValueException.java │ │ │ └── types │ │ │ │ ├── AtomicIntegerHelper.java │ │ │ │ ├── AtomicLongHelper.java │ │ │ │ ├── BigDecimalHelper.java │ │ │ │ ├── BigIntegerHelper.java │ │ │ │ ├── ByteHelper.java │ │ │ │ ├── DoubleHelper.java │ │ │ │ ├── FloatHelper.java │ │ │ │ ├── IntegerHelper.java │ │ │ │ ├── IntegerNumberHelper.java │ │ │ │ ├── LongHelper.java │ │ │ │ ├── NumberHelperContainer.java │ │ │ │ ├── RationalNumberHelper.java │ │ │ │ ├── ShortHelper.java │ │ │ │ └── TypedNumberHelper.java │ │ └── unitconverter │ │ │ ├── AbstractConverter.java │ │ │ ├── AddConverter.java │ │ │ ├── DoubleMultiplyConverter.java │ │ │ ├── ExpConverter.java │ │ │ ├── IdentityMultiplyConverter.java │ │ │ ├── LogConverter.java │ │ │ ├── MultiplyConverter.java │ │ │ ├── PowerOfIntConverter.java │ │ │ ├── PowerOfPiConverter.java │ │ │ └── RationalConverter.java │ │ ├── io │ │ ├── DefaultQuantityReader.java │ │ ├── QuantityReader.java │ │ └── QuantityWriter.java │ │ ├── math │ │ └── QuantityMath.java │ │ ├── quantities │ │ ├── AbstractQuantity.java │ │ ├── ComparableQuantity.java │ │ ├── NumberQuantity.java │ │ └── Torque.java │ │ ├── service │ │ ├── DefaultUnitsApiService.java │ │ └── UnitsApiService.java │ │ └── units │ │ ├── binary │ │ ├── BinarySystem.java │ │ ├── BinarySystemUnitsConstants.java │ │ ├── Data.java │ │ └── bytes │ │ │ ├── Bit.java │ │ │ ├── Byte.java │ │ │ ├── Gibibyte.java │ │ │ ├── Gigabyte.java │ │ │ ├── Kibibyte.java │ │ │ ├── Kilobyte.java │ │ │ ├── Mebibyte.java │ │ │ ├── Megabyte.java │ │ │ ├── Tebibyte.java │ │ │ └── Terabyte.java │ │ ├── general │ │ ├── AbstractUnit.java │ │ ├── AlternateUnit.java │ │ ├── AnnotatedUnit.java │ │ ├── BaseUnit.java │ │ ├── ComparableUnit.java │ │ ├── IUnit.java │ │ ├── ProductUnit.java │ │ ├── ProductUnitElement.java │ │ ├── ProductUnitElementUtil.java │ │ ├── ScaledUnit.java │ │ ├── TransformedUnit.java │ │ ├── UnitDimension.java │ │ └── UnitScanUtils.java │ │ └── si │ │ ├── SISystem.java │ │ ├── SISystemUnitsConstants.java │ │ ├── acceleration │ │ └── MetrePerSquaredSecond.java │ │ ├── area │ │ └── SquareMetre.java │ │ ├── dimensionless │ │ ├── One.java │ │ └── Percent.java │ │ ├── electrical │ │ ├── charge │ │ │ ├── AmpereHour.java │ │ │ └── Coulomb.java │ │ ├── current │ │ │ ├── Ampere.java │ │ │ └── MilliAmpere.java │ │ └── potential │ │ │ ├── MilliVolt.java │ │ │ └── Volt.java │ │ ├── energy │ │ ├── Joule.java │ │ ├── KiloWattHour.java │ │ ├── MilliWattHour.java │ │ └── WattHour.java │ │ ├── force │ │ └── Newton.java │ │ ├── frequency │ │ └── Hertz.java │ │ ├── length │ │ ├── Centimetre.java │ │ ├── Kilometre.java │ │ ├── Metre.java │ │ └── Millimetre.java │ │ ├── mass │ │ └── Kilogram.java │ │ ├── power │ │ ├── MilliWatt.java │ │ └── Watt.java │ │ ├── speed │ │ ├── KilometrePerHour.java │ │ └── MetrePerSecond.java │ │ ├── temperature │ │ ├── Celsius.java │ │ └── Kelvin.java │ │ ├── time │ │ ├── Hour.java │ │ ├── MicroSecond.java │ │ ├── MilliSecond.java │ │ ├── Minute.java │ │ ├── NanoSecond.java │ │ └── Second.java │ │ ├── torque │ │ └── NewtonMetre.java │ │ └── volume │ │ ├── CubicMetre.java │ │ └── Litre.java │ └── test │ ├── groovy │ └── com │ │ └── raynigon │ │ └── unit │ │ └── api │ │ └── core │ │ ├── function │ │ ├── CalculatorSpec.groovy │ │ ├── CompositionTaskArrayAdapterSpec.groovy │ │ ├── CompositionTaskSpec.groovy │ │ ├── DimensionalModelSpec.groovy │ │ ├── LazySpec.groovy │ │ ├── ScaleHelperSpec.groovy │ │ ├── StandardModelSpec.groovy │ │ ├── UnitComparatorSpec.groovy │ │ ├── UnitCompositionHandlerYieldingNormalFormSpec.groovy │ │ ├── numbersystem │ │ │ ├── DefaultNumberSystemSpec.groovy │ │ │ ├── DefaultNumberTypeSpec.groovy │ │ │ └── types │ │ │ │ ├── AtomicIntegerHelperSpec.groovy │ │ │ │ ├── AtomicLongHelperSpec.groovy │ │ │ │ ├── BigDecimalHelperSpec.groovy │ │ │ │ ├── BigIntegerHelperSpec.groovy │ │ │ │ ├── ByteHelperSpec.groovy │ │ │ │ ├── DoubleHelperSpec.groovy │ │ │ │ ├── FloatHelperSpec.groovy │ │ │ │ ├── IntegerHelperSpec.groovy │ │ │ │ ├── LongHelperSpec.groovy │ │ │ │ ├── RationalNumberHelperSpec.groovy │ │ │ │ └── ShortHelperSpec.groovy │ │ └── unitconverter │ │ │ ├── AbstractConverterSpec.groovy │ │ │ ├── AddConverterSpec.groovy │ │ │ ├── ConverterTestUtils.groovy │ │ │ ├── DoubleMultiplyConverterSpec.groovy │ │ │ ├── ExpConverterSpec.groovy │ │ │ ├── IdentityMultiplyConverterSpec.groovy │ │ │ ├── LogConverterSpec.groovy │ │ │ ├── MultiplyConverterSpec.groovy │ │ │ ├── PowerOfPiConverterSpec.groovy │ │ │ └── RationalNumberSpec.groovy │ │ ├── general │ │ ├── AbstractUnitSpec.groovy │ │ └── AnnotatedUnitSpec.groovy │ │ ├── io │ │ └── DefaultQuantityReaderSpec.groovy │ │ ├── math │ │ └── QuantityMathSpec.groovy │ │ ├── quantities │ │ ├── AbstractQuantitySpec.groovy │ │ └── NumberQuantitySpec.groovy │ │ ├── service │ │ ├── UnitsApiServiceSpec.groovy │ │ └── testdata │ │ │ ├── DummySystemOfUnits.groovy │ │ │ └── DummyUnit.groovy │ │ └── units │ │ ├── binary │ │ └── bytes │ │ │ └── ByteSpec.groovy │ │ ├── general │ │ ├── BaseUnitSpec.groovy │ │ └── ProductUnitSpec.groovy │ │ └── si │ │ ├── SISystemSpec.groovy │ │ ├── SISystemUnitsConstantsSpec.groovy │ │ ├── length │ │ └── MetreSpec.groovy │ │ └── temperature │ │ └── CelsiusSpec.groovy │ └── resources │ └── META-INF │ └── services │ └── javax.measure.spi.SystemOfUnits ├── unit-api-jackson ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── raynigon │ │ └── unit │ │ └── api │ │ └── jackson │ │ ├── UnitApiModule.java │ │ ├── annotation │ │ ├── JsonQuantityHelper.java │ │ ├── JsonQuantityReader.java │ │ ├── JsonQuantityWriter.java │ │ ├── JsonUnit.java │ │ └── JsonUnitHelper.java │ │ ├── config │ │ ├── UnitApiConfig.java │ │ └── UnitApiFeature.java │ │ ├── deserializer │ │ ├── QuantityDeserializer.java │ │ └── extractor │ │ │ ├── NumberExtractor.java │ │ │ ├── ObjectExtractor.java │ │ │ └── StringExtractor.java │ │ ├── exception │ │ ├── IncompatibleUnitException.java │ │ ├── InitializationException.java │ │ ├── MissingUnitException.java │ │ └── UnknownUnitException.java │ │ └── serializer │ │ └── QuantitySerializer.java │ └── test │ └── groovy │ └── com │ └── raynigon │ └── unit │ └── api │ └── jackson │ ├── UnitApiModuleSpec.groovy │ ├── annotation │ ├── JsonQuantityHelperSpec.groovy │ └── JsonUnitHelperSpec.groovy │ ├── config │ └── UnitApiFeatureSpec.groovy │ ├── deserializer │ ├── QuantityDeserializerSpec.groovy │ └── extractor │ │ ├── NumberExtractorSpec.groovy │ │ ├── ObjectExtractorSpec.groovy │ │ └── StringExtractorSpec.groovy │ ├── exception │ └── UnitExceptionSpec.groovy │ ├── helpers │ ├── BasicEntity.groovy │ ├── DummyContext.groovy │ ├── DummyQuantityWriter.groovy │ └── ExampleEntity.groovy │ └── serializer │ └── QuantitySerializerSpec.groovy ├── unit-api-kotlin ├── build.gradle.kts └── src │ ├── main │ └── kotlin │ │ └── com │ │ └── raynigon │ │ └── unit │ │ └── api │ │ └── kotlin │ │ ├── DurationExtension.kt │ │ ├── Geometry.kt │ │ ├── QuantityExtension.kt │ │ ├── QuantityOperators.kt │ │ └── RangeOperators.kt │ └── test │ └── kotlin │ └── com │ └── raynigon │ └── unit │ └── api │ └── kotlin │ ├── DurationExtensionTest.kt │ ├── GeometryTest.kt │ ├── QuantityExtensionTest.kt │ ├── QuantityOperatorsTest.kt │ └── RangeOperatorsTest.kt └── unit-api-validation ├── build.gradle └── src ├── main ├── java │ └── com │ │ └── raynigon │ │ └── unit │ │ └── api │ │ └── validation │ │ ├── annotation │ │ ├── UnitMax.java │ │ └── UnitMin.java │ │ └── validator │ │ ├── AbstractUnitValidator.java │ │ ├── UnitMaxValidator.java │ │ └── UnitMinValidator.java └── resources │ └── ValidationMessages.properties └── test └── groovy └── com └── raynigon └── unit └── api └── validation └── validator ├── UnitMaxValidatorSpec.groovy └── UnitMinValidatorSpec.groovy /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Additional context** 24 | Add any other context about the problem here. 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Basic set up for gradle package manager 2 | version: 2 3 | updates: 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "daily" 8 | - package-ecosystem: "gradle" 9 | directory: "/" 10 | schedule: 11 | interval: "daily" 12 | - package-ecosystem: "gradle" 13 | directory: "/spring-boot-core-starter/" 14 | schedule: 15 | interval: "daily" 16 | - package-ecosystem: "gradle" 17 | directory: "/spring-boot-jackson-starter/" 18 | schedule: 19 | interval: "daily" 20 | - package-ecosystem: "gradle" 21 | directory: "/spring-boot-jpa-starter/" 22 | schedule: 23 | interval: "daily" 24 | - package-ecosystem: "gradle" 25 | directory: "/spring-boot-springdoc-starter/" 26 | schedule: 27 | interval: "daily" 28 | - package-ecosystem: "gradle" 29 | directory: "/unit-api-core/" 30 | schedule: 31 | interval: "daily" 32 | - package-ecosystem: "gradle" 33 | directory: "/unit-api-jackson/" 34 | schedule: 35 | interval: "daily" 36 | - package-ecosystem: "gradle" 37 | directory: "/unit-api-kotlin/" 38 | schedule: 39 | interval: "daily" 40 | -------------------------------------------------------------------------------- /.github/mergify.yml: -------------------------------------------------------------------------------- 1 | pull_request_rules: 2 | - name: dependabot 3 | conditions: 4 | - and: 5 | - -draft 6 | - base=main 7 | - -closed 8 | - -conflict 9 | - label=dependencies 10 | - author=dependabot[bot] 11 | - check-success=javadoc 12 | - check-success=test 13 | actions: 14 | merge: 15 | method: merge 16 | -------------------------------------------------------------------------------- /.github/pr-branch-labeler.yml: -------------------------------------------------------------------------------- 1 | # Apply label "feature" if head matches "feature/*" 2 | feature: 3 | head: "feature/*" 4 | 5 | bug: 6 | head: "bugfix/*" 7 | 8 | housekeeping: 9 | head: "housekeeping/*" 10 | 11 | documentation: 12 | head: "docs/*" 13 | -------------------------------------------------------------------------------- /.github/workflows/ci-codacy-analysis.yaml: -------------------------------------------------------------------------------- 1 | name: CI - Codacy 2 | 3 | on: [ "push" ] 4 | 5 | jobs: 6 | codacy-analysis-cli: 7 | if: github.actor != 'dependabot[bot]' 8 | name: Codacy Analysis CLI 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout code 12 | uses: actions/checkout@v4 13 | 14 | - name: Create build folder 15 | run: mkdir -p build/ 16 | 17 | - name: Run Codacy Analysis CLI 18 | uses: codacy/codacy-analysis-cli-action@master 19 | with: 20 | project-token: ${{ secrets.CODACY_TOKEN }} 21 | upload: true 22 | max-allowed-issues: 2147483647 23 | output: build/results.sarif 24 | format: sarif 25 | 26 | - name: Upload SARIF results file 27 | uses: github/codeql-action/upload-sarif@main 28 | with: 29 | sarif_file: build/results.sarif -------------------------------------------------------------------------------- /.github/workflows/ci-main.yml: -------------------------------------------------------------------------------- 1 | name: CI - Main 2 | on: 3 | push: 4 | branches: [ main ] 5 | 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | - name: "Setup Java JDK" 12 | uses: actions/setup-java@v3.13.0 13 | with: 14 | java-version: 17 15 | distribution: adopt 16 | - name: Unit Tests 17 | uses: eskatos/gradle-command-action@d1b726d8c1e0cc120447ad1a950d6e6794c51ad8 18 | with: 19 | arguments: test 20 | - name: Codacy Publish 21 | uses: codacy/codacy-coverage-reporter-action@master 22 | with: 23 | project-token: ${{ secrets.CODACY_TOKEN }} 24 | 25 | javadoc: 26 | runs-on: ubuntu-latest 27 | if: github.ref == 'refs/heads/main' || contains(github.ref, 'refs/tags/') 28 | steps: 29 | - uses: actions/checkout@v4 30 | - name: "Setup Java JDK" 31 | uses: actions/setup-java@v3.13.0 32 | with: 33 | java-version: 17 34 | distribution: adopt 35 | - name: Generate javadoc 36 | uses: eskatos/gradle-command-action@d1b726d8c1e0cc120447ad1a950d6e6794c51ad8 37 | with: 38 | arguments: globalJavadoc 39 | - name: Upload javadoc 40 | uses: sebastianpopp/ftp-action@releases/v2 41 | with: 42 | host: ${{ secrets.WEBSPACE_HOST }} 43 | user: ${{ secrets.WEBSPACE_USER }} 44 | password: ${{ secrets.WEBSPACE_PASSWORD }} 45 | localDir: "build/javadoc/" 46 | remoteDir: "javadoc/" 47 | 48 | documentation: 49 | runs-on: ubuntu-latest 50 | if: github.ref == 'refs/heads/main' || contains(github.ref, 'refs/tags/') 51 | steps: 52 | - uses: actions/checkout@v4 53 | - uses: actions/setup-python@v4 54 | with: 55 | python-version: '3.10' 56 | - run: pip3 install -r requirements.txt 57 | - run: mkdocs build -d build/site/ 58 | - name: Upload documentation 59 | uses: sebastianpopp/ftp-action@releases/v2 60 | with: 61 | host: ${{ secrets.WEBSPACE_HOST }} 62 | user: ${{ secrets.WEBSPACE_USER }} 63 | password: ${{ secrets.WEBSPACE_PASSWORD }} 64 | localDir: "build/site/" 65 | remoteDir: "." 66 | -------------------------------------------------------------------------------- /.github/workflows/labeler.yml: -------------------------------------------------------------------------------- 1 | name: "PR Labeler" 2 | on: 3 | pull_request_target: 4 | types: [ opened ] 5 | 6 | jobs: 7 | triage: 8 | permissions: 9 | contents: read 10 | pull-requests: write 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: ffittschen/pr-branch-labeler@v1 14 | with: 15 | repo-token: ${{ secrets.GITHUB_TOKEN }} 16 | -------------------------------------------------------------------------------- /.github/workflows/update-gradle-wrapper.yml: -------------------------------------------------------------------------------- 1 | name: Update Gradle Wrapper 2 | 3 | on: 4 | workflow_dispatch: { } 5 | schedule: 6 | - cron: "0 0 * * *" 7 | 8 | permissions: 9 | contents: read 10 | 11 | jobs: 12 | update-gradle-wrapper: 13 | permissions: 14 | contents: write # for gradle-update/update-gradle-wrapper-action 15 | pull-requests: write # for gradle-update/update-gradle-wrapper-action 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | - uses: actions/setup-java@v4.2.2 21 | with: 22 | java-version: 21 23 | distribution: adopt 24 | - name: Update Gradle Wrapper 25 | uses: gradle-update/update-gradle-wrapper-action@v1 26 | with: 27 | repo-token: ${{ secrets.GITHUB_TOKEN }} 28 | labels: dependencies 29 | - uses: gradle/wrapper-validation-action@v1 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | 25 | # Gradle 26 | .gradle 27 | 28 | build/ 29 | 30 | # editor 31 | .idea 32 | 33 | # Codespaces 34 | pythonenv* -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution 2 | 3 | * Star the project on [Github](https://github.com/raynigon/unit-api) and help spread the word :) 4 | * [Post an issue](https://github.com/raynigon/unit-api/issues) if you find any bugs 5 | * Contribute improvements or fixes using a [Pull Request](https://github.com/raynigon/unit-api/pulls). 6 | If you're going to contribute, thank you! Please just be sure to: 7 | * discuss with the authors on an issue ticket prior to doing anything big. 8 | * follow the style, naming and structure conventions of the rest of the project. 9 | * make commits atomic and easy to merge. 10 | * verify all tests are passing. Build the project with `./gradlew check` to do this. 11 | **N.B.** Gradle's Build Cache is enabled by default, but you can add `--no-build-cache` flag to disable it. 12 | 13 | ## Contributors 14 | The Icon was designed by [Flatart](https://www.iconfinder.com/Flatart). 15 | 16 | The list of all [Contributors](https://github.com/raynigon/unit-api/graphs/contributors) can be found on [Github](https://github.com/raynigon/unit-api/graphs/contributors). 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # unit-api 2 | 3 | ![CI](https://github.com/raynigon/unit-api/workflows/CI%20-%20Main/badge.svg) 4 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/05af413562694d6ba3b3a923d86da210)](https://app.codacy.com/gh/raynigon/unit-api/dashboard) 5 | [![Codacy Badge](https://app.codacy.com/project/badge/Coverage/16680694f7a84aab8246e4a7f57b06f3)](https://app.codacy.com/gh/raynigon/unit-api/dashboard) 6 | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.raynigon.unit-api/unit-api-kotlin/badge.svg)](https://search.maven.org/search?q=com.raynigon.unit-api) 7 | 8 | Implementation of [JSR-385](https://www.jcp.org/en/jsr/detail?id=385) with focus on the SI System redefinition, 9 | modularity and support for Java 17 and above. 10 | Integration in various Frameworks, Libraries and Languages, such as Spring Boot, Hibernate, Jackson, Kotlin and more. 11 | 12 | 13 | 14 | The unit-api logo.The image shows a measurement tool with scales on all sites 15 | 16 | 17 | ## [Read the documentation here](http://unit-api.raynigon.com) 18 | 19 | ## Unit API Core 20 | 21 | The code in the "unit-api-core" module was copied 22 | from [Unit of Measurement API](https://unitsofmeasurement.github.io/unit-api/) 23 | and adapted to be used in this project. 24 | 25 | ## License 26 | 27 | [Apache License 2.0](LICENSE) 28 | 29 | ## Copyright 30 | 31 | Copyright (c) 2021 Simon Schneider and other authors. 32 | 33 | See [contributors](https://github.com/raynigon/unit-api/graphs/contributors) for all contributors. 34 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | | Version | Supported | 6 | | ------- | ------------------ | 7 | | 1.1.x | :white_check_mark: | 8 | | 1.0.x | :x: | 9 | 10 | ## Reporting a Vulnerability 11 | 12 | Open a Github Issue [here](https://github.com/raynigon/unit-api). 13 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | } 5 | } 6 | 7 | plugins { 8 | // Auto Update Versions 9 | id 'se.patrikerdes.use-latest-versions' version '0.2.18' 10 | id 'com.github.ben-manes.versions' version '0.52.0' 11 | 12 | id 'maven-publish' 13 | id "net.researchgate.release" version "3.1.0" 14 | } 15 | 16 | evaluationDependsOnChildren() 17 | 18 | allprojects { 19 | group = 'com.raynigon.unit-api' 20 | } 21 | 22 | release { 23 | preTagCommitMessage = "[Release] Version:" 24 | tagCommitMessage = "[Release] Version:" 25 | newVersionCommitMessage = "[Release] Update Version:" 26 | tagTemplate = 'v${version}' 27 | buildTasks = ['publish'] 28 | 29 | git { 30 | requireBranch.set("release") 31 | } 32 | } 33 | 34 | def updateMkdocsConfig = tasks.register("updateMkdocsConfig") { 35 | doFirst { 36 | def cfg = project.file(project.file('mkdocs.yml')) 37 | cfg.text = cfg.text.replaceAll(/(?m)latest_version:.*/, "latest_version: ${project.version}") 38 | } 39 | } 40 | 41 | tasks.named("afterReleaseBuild").configure { 42 | dependsOn( 43 | subprojects.collect { it.tasks.named("publish") }, 44 | updateMkdocsConfig 45 | ) 46 | } 47 | -------------------------------------------------------------------------------- /buildSrc/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | `kotlin-dsl` 3 | } 4 | 5 | repositories { 6 | mavenCentral() 7 | maven { 8 | url = uri("https://plugins.gradle.org/m2/") 9 | } 10 | } 11 | 12 | dependencies { 13 | implementation("io.spring.gradle:dependency-management-plugin:1.1.7") 14 | implementation("com.github.spotbugs.snom:spotbugs-gradle-plugin:6.0.1") 15 | implementation("org.owasp:dependency-check-gradle:10.0.3") 16 | 17 | implementation("org.springframework.boot:spring-boot-gradle-plugin:3.5.0") 18 | } -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/unit-api.java-conventions.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.gradle.kotlin.dsl.withType 2 | import org.owasp.dependencycheck.reporting.ReportGenerator.Format 3 | 4 | plugins { 5 | java 6 | `java-library` 7 | id("io.spring.dependency-management") 8 | 9 | checkstyle 10 | pmd 11 | id("com.github.spotbugs") 12 | id("org.owasp.dependencycheck") 13 | 14 | id("unit-api.version-class") 15 | id("unit-api.javadoc") 16 | id("unit-api.test") 17 | id("unit-api.publishing") 18 | } 19 | 20 | repositories { 21 | mavenCentral() 22 | } 23 | 24 | java { 25 | toolchain { 26 | languageVersion = JavaLanguageVersion.of(17) 27 | } 28 | } 29 | 30 | tasks.withType().configureEach { 31 | configFile = File(rootProject.projectDir, "gradle/config/checkstyle.xml") 32 | reports { 33 | xml.required = true 34 | html.required = true 35 | } 36 | } 37 | 38 | pmd { 39 | isConsoleOutput = true 40 | isIgnoreFailures = true 41 | toolVersion = "6.41.0" 42 | rulesMinimumPriority = 3 43 | } 44 | 45 | spotbugs { 46 | ignoreFailures = true 47 | } 48 | 49 | dependencyCheck { 50 | autoUpdate = false 51 | skipTestGroups = true 52 | suppressionFile = "${parent!!.projectDir}/gradle/config/dependency-check-suppression.xml" 53 | formats = listOf(Format.JSON.toString(), Format.HTML.toString()) 54 | 55 | analyzers.nodeEnabled = false 56 | analyzers.nuspecEnabled = false 57 | analyzers.nugetconfEnabled = false 58 | analyzers.assemblyEnabled = false 59 | analyzers.retirejs.enabled = false 60 | } 61 | 62 | dependencies { 63 | compileOnly("org.projectlombok:lombok:1.18.32") 64 | api("javax.measure:unit-api:2.2") 65 | api("org.apache.commons:commons-lang3:3.14.0") 66 | api("org.slf4j:slf4j-api:2.0.13") 67 | api("org.jetbrains:annotations:24.1.0") 68 | annotationProcessor("org.projectlombok:lombok:1.18.32") 69 | } -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/unit-api.javadoc.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | } 4 | 5 | tasks.javadoc { 6 | // options.addBooleanOption('html5', true) 7 | } 8 | 9 | tasks.register("globalJavadoc") { 10 | dependsOn(tasks.javadoc) 11 | group = "documentation" 12 | val branchName = (System.getenv("GITHUB_REF") ?: "refs/heads/master").split("/")[2] 13 | from(layout.buildDirectory.dir("docs/javadoc")) 14 | into(parent!!.layout.buildDirectory.dir("javadoc/$branchName/${project.name}")) 15 | } 16 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/unit-api.publishing.gradle.kts: -------------------------------------------------------------------------------- 1 | import groovy.util.Node 2 | import groovy.util.NodeList 3 | 4 | plugins { 5 | `java-library` 6 | `maven-publish` 7 | signing 8 | } 9 | 10 | java { 11 | withJavadocJar() 12 | withSourcesJar() 13 | } 14 | 15 | signing { 16 | val signingKey = findProperty("signingKey").toString() 17 | val signingPassword = findProperty("signingPassword").toString() 18 | useInMemoryPgpKeys(signingKey, signingPassword) 19 | sign(publishing.publications) 20 | } 21 | 22 | publishing { 23 | repositories { 24 | maven { 25 | name = "OSSRH" // OSS Repository Hosting 26 | url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") 27 | credentials { 28 | username = System.getenv("OSSRH_USERNAME") ?: null 29 | password = System.getenv("OSSRH_PASSWORD") ?: null 30 | } 31 | 32 | } 33 | } 34 | publications { 35 | create("maven") { 36 | artifactId = project.name 37 | from(components["java"]) 38 | 39 | pom { 40 | name = project.name 41 | description = "The ${project.name} is a part of the unit-api" 42 | url = "https://unit-api.raynigon.com/" 43 | issueManagement { 44 | system = "GitHub" 45 | url = "https://github.com/raynigon/unit-api/issues" 46 | } 47 | licenses { 48 | license { 49 | name = "Apache-2.0" 50 | url = "https://opensource.org/licenses/Apache-2.0" 51 | } 52 | } 53 | scm { 54 | url = "https://github.com/raynigon/unit-api/" 55 | connection = "scm:git:git://github.com/raynigon/unit-api.git" 56 | developerConnection = "scm:git:ssh://git@github.com/raynigon/unit-api.git" 57 | } 58 | developers { 59 | developer { 60 | id = "raynigon" 61 | name = "Simon Schneider" 62 | email = "opensource@raynigon.de" 63 | } 64 | } 65 | } 66 | pom.withXml { 67 | val rootNode = asNode() 68 | rootNode.remove((rootNode.get("dependencyManagement") as NodeList)[0] as Node) 69 | } 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/unit-api.spring-conventions.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.springframework.boot.gradle.tasks.bundling.BootJar 2 | 3 | plugins { 4 | id("unit-api.java-conventions") 5 | 6 | id("org.springframework.boot") 7 | } 8 | 9 | tasks.named("bootJar") { 10 | enabled = false 11 | } 12 | 13 | dependencies { 14 | compileOnly("org.springframework.boot:spring-boot-starter") 15 | compileOnly("org.springframework:spring-context-support") 16 | compileOnly("org.springframework.boot:spring-boot-autoconfigure") 17 | annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") 18 | 19 | testImplementation("org.springframework.boot:spring-boot-starter") 20 | testImplementation("org.springframework:spring-context-support") 21 | testImplementation("org.springframework.boot:spring-boot-autoconfigure") 22 | testImplementation("org.springframework.boot:spring-boot-starter-test") { 23 | exclude(group = "org.junit.vintage", module = "junit-vintage-engine") 24 | } 25 | testImplementation("org.spockframework:spock-spring:2.4-M4-groovy-4.0") 26 | } -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/unit-api.test.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | groovy 4 | jacoco 5 | } 6 | 7 | tasks.test { 8 | useJUnitPlatform() 9 | finalizedBy(tasks.jacocoTestReport) // report is always generated after tests run 10 | } 11 | 12 | tasks.jacocoTestReport { 13 | dependsOn(tasks.test) // tests are required to run before generating the report 14 | reports { 15 | xml.required = true 16 | html.required = true 17 | csv.required = false 18 | } 19 | } 20 | 21 | dependencies { 22 | testCompileOnly("org.projectlombok:lombok:1.18.32") 23 | testImplementation("org.apache.groovy:groovy:4.0.21") 24 | testImplementation("org.spockframework:spock-core:2.4-M4-groovy-4.0") 25 | testRuntimeOnly("net.bytebuddy:byte-buddy:1.14.13") 26 | testAnnotationProcessor("org.projectlombok:lombok:1.18.32") 27 | } -------------------------------------------------------------------------------- /docs/_dep/modules/jackson-starter.md: -------------------------------------------------------------------------------- 1 | # Jackson Starter 2 | 3 | The Jackson Starter provides a convenient wrapper around the [Jackson Module](/modules/jackson-module) 4 | 5 | ## Project Dependencies 6 | 7 | Add the following dependency to your pom.xml/build.gradle file: 8 | 9 | === "Gradle" 10 | ```groovy 11 | implementation("com.raynigon.unit-api:jackson-starter:{{latest_version}}") 12 | ``` 13 | === "Maven" 14 | ```xml 15 | 16 | com.raynigon.unit-api 17 | jackson-starter 18 | {{latest_version}} 19 | 20 | ``` 21 | 22 | ## Configuration 23 | 24 | The Unit-Api Jackson Starter can be configured with Spring Configuration. The root key is `spring.jackson.unit-api`. 25 | 26 | ### Options 27 | 28 | | Key | Values | Description | 29 | | :----------------------------------------------------------------- |:-----------:| ----------: | 30 | | spring.jackson.unit-api.features.SYSTEM_UNIT_ON_MISSING_ANNOTATION | true, false | If no Annotation is present and the given input is a number, the system unit for this quantity should be used. | 31 | 32 | ### Usage 33 | 34 | To enable the `SYSTEM_UNIT_ON_MISSING_ANNOTATION` feature add the following line in your `application.properties`: 35 | 36 | ``` 37 | spring.jackson.unit-api.features.SYSTEM_UNIT_ON_MISSING_ANNOTATION=true 38 | ``` -------------------------------------------------------------------------------- /docs/_dep/modules/jpa-starter.md: -------------------------------------------------------------------------------- 1 | # JPA Starter 2 | ## Project Dependencies 3 | 4 | Add the following dependency to your pom.xml/build.gradle file: 5 | 6 | === "Gradle" 7 | ```groovy 8 | implementation("com.raynigon.unit-api:jpa-starter:{{latest_version}}") 9 | ``` 10 | === "Maven" 11 | ```xml 12 | 13 | com.raynigon.unit-api 14 | jpa-starter 15 | {{latest_version}} 16 | 17 | ``` -------------------------------------------------------------------------------- /docs/_dep/modules/springdoc-starter.md: -------------------------------------------------------------------------------- 1 | # Springdoc Starter 2 | ## Project Dependencies 3 | 4 | Add the following dependency to your pom.xml/build.gradle file: 5 | 6 | === "Gradle" 7 | ```groovy 8 | implementation("com.raynigon.unit-api:springdoc-starter:{{latest_version}}") 9 | ``` 10 | === "Maven" 11 | ```xml 12 | 13 | com.raynigon.unit-api 14 | springdoc-starter 15 | {{latest_version}} 16 | 17 | ``` -------------------------------------------------------------------------------- /docs/_dep/quickstart/jackson.md: -------------------------------------------------------------------------------- 1 | # Quickstart - Jackson 2 | 3 | ## Project Dependencies 4 | To use the unit-api with Jackson you need to include 5 | the following dependencies to your pom.xml/build.gradle file: 6 | 7 | === "Gradle" 8 | ```groovy 9 | implementation("com.raynigon.unit-api:jackson-module:{{latest_version}}") 10 | ``` 11 | === "Maven" 12 | ```xml 13 | 14 | com.raynigon.unit-api 15 | jackson-module 16 | {{latest_version}} 17 | 18 | ``` 19 | 20 | ## Usage 21 | 22 | You can declare your model like this: 23 | ```java 24 | public class BasicEntity { 25 | 26 | public String id; 27 | 28 | @JsonUnit(KilometrePerHour.class) 29 | public Quantity speed; 30 | } 31 | ``` 32 | 33 | Jackson will now accept any quantity and convert it to the given unit. 34 | The following examples will be accepted by Jackson: 35 | 36 | === "Number" 37 | ```json 38 | { 39 | "id": "65bf1872-d197-4d72-9950-2b7b4d74a674", 40 | "speed": 80 41 | } 42 | ``` 43 | === "String" 44 | ```json 45 | { 46 | "id": "65bf1872-d197-4d72-9950-2b7b4d74a674", 47 | "speed": "80" 48 | } 49 | ``` 50 | === "Object" 51 | ```json 52 | { 53 | "id": "65bf1872-d197-4d72-9950-2b7b4d74a674", 54 | "speed": { 55 | "value:" 80, 56 | "unit": "km/h" 57 | } 58 | } 59 | ``` 60 | === "String in km/h" 61 | ```json 62 | { 63 | "id": "65bf1872-d197-4d72-9950-2b7b4d74a674", 64 | "speed": "80 km/h" 65 | } 66 | ``` 67 | === "String in m/s" 68 | ```json 69 | { 70 | "id": "65bf1872-d197-4d72-9950-2b7b4d74a674", 71 | "speed": "22.2222 m/s" 72 | } 73 | ``` 74 | Every example will result in having the speed property with a value of 80 and the unit "km/h". 75 | -------------------------------------------------------------------------------- /docs/assets/logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raynigon/unit-api/5e87657b25827437dd869a56ce8539f9517a5c20/docs/assets/logo.ico -------------------------------------------------------------------------------- /docs/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raynigon/unit-api/5e87657b25827437dd869a56ce8539f9517a5c20/docs/assets/logo.png -------------------------------------------------------------------------------- /docs/assets/springdoc/springdoc-properties.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raynigon/unit-api/5e87657b25827437dd869a56ce8539f9517a5c20/docs/assets/springdoc/springdoc-properties.png -------------------------------------------------------------------------------- /docs/contribution.md: -------------------------------------------------------------------------------- 1 | # Contribution 2 | 3 | * Star the project on [Github](https://github.com/raynigon/unit-api) and help spread the word :) 4 | * [Post an issue](https://github.com/raynigon/unit-api/issues) if you find any bugs 5 | * Contribute improvements or fixes using a [Pull Request](https://github.com/raynigon/unit-api/pulls). 6 | If you're going to contribute, thank you! Please just be sure to: 7 | * discuss with the authors on an issue ticket prior to doing anything big. 8 | * follow the style, naming and structure conventions of the rest of the project. 9 | * make commits atomic and easy to merge. 10 | * verify all tests are passing. Build the project with `./gradlew check` to do this. 11 | **N.B.** Gradle's Build Cache is enabled by default, but you can add `--no-build-cache` flag to disable it. 12 | 13 | ## Contributors 14 | The Icon was designed by [Flatart](https://www.iconfinder.com/Flatart). 15 | 16 | The list of all [Contributors](https://github.com/raynigon/unit-api/graphs/contributors) can be found on [Github](https://github.com/raynigon/unit-api/graphs/contributors). 17 | -------------------------------------------------------------------------------- /docs/examples.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | The following List contains practical examples for the usage of the Unit Api. If you find a good example, feel free to 4 | create a PR and link it here. 5 | 6 | ## Spring Boot - Groundstation 7 | 8 | **Link:** https://github.com/raynigon/unit-api-example 9 | 10 | ### Summary 11 | 12 | This project contains a hypothetical backend for receiving telemetry data from a satellite. The backend is designed for 13 | the Mars Climate Orbiter. If you want to know more, about how te JSR-385 could have saved the Mars Climate Orbiter check 14 | out [this](https://www.slideshare.net/filipvanlaenen/how-jsr-385-could-have-saved-the-mars-climate-orbiter-138213660) 15 | Talk from [Filip Van Laenen](https://github.com/filipvanlaenen). 16 | 17 | ### Technologies 18 | 19 | * Spring Boot 20 | * Jackson 21 | * Jpa 22 | * Kotlin 23 | 24 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # Unit API 2 | 3 | ![](assets/logo.png) 4 | 5 | ## About 6 | 7 | The (Raynigon) Unit API provides an Implementation of [JSR-385](https://www.jcp.org/en/jsr/detail?id=385) 8 | with focus on the SI System redefinition, modularity and support for Java SE 17 and above. 9 | It integrates into various Frameworks, Libraries and Languages, such as Spring Boot, Hibernate, Jackson, Kotlin and more. 10 | Spring Boot integrations are available as "-starter" modules. 11 | The Spring Boot Starter modules will allow you to use the unit-api directly in Spring Boot without configuration. 12 | You can also use the Jackson Module, Kotlin Module for non Spring boot Use cases. 13 | 14 | ## Unit of Measurement API 15 | 16 | The majority of the code in this library originates from the [Unit of Measurement API](https://unitsofmeasurement.github.io/unit-api/). 17 | The new code enables better integration into Frameworks, Libraries and Languages. 18 | 19 | ## Maven dependencies 20 | 21 | Unit API is distributed as separate JARs with a common version number: 22 | 23 | * A core JAR file for core functionality 24 | * A separate JAR file for each of the specialised modules. 25 | Each module's documentation describes the Maven/Gradle dependency to add to your project's build. 26 | 27 | The most commonly used modules are explained in the quick start sections: 28 | 29 | * [Spring Boot](/quickstart/spring-boot) 30 | * [Jackson Standalone](/quickstart/jackson) 31 | 32 | ## Kotlin Support 33 | 34 | There is a module which adds support for Kotlin operators: 35 | 36 | * [Kotlin](/modules/kotlin-module) -------------------------------------------------------------------------------- /docs/javadoc-ref.md: -------------------------------------------------------------------------------- 1 | # JavaDoc 2 | 3 | Current Javadocs are provided [here](https://unit-api.raynigon.com/javadoc/main/). 4 | 5 | ## Modules 6 | - [unit-api-core](https://unit-api.raynigon.com/javadoc/main/unit-api-core/) 7 | - [unit-api-jackson](https://unit-api.raynigon.com/javadoc/main/unit-api-jackson/) 8 | - [unit-api-kotlin](https://unit-api.raynigon.com/javadoc/main/unit-api-kotlin/) 9 | - [spring-boot-core-starter](https://unit-api.raynigon.com/javadoc/main/spring-boot-core-starter/) 10 | - [spring-boot-jackson-starter](https://unit-api.raynigon.com/javadoc/main/spring-boot-jackson-starter/) 11 | - [spring-boot-jpa-starter](https://unit-api.raynigon.com/javadoc/main/spring-boot-jpa-starter/) 12 | - [spring-boot-springdoc-starter](https://unit-api.raynigon.com/javadoc/main/spring-boot-springdoc-starter/) 13 | 14 | 15 | -------------------------------------------------------------------------------- /docs/spring-boot/index.md: -------------------------------------------------------------------------------- 1 | # Quickstart - Spring Boot 2 | 3 | ## Project dependencies 4 | To use the unit-api with Spring Boot you need to include 5 | the following dependencies to your pom.xml/build.gradle file: 6 | 7 | === "Gradle" 8 | ```groovy 9 | implementation("com.raynigon.unit-api:spring-boot-jackson-starter:{{latest_version}}") 10 | implementation("com.raynigon.unit-api:spring-boot-jpa-starter:{{latest_version}}") 11 | implementation("com.raynigon.unit-api:spring-boot-springdoc-starter:{{latest_version}}") 12 | ``` 13 | === "Maven" 14 | ```xml 15 | 16 | com.raynigon.unit-api 17 | spring-boot-jackson-starter 18 | {{latest_version}} 19 | 20 | 21 | com.raynigon.unit-api 22 | spring-boot-jpa-starter 23 | {{latest_version}} 24 | 25 | 26 | com.raynigon.unit-api 27 | spring-boot-springdoc-starter 28 | {{latest_version}} 29 | 30 | ``` 31 | ## Module description 32 | 33 | * The first module provides a convenient wrapper around the [Unit API Jackson Module](/java/jackson/). 34 | * The second module provides [JPA integration](/spring-boot/jpa/) for Hibernate. 35 | * The third module provides enhanced API documentation for Quantity and Unit properties in [Springdoc](/spring-boot/springdoc/). -------------------------------------------------------------------------------- /docs/spring-boot/jackson.md: -------------------------------------------------------------------------------- 1 | # Jackson Starter 2 | 3 | The Jackson Starter provides a convenient wrapper around the [Unit API Jackson Module](/java/jackson/) 4 | 5 | ## Project Dependencies 6 | 7 | Add the following dependency to your pom.xml/build.gradle file: 8 | 9 | === "Gradle" 10 | ```groovy 11 | implementation("com.raynigon.unit-api:spring-boot-jackson-starter:{{latest_version}}") 12 | ``` 13 | === "Maven" 14 | ```xml 15 | 16 | com.raynigon.unit-api 17 | spring-boot-jackson-starter 18 | {{latest_version}} 19 | 20 | ``` 21 | 22 | ## Usage 23 | The starter automatically adds the UnitAPI Jackson module to the default ObjectMapper bean. 24 | If the ObjectMapper bean is created by a custom factory, the module has to be added manually. 25 | All instructions are provided [here](/java/jackson/#usage). 26 | The UnitAPI Jackson module itself is also provided as a bean. 27 | 28 | ## Configuration 29 | 30 | The Unit-Api Jackson Starter can be configured with Spring Configuration. The root key is `spring.jackson.unit-api`. 31 | 32 | ### Options 33 | 34 | | Key | Values | Description | 35 | | :----------------------------------------------------------------- |:-----------:| ----------: | 36 | | spring.jackson.unit-api.features.SYSTEM_UNIT_ON_MISSING_ANNOTATION | true, false | If no Annotation is present and the given input is a number, the system unit for this quantity should be used. | 37 | 38 | ### Example 39 | 40 | To enable the `SYSTEM_UNIT_ON_MISSING_ANNOTATION` feature add the following line in your `application.properties`: 41 | 42 | ``` 43 | spring.jackson.unit-api.features.SYSTEM_UNIT_ON_MISSING_ANNOTATION=true 44 | ``` 45 | -------------------------------------------------------------------------------- /docs/spring-boot/jpa.md: -------------------------------------------------------------------------------- 1 | # Java Persistance API (JPA) 2 | 3 | ## Project Dependencies 4 | 5 | Add the following dependency to your pom.xml/build.gradle file: 6 | 7 | === "Gradle" 8 | ```groovy 9 | implementation("com.raynigon.unit-api:spring-boot-jpa-starter:{{latest_version}}") 10 | ``` 11 | === "Maven" 12 | ```xml 13 | 14 | com.raynigon.unit-api 15 | spring-boot-jpa-starter 16 | {{latest_version}} 17 | 18 | ``` 19 | 20 | ## Limitations 21 | Currently the Raynigon Unit API JPA integration only works for hibernate. 22 | 23 | ## Usage 24 | To use the Raynigon Unit API with JPA, an Entity needs to be created. 25 | This Entity needs to have a `@Type` annotation with a definition for the `QuantityType`. 26 | 27 | !!! warning 28 | You need to have the `@Type` annotation on every Entity due to a missing feature in hibernate 29 | (see [here](https://hibernate.atlassian.net/browse/HHH-11110)). 30 | ```java 31 | @Entity 32 | @Table("basic_entity") 33 | public class BasicEntity { 34 | 35 | @Id 36 | @Column(name="id") 37 | public String id; 38 | 39 | @JpaUnit(KilometrePerHour.class) 40 | @Type(QuantityType.class) 41 | @Column(name="speed") 42 | public Quantity speed; 43 | } 44 | ``` 45 | 46 | Depending on the database you are using, you need to specify the `columnDefinition` property in the `@Column` annotation. 47 | By default, the value stored in the database will be a floating-point value. In this example the value will be saved in "km/h". -------------------------------------------------------------------------------- /docs/spring-boot/springdoc.md: -------------------------------------------------------------------------------- 1 | # Springdoc 2 | 3 | ## Project Dependencies 4 | 5 | Add the following dependency to your pom.xml/build.gradle file: 6 | 7 | === "Gradle" 8 | ```groovy 9 | implementation("com.raynigon.unit-api:spring-boot-springdoc-starter:{{latest_version}}") 10 | ``` 11 | === "Maven" 12 | ```xml 13 | 14 | com.raynigon.unit-api 15 | spring-boot-springdoc-starter 16 | {{latest_version}} 17 | 18 | ``` 19 | 20 | ## Usage 21 | 22 | To view documentation generated from your data model create an Entity which should contain `@JsonUnit` annotations. 23 | This model has then to be used in the controller as either request or response. 24 | 25 | ```kotlin 26 | data class TelemetryRecordRequest( 27 | 28 | @JsonUnit(MilliSecond::class) 29 | val rtt: Quantity