├── .gitattributes ├── .github └── workflows │ ├── maven.yml │ └── release-and-deploy.yml ├── .gitignore ├── .gitmodules ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── pom.xml ├── qudtlib-common-codegen ├── pom.xml └── src │ ├── main │ └── java │ │ └── io │ │ └── github │ │ └── qudtlib │ │ ├── common │ │ ├── BigDecimalFormatterFactory.java │ │ ├── CodeGen.java │ │ └── safenames │ │ │ ├── NameCollisionException.java │ │ │ └── SafeStringMapper.java │ │ └── constgen │ │ └── Constant.java │ └── test │ └── java │ └── io │ └── github │ └── qudtlib │ └── common │ └── CodeGenTest.java ├── qudtlib-common-rdf ├── pom.xml └── src │ └── main │ └── java │ └── io │ └── github │ └── qudtlib │ └── common │ └── RdfOps.java ├── qudtlib-constants-gen ├── pom.xml └── src │ └── main │ ├── java │ └── io │ │ └── github │ │ └── qudtlib │ │ └── constgen │ │ └── ConstantsGenerator.java │ └── resources │ ├── query │ ├── physicalConstants.rq │ ├── prefixes.rq │ ├── quantitykinds.rq │ ├── systems-of-units.rq │ └── units.rq │ └── template │ └── constants.ftl ├── qudtlib-data-gen ├── pom.xml └── src │ └── main │ ├── java │ └── io │ │ └── github │ │ └── qudtlib │ │ └── data │ │ └── DataGenerator.java │ └── resources │ ├── add-to-quantitykinds.ttl │ ├── add-to-units.ttl │ ├── delete-from-quantitykinds-by-query1_dontfind.rq │ ├── delete-from-quantitykinds.ttl │ ├── delete-from-units-by-query1.rq │ ├── delete-from-units-by-query2_dontfind.rq │ ├── delete-from-units.ttl │ ├── delete-kiloGM-scalings.rq │ ├── delete-units.rq │ ├── factorUnit.rq │ ├── isScalingOf.rq │ ├── missing-units.rq │ ├── si-base-units.ttl │ └── tmpExpected │ ├── README.md │ ├── newtriples.ttl │ └── qudt-unit.ttl ├── qudtlib-data └── pom.xml ├── qudtlib-example ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── org │ └── example │ └── qudlib │ └── QudtlibExample.java ├── qudtlib-hardcoded-model-gen ├── pom.xml └── src │ └── main │ ├── java │ └── io │ │ └── github │ │ └── qudtlib │ │ └── HardcodedModelGenerator.java │ └── resources │ └── template │ └── InitializerImpl.ftl ├── qudtlib-ingest-qudt ├── pom.xml └── src │ └── test │ └── resources │ └── query │ ├── README.md │ ├── allPrefixes.rq │ ├── allScalingOf.rq │ ├── isScalingOf-inconsistencies.rq │ ├── missingConversionMultiplier.rq │ ├── missingScalingTriples.rq │ ├── unitDimensionVectors.rq │ └── unitDimensionVectorsMissing.rq ├── qudtlib-init-hardcoded └── pom.xml ├── qudtlib-init-rdf ├── pom.xml └── src │ └── main │ ├── java │ └── io │ │ └── github │ │ └── qudtlib │ │ └── init │ │ └── InitializerImpl.java │ └── resources │ └── qudtlib │ └── query │ ├── constantValue.rq │ ├── factor-units.rq │ ├── physicalConstant.rq │ ├── prefix.rq │ ├── quantitykind.rq │ ├── system-of-units.rq │ └── unit.rq ├── qudtlib-js-gen ├── pom.xml └── src │ └── main │ ├── java │ └── io │ │ └── github │ │ └── qudtlib │ │ └── HardcodedTypescriptModelGenerator.java │ └── resources │ └── template │ └── units.ts.ftl ├── qudtlib-main-rdf ├── pom.xml └── src │ └── test │ └── java │ └── io │ └── github │ └── qudtlib │ └── QudtMainForDebugging.java ├── qudtlib-main ├── pom.xml └── src │ └── main │ └── java │ ├── com │ └── java2s │ │ └── Log10BigDecimal.java │ └── io │ └── github │ └── qudtlib │ ├── Qudt.java │ └── support │ ├── fractional │ ├── FractionalDimensionVector.java │ └── FractionalUnits.java │ ├── index │ ├── Flag.java │ ├── MultivaluePatriciaTrie.java │ └── SearchIndex.java │ └── parse │ ├── AbstractStateTransition.java │ ├── ClosingBracketTransition.java │ ├── DividerTransition.java │ ├── DotTransition.java │ ├── ExponentTransition.java │ ├── OneTransition.java │ ├── OpeningBracketTransition.java │ ├── ParsedUnit.java │ ├── State.java │ ├── StateTransition.java │ ├── UnitParser.java │ ├── UnitTransition.java │ └── WhitespaceTransition.java ├── qudtlib-model ├── pom.xml └── src │ └── main │ └── java │ └── io │ └── github │ └── qudtlib │ ├── algorithm │ └── AssignmentProblem.java │ ├── exception │ ├── IncompleteDataException.java │ ├── InconvertibleQuantitiesException.java │ ├── NonUniqueResultException.java │ ├── NotFoundException.java │ ├── QudtException.java │ └── QudtInitializationException.java │ ├── init │ └── Initializer.java │ ├── math │ └── BigDec.java │ ├── model │ ├── ConstantValue.java │ ├── DerivedUnitSearchMode.java │ ├── DimensionVector.java │ ├── FactorUnit.java │ ├── FactorUnitMatch.java │ ├── FactorUnits.java │ ├── LangString.java │ ├── LangStrings.java │ ├── Namespace.java │ ├── PhysicalConstant.java │ ├── Prefix.java │ ├── Quantity.java │ ├── QuantityKind.java │ ├── QuantityValue.java │ ├── QudtNamespaces.java │ ├── SystemOfUnits.java │ └── Unit.java │ └── nodedef │ ├── Builder.java │ ├── EmptyBuilder.java │ ├── MapBackedNodeDefinition.java │ ├── NodeDefinition.java │ ├── NodeDefinitionBase.java │ ├── SelfSmuggler.java │ ├── SettableBuilder.java │ └── SettableBuilderBase.java ├── qudtlib-test ├── pom.xml └── src │ └── test │ └── java │ └── io │ └── github │ └── qudtlib │ ├── ConstantTests.java │ ├── CurrencyTests.java │ ├── DerivedUnitTests.java │ ├── FactorUnitTests.java │ ├── FactorUnitsTests.java │ ├── NamespaceTests.java │ ├── NumericStabilityTests.java │ ├── QuantityKindTests.java │ ├── QudtTests.java │ ├── SystemOfUnitsTests.java │ └── UnitTests.java ├── qudtlib-tools ├── pom.xml └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── github │ │ │ └── qudtlib │ │ │ ├── QudtEntityAtRuntimeAdder.java │ │ │ └── tools │ │ │ ├── contribute │ │ │ ├── QudtContribution_symbol.java │ │ │ ├── QudtContribution_ucumCode.java │ │ │ ├── QudtEntityGenerator.java │ │ │ ├── Tool.java │ │ │ ├── ToolImpl.java │ │ │ ├── model │ │ │ │ ├── CommonEntityMetadata.java │ │ │ │ ├── MetadataBuilder.java │ │ │ │ ├── QuantityKindForContribution.java │ │ │ │ ├── QuantityKindMetadata.java │ │ │ │ ├── TypedLiteral.java │ │ │ │ ├── UnitForContribution.java │ │ │ │ └── UnitMetadata.java │ │ │ └── support │ │ │ │ ├── ContributionHelper.java │ │ │ │ ├── FormattingHelper.java │ │ │ │ ├── IndentedOutputStream.java │ │ │ │ ├── LabelCombiner.java │ │ │ │ ├── QuantityKindBuilderFacade.java │ │ │ │ ├── SelectionHelper.java │ │ │ │ └── tree │ │ │ │ ├── FormattingNodeVisitor.java │ │ │ │ ├── Node.java │ │ │ │ ├── NodeVisitor.java │ │ │ │ ├── QuantityKindTree.java │ │ │ │ ├── TreeWalker.java │ │ │ │ └── UnitTree.java │ │ │ └── contributions │ │ │ ├── CheckConversionMultipliers.java │ │ │ ├── CheckDimensionVectors.java │ │ │ ├── CheckSymbols.java │ │ │ ├── CheckUcumCode.java │ │ │ ├── GenerateNumericValuesAsXsdDoubleAndXsdDecimal.java │ │ │ ├── GlobalData.java │ │ │ └── archive │ │ │ ├── CheckConversionMultipliers.java │ │ │ ├── CheckConversionMultipliersForScaledUnits.java │ │ │ ├── ContributeCorrectedConversionFactor.java │ │ │ ├── ContributeCorrectedSymbols.java │ │ │ ├── ContributeCorrectedUcumCode.java │ │ │ ├── ContributeFixedPrefixes.java │ │ │ ├── ContributeMissingUcumCode.java │ │ │ ├── ContributeRman.java │ │ │ └── FindFactorsToFix.java │ └── resources │ │ └── contribute │ │ └── contribution-shapes.ttl │ └── test │ └── java │ ├── io │ └── github │ │ └── qudtlib │ │ ├── model │ │ └── DimensionVectorTest.java │ │ └── tools │ │ └── contribute │ │ └── support │ │ └── tree │ │ └── NodeTests.java │ └── some │ └── pkg │ └── QudtContributionExample.java ├── qudtlib-vocab ├── pom.xml └── src │ └── main │ └── java │ └── io │ └── github │ └── qudtlib │ └── vocab │ ├── QUDT.java │ └── QUDTX.java └── qudtlib └── pom.xml /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 3 | 4 | name: Java CI with Maven 5 | 6 | on: 7 | push: 8 | branches: [ "main" ] 9 | pull_request: 10 | branches: [ "main" ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | - name: Set up JDK 17 20 | uses: actions/setup-java@v3 21 | with: 22 | java-version: '17' 23 | distribution: 'temurin' 24 | cache: maven 25 | - name: Build with Maven 26 | run: mvn install 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /**/target/ 2 | /**/pom.xml.tag 3 | /**/pom.xml.releaseBackup 4 | /**/pom.xml.versionsBackup 5 | /**/pom.xml.next 6 | /**/release.properties 7 | /**/dependency-reduced-pom.xml 8 | /**/buildNumber.properties 9 | /**/.mvn/timing.properties 10 | # https://github.com/takari/maven-wrapper#usage-without-binary-jar 11 | /**/.mvn/wrapper/maven-wrapper.jar 12 | 13 | # Eclipse m2e generated files 14 | # Eclipse Core 15 | /**/.project 16 | # JDT-specific (Eclipse Java Development Tools) 17 | /**/.classpath 18 | 19 | # Intellij 20 | /**/.idea/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "qudtlib-js"] 2 | path = qudtlib-js 3 | url = https://github.com/qudtlib/qudtlib-js.git 4 | branch = main -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | If you choose to contribute to this project, BIG THANKS TO YOU! 2 | 3 | ## Issues 4 | 5 | We are very loose about process. If you spot a problem, create an issue. 6 | 7 | ## Pull Requests 8 | 9 | If you fix a bug or want to add code, make a pull request and please make sure to **add tests** for the bug you fix or the feature you add. Test coverage is always an issue, and it's not getting better by having more untested code. Thanks! 10 | 11 | Also, When you make a pull request, please run `mvn install` at the top level to make sure the build succeeds. 12 | 13 | -------------------------------------------------------------------------------- /qudtlib-common-codegen/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | qudtlib-java 5 | io.github.qudtlib 6 | 6.8.2-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | qudtlib-common-codegen 11 | 12 | 13 | 14 | org.freemarker 15 | freemarker 16 | 17 | 18 | org.junit.jupiter 19 | junit-jupiter 20 | 21 | 22 | io.github.qudtlib 23 | qudtlib-model 24 | ${project.version} 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.apache.maven.plugins 32 | maven-deploy-plugin 33 | 34 | true 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /qudtlib-common-codegen/src/main/java/io/github/qudtlib/common/BigDecimalFormatterFactory.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.common; 2 | 3 | import freemarker.core.Environment; 4 | import freemarker.core.TemplateNumberFormat; 5 | import freemarker.core.TemplateNumberFormatFactory; 6 | import freemarker.template.TemplateModelException; 7 | import freemarker.template.TemplateNumberModel; 8 | import java.math.BigDecimal; 9 | import java.util.Locale; 10 | 11 | public class BigDecimalFormatterFactory extends TemplateNumberFormatFactory { 12 | @Override 13 | public TemplateNumberFormat get(String s, Locale locale, Environment environment) { 14 | return new TemplateNumberFormat() { 15 | @Override 16 | public String formatToPlainText(TemplateNumberModel templateNumberModel) 17 | throws TemplateModelException { 18 | Number num = templateNumberModel.getAsNumber(); 19 | if (!(num instanceof BigDecimal)) { 20 | throw new IllegalArgumentException( 21 | "This formatter can only be used with BigDecimals but was asked to format a " 22 | + num.getClass()); 23 | } 24 | BigDecimal bd = (BigDecimal) templateNumberModel.getAsNumber(); 25 | return bd.toString(); 26 | } 27 | 28 | @Override 29 | public boolean isLocaleBound() { 30 | return false; 31 | } 32 | 33 | @Override 34 | public String getDescription() { 35 | return "Number format for BigDecimal using BigDecimal.toString()"; 36 | } 37 | }; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /qudtlib-common-codegen/src/main/java/io/github/qudtlib/common/CodeGen.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.common; 2 | 3 | import freemarker.core.Environment; 4 | import freemarker.template.*; 5 | import io.github.qudtlib.common.safenames.SafeStringMapper; 6 | import io.github.qudtlib.constgen.Constant; 7 | import io.github.qudtlib.model.LangString; 8 | import java.io.File; 9 | import java.io.FileWriter; 10 | import java.io.IOException; 11 | import java.nio.charset.StandardCharsets; 12 | import java.util.Map; 13 | import java.util.Objects; 14 | import java.util.Set; 15 | import java.util.function.Function; 16 | import java.util.regex.Pattern; 17 | 18 | public abstract class CodeGen { 19 | 20 | public static Configuration getFreemarkerConfiguration() { 21 | return getFreemarkerConfiguration(Thread.currentThread().getContextClassLoader()); 22 | } 23 | 24 | public static Configuration getFreemarkerConfiguration(ClassLoader classLoaderForTemplate) { 25 | Objects.requireNonNull(classLoaderForTemplate); 26 | Configuration cfg = new Configuration(Configuration.VERSION_2_3_31); 27 | cfg.setClassLoaderForTemplateLoading(classLoaderForTemplate, "/"); 28 | cfg.setDefaultEncoding("UTF-8"); 29 | cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); 30 | cfg.setCustomNumberFormats(Map.of("toString", new BigDecimalFormatterFactory())); 31 | return cfg; 32 | } 33 | 34 | public static void generateFileFromTemplate( 35 | Configuration config, 36 | String templateFileClasspathUrl, 37 | Map templateVars, 38 | File outFile) 39 | throws IOException, TemplateException { 40 | Template template = config.getTemplate(templateFileClasspathUrl); 41 | FileWriter out = new FileWriter(outFile, StandardCharsets.UTF_8); 42 | Environment env = template.createProcessingEnvironment(templateVars, out); 43 | env.setOutputEncoding(StandardCharsets.UTF_8.toString()); 44 | env.process(); 45 | } 46 | 47 | public static Constant makeConstant( 48 | Set labels, 49 | String iri, 50 | String typeName, 51 | String symbol, 52 | String constantName, 53 | SafeStringMapper constantNameMapper) { 54 | String label = labels.stream().findFirst().map(LangString::getString).orElse("[no label]"); 55 | String iriLocalName = iri.replaceAll("^.+[/|#]", ""); 56 | String codeConstantName = constantNameMapper.applyMapping(constantName); 57 | String valueFactory = 58 | typeName.substring(0, 1).toLowerCase() 59 | + typeName.substring(1) 60 | + "FromLocalnameRequired"; 61 | if (typeName.equals("Unit") && codeConstantName.endsWith("_Currency")) { 62 | valueFactory = "currencyFromLocalnameRequired"; 63 | } 64 | return new Constant( 65 | codeConstantName, iriLocalName, label, iri, typeName, symbol, valueFactory); 66 | } 67 | 68 | public static SafeStringMapper javaConstantMapper() { 69 | return new SafeStringMapper(javaConstantNameMapper); 70 | } 71 | 72 | static final Function javaConstantNameMapper = 73 | constName -> { 74 | Pattern startPattern = Pattern.compile("^[$€a-zA-Z_]"); 75 | if (!startPattern.matcher(constName).lookingAt()) { 76 | constName = "_" + constName; 77 | } 78 | constName = constName.replaceAll("-", "__").replaceAll("\\.", "pt"); 79 | return constName; 80 | }; 81 | } 82 | -------------------------------------------------------------------------------- /qudtlib-common-codegen/src/main/java/io/github/qudtlib/common/safenames/NameCollisionException.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.common.safenames; 2 | 3 | public class NameCollisionException extends RuntimeException { 4 | public NameCollisionException(String collidingInput, String input, String mappedOutput) { 5 | super( 6 | String.format( 7 | "IdentifierCollision detected! Input String '%s' clashes with previously established Mapping '%s' => '%s'", 8 | collidingInput, input, mappedOutput)); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /qudtlib-common-codegen/src/main/java/io/github/qudtlib/common/safenames/SafeStringMapper.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.common.safenames; 2 | 3 | import java.util.Map; 4 | import java.util.Objects; 5 | import java.util.concurrent.ConcurrentHashMap; 6 | import java.util.function.Function; 7 | 8 | /** 9 | * Applies the provided deterministic mappingFunction provided in the 10 | * constructor, keeping track of the mappings produced. If two different inputs result in the same 11 | * output, a {@link NameCollisionException} is thrown. 12 | */ 13 | public class SafeStringMapper { 14 | private final Map outputToInput = new ConcurrentHashMap<>(); 15 | private final Function mappingFunction; 16 | 17 | public SafeStringMapper(Function mappingFunction) { 18 | this.mappingFunction = mappingFunction; 19 | } 20 | 21 | /** 22 | * Applies the specified mapping, throwing an exception if a previously produced output is 23 | * reproduced with a different input. 24 | * 25 | * @param input the value to map safely 26 | * @return the mapped value 27 | */ 28 | public String applyMapping(String input) { 29 | Objects.requireNonNull(input); 30 | final String output = mappingFunction.apply(input); 31 | outputToInput.merge( 32 | output, 33 | input, 34 | (previousInput, currentInput) -> { 35 | if (previousInput.equals(currentInput)) { 36 | return input; 37 | } 38 | throw new NameCollisionException(input, previousInput, output); 39 | }); 40 | return output; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /qudtlib-common-codegen/src/main/java/io/github/qudtlib/constgen/Constant.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.constgen; 2 | 3 | import java.util.Objects; 4 | import java.util.Optional; 5 | 6 | /** 7 | * Class representing constant names/labels/local names in IRIs for generating RDF vocabularies. 8 | * 9 | * @author Florian Kleedorfer 10 | * @since 1.0 11 | */ 12 | public class Constant { 13 | private final String codeConstantName; 14 | private final String iriLocalname; 15 | private final String label; 16 | 17 | private final String iri; 18 | 19 | private final String typeName; 20 | 21 | private final String symbol; 22 | private final String valueFactory; 23 | 24 | public Constant( 25 | String codeConstantName, 26 | String iriLocalname, 27 | String label, 28 | String iri, 29 | String typeName, 30 | String symbol, 31 | String valueFactory) { 32 | Objects.requireNonNull(codeConstantName); 33 | Objects.requireNonNull(iriLocalname); 34 | Objects.requireNonNull(iri); 35 | Objects.requireNonNull(label); 36 | Objects.requireNonNull(typeName); 37 | Objects.requireNonNull(valueFactory); 38 | this.codeConstantName = codeConstantName; 39 | this.iriLocalname = iriLocalname; 40 | this.label = label; 41 | this.iri = iri; 42 | this.typeName = typeName; 43 | this.symbol = symbol; 44 | this.valueFactory = valueFactory; 45 | } 46 | 47 | public String getCodeConstantName() { 48 | return codeConstantName; 49 | } 50 | 51 | public String getIriLocalname() { 52 | return iriLocalname; 53 | } 54 | 55 | public String getLabel() { 56 | return label; 57 | } 58 | 59 | public String getIri() { 60 | return iri; 61 | } 62 | 63 | public String getTypeName() { 64 | return typeName; 65 | } 66 | 67 | public Optional getSymbol() { 68 | return Optional.ofNullable(symbol); 69 | } 70 | 71 | public String getValueFactory() { 72 | return valueFactory; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /qudtlib-common-codegen/src/test/java/io/github/qudtlib/common/CodeGenTest.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.common; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertThrows; 5 | 6 | import io.github.qudtlib.common.safenames.NameCollisionException; 7 | import io.github.qudtlib.common.safenames.SafeStringMapper; 8 | import org.junit.jupiter.api.Test; 9 | 10 | public class CodeGenTest { 11 | @Test 12 | public void testConstantMapper() { 13 | SafeStringMapper mapper = CodeGen.javaConstantMapper(); 14 | assertEquals("_1constant", mapper.applyMapping("1constant")); 15 | assertEquals("_1constant", mapper.applyMapping("1constant")); 16 | assertEquals("_2constant", mapper.applyMapping("2constant")); 17 | assertThrows(NameCollisionException.class, () -> mapper.applyMapping("_1constant")); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /qudtlib-common-rdf/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | qudtlib-java 5 | io.github.qudtlib 6 | 6.8.2-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | qudtlib-common-rdf 11 | 12 | 13 | 14 | org.eclipse.rdf4j 15 | rdf4j-runtime 16 | pom 17 | 18 | 19 | org.eclipse.rdf4j 20 | rdf4j-rio-turtle 21 | 22 | 23 | org.eclipse.rdf4j 24 | rdf4j-rio-api 25 | 26 | 27 | 28 | 29 | 30 | org.apache.maven.plugins 31 | maven-deploy-plugin 32 | 33 | true 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /qudtlib-constants-gen/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | qudtlib-java 5 | io.github.qudtlib 6 | 6.8.2-SNAPSHOT 7 | 8 | 4.0.0 9 | qudtlib-constants-gen 10 | jar 11 | 12 | 13 | 14 | io.github.qudtlib 15 | qudtlib-common-rdf 16 | ${project.version} 17 | 18 | 19 | io.github.qudtlib 20 | qudtlib-common-codegen 21 | ${project.version} 22 | 23 | 24 | io.github.qudtlib 25 | qudtlib-data 26 | ${project.version} 27 | 28 | 29 | 30 | 31 | 32 | org.apache.maven.plugins 33 | maven-deploy-plugin 34 | 35 | true 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /qudtlib-constants-gen/src/main/resources/query/physicalConstants.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | PREFIX constant: 4 | PREFIX rdfs: 5 | 6 | SELECT DISTINCT ?constName ?localName ?label (?qk as ?iri) ("PhysicalConstant" as ?typeName) ?symbol 7 | where 8 | { 9 | ?qk a qudt:PhysicalConstant . 10 | { 11 | select ?qk (MIN(STR(?labelVal)) as ?label) where { 12 | ?qk a qudt:PhysicalConstant . 13 | optional { 14 | ?qk rdfs:label ?labelVal . 15 | FILTER(LANG(?labelVal) = "en") 16 | } 17 | } GROUP BY ?qk ?symbol 18 | } 19 | { 20 | select ?qk (GROUP_CONCAT(STR(?smb); separator=" or ") as ?symbol) where { 21 | ?qk a qudt:PhysicalConstant . 22 | optional { 23 | ?qk qudt:symbol ?smb . 24 | } 25 | } GROUP BY ?qk 26 | } 27 | BIND(REPLACE(STR(?qk), "^.+/", "") as ?localName) 28 | BIND(REPLACE(?localName, "-", "__") as ?constName) 29 | } order by ?qk 30 | -------------------------------------------------------------------------------- /qudtlib-constants-gen/src/main/resources/query/prefixes.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | PREFIX kind: 4 | PREFIX rdfs: 5 | 6 | SELECT DISTINCT ?constName ?localName ?label (?prefix as ?iri) ("Prefix" as ?typeName) ?symbol 7 | where 8 | { 9 | ?prefix a qudt:Prefix . 10 | { 11 | select ?prefix (MIN(STR(?labelVal)) as ?label) where { 12 | ?prefix a qudt:Prefix . 13 | optional { 14 | ?prefix rdfs:label ?labelVal . 15 | FILTER(LANG(?labelVal) = "en") 16 | } 17 | 18 | } GROUP BY ?prefix 19 | } 20 | { 21 | select ?prefix (GROUP_CONCAT(STR(?smb); separator=" or ") as ?symbol) where { 22 | ?prefix a qudt:Prefix . 23 | optional { 24 | ?prefix qudt:symbol ?smb . 25 | } 26 | } GROUP BY ?prefix 27 | } 28 | BIND(REPLACE(STR(?prefix), "^.+/", "") as ?localName) 29 | BIND(REPLACE(?localName, "-", "__") as ?constName) 30 | } order by ?prefix 31 | -------------------------------------------------------------------------------- /qudtlib-constants-gen/src/main/resources/query/quantitykinds.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | PREFIX kind: 4 | PREFIX rdfs: 5 | 6 | SELECT DISTINCT ?constName ?localName ?label (?qk as ?iri) ("QuantityKind" as ?typeName) ?symbol 7 | where 8 | { 9 | ?qk a qudt:QuantityKind . 10 | { 11 | select ?qk (MIN(STR(?labelVal)) as ?label) where { 12 | ?qk a qudt:QuantityKind . 13 | optional { 14 | ?qk rdfs:label ?labelVal . 15 | FILTER(LANG(?labelVal) = "en") 16 | } 17 | } GROUP BY ?qk ?symbol 18 | } 19 | { 20 | select ?qk (GROUP_CONCAT(STR(?smb); separator=" or ") as ?symbol) where { 21 | ?qk a qudt:QuantityKind . 22 | optional { 23 | ?qk qudt:symbol ?smb . 24 | } 25 | } GROUP BY ?qk 26 | } 27 | BIND(REPLACE(STR(?qk), "^.+/", "") as ?localName) 28 | BIND(REPLACE(?localName, "-", "__") as ?constName) 29 | } order by ?qk 30 | -------------------------------------------------------------------------------- /qudtlib-constants-gen/src/main/resources/query/systems-of-units.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | PREFIX kind: 4 | PREFIX rdfs: 5 | 6 | SELECT DISTINCT ?constName ?localName ?label (?sou as ?iri) ("SystemOfUnits" as ?typeName) ?symbol 7 | where 8 | { 9 | ?sou a qudt:SystemOfUnits . 10 | { 11 | select ?sou (MIN(STR(?labelVal)) as ?label) where { 12 | ?sou a qudt:SystemOfUnits . 13 | optional { 14 | ?sou rdfs:label ?labelVal . 15 | FILTER(LANG(?labelVal) = "en") 16 | } 17 | } GROUP BY ?sou 18 | 19 | } 20 | { 21 | select ?sou (GROUP_CONCAT(STR(?smb); separator=" or ") as ?symbol) where { 22 | ?sou a qudt:SystemOfUnits . 23 | optional { 24 | ?sou qudt:abbreviation ?smb . 25 | } 26 | } GROUP BY ?sou 27 | } 28 | BIND(REPLACE(STR(?sou), "^.+/", "") as ?localName) 29 | BIND(REPLACE(?localName, "-", "__") as ?constName) 30 | } order by ?sou 31 | -------------------------------------------------------------------------------- /qudtlib-constants-gen/src/main/resources/query/units.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | PREFIX kind: 4 | PREFIX rdfs: 5 | 6 | SELECT DISTINCT ?constName ?localName ?label ?iri ?typeName ?symbol where { 7 | { 8 | SELECT DISTINCT ?unitType ?label (?unit as ?iri) ("Unit" as ?typeName) ?symbol { 9 | { 10 | ?unit a qudt:Unit . 11 | BIND("Unit" as ?unitType) 12 | } UNION { 13 | ?unit a qudt:CurrencyUnit . 14 | BIND("CurrencyUnit" as ?unitType) 15 | } 16 | { 17 | select ?unit (MIN(STR(?labelVal)) as ?label) where { 18 | { 19 | ?unit a qudt:Unit . 20 | BIND("Unit" as ?unitType) 21 | } UNION { 22 | ?unit a qudt:CurrencyUnit . 23 | BIND("CurrencyUnit" as ?unitType) 24 | } optional { 25 | ?unit rdfs:label ?labelVal . 26 | FILTER(LANG(?labelVal) = "en") 27 | } 28 | } GROUP BY ?unit 29 | } 30 | { 31 | select ?unit (GROUP_CONCAT(STR(?smb); separator=" or ") as ?symbol) where { 32 | { 33 | ?unit a qudt:Unit . 34 | BIND("Unit" as ?unitType) 35 | } UNION { 36 | ?unit a qudt:CurrencyUnit . 37 | BIND("CurrencyUnit" as ?unitType) 38 | } optional { 39 | ?unit qudt:symbol ?smb . 40 | } 41 | } GROUP BY ?unit 42 | } 43 | } 44 | } 45 | BIND(REPLACE(STR(?iri), "^.+/", "") as ?localName) 46 | BIND(REPLACE(?localName, "-", "__") as ?constNameTmp) 47 | BIND(IF(?unitType = "CurrencyUnit", CONCAT(?constNameTmp, "_Currency"), ?constNameTmp) as ?constName) 48 | } order by ?iri 49 | -------------------------------------------------------------------------------- /qudtlib-constants-gen/src/main/resources/template/constants.ftl: -------------------------------------------------------------------------------- 1 | <#if copyright??> 2 | ${copyright} 3 | 4 | package ${package}; 5 | 6 | import static io.github.qudtlib.Qudt.*; 7 | 8 | import io.github.qudtlib.model.${type}; 9 | 10 | /** 11 | * Constants for QUDT ${type}s. 12 | */ 13 | public abstract class ${typePlural} { 14 | 15 | <#list constants as constant> 16 | /** 17 | * QUDT ${constant.typeName} constant ${constant.iriLocalname}: ${constant.label}<#if constant.symbol.isPresent()> (${constant.symbol.get()}) 18 | **/ 19 | public static final ${type} ${constant.codeConstantName} = ${constant.valueFactory}("${constant.iriLocalname}"); 20 | 21 | 22 | 23 | } 24 | 25 | -------------------------------------------------------------------------------- /qudtlib-data-gen/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | qudtlib-java 5 | io.github.qudtlib 6 | 6.8.2-SNAPSHOT 7 | 8 | 4.0.0 9 | qudtlib-data-gen 10 | jar 11 | 12 | 13 | io.github.qudtlib 14 | qudtlib-ingest-qudt 15 | ${project.version} 16 | 17 | 18 | io.github.qudtlib 19 | qudtlib-vocab 20 | ${project.version} 21 | 22 | 23 | io.github.qudtlib 24 | qudtlib-common-rdf 25 | ${project.version} 26 | 27 | 28 | org.eclipse.rdf4j 29 | rdf4j-runtime 30 | pom 31 | 32 | 33 | org.eclipse.rdf4j 34 | rdf4j-rio-turtle 35 | 36 | 37 | org.eclipse.rdf4j 38 | rdf4j-rio-api 39 | 40 | 41 | 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-deploy-plugin 46 | 47 | true 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /qudtlib-data-gen/src/main/resources/add-to-quantitykinds.ttl: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /qudtlib-data-gen/src/main/resources/add-to-units.ttl: -------------------------------------------------------------------------------- 1 | @prefix xsd: . 2 | @prefix qudt: . 3 | @prefix unit: . 4 | 5 | unit:DEG_C2 6 | qudt:symbol "°C²" . 7 | 8 | unit:GM-PER-M2-HR 9 | qudt:symbol "g/m²·hr" . 10 | 11 | unit:GM-PER-M2-YR 12 | qudt:symbol "g/m²·yr" . 13 | 14 | unit:GM-PER-M3-CentiPOISE 15 | qudt:symbol "g/(m³·cP)" . 16 | 17 | unit:GM-PER-M3-PA-SEC 18 | qudt:symbol "g/(m³Pa·s)" . 19 | 20 | unit:KiloGM-PER-M2-DAY 21 | qudt:symbol "kg/(m²·d)" . 22 | 23 | unit:KiloTONNE-PER-YR 24 | qudt:symbol "kt/yr" . 25 | 26 | unit:MegaGM-PER-HA-YR 27 | qudt:symbol "Mg/(ha·yr)" . 28 | 29 | unit:MegaJ-PER-M2-DAY 30 | qudt:symbol "MJ/(m²·d)" . 31 | 32 | unit:MicroGM-PER-GM-HR 33 | qudt:symbol "μg/(g·h)" . 34 | 35 | unit:MicroGM-PER-L-DAY 36 | qudt:symbol "μg/(L·d)" . 37 | 38 | unit:MicroMOL-PER-M2-SEC2 39 | qudt:symbol "μmol/(m²·s²)" . 40 | 41 | unit:MilliM-PER-M2 42 | qudt:symbol "mm/m²" . 43 | 44 | unit:MilliMOL-PER-M2-HR 45 | qudt:symbol "mmol/(m²·h)" . 46 | 47 | unit:NanoMOL-PER-GM-HR 48 | qudt:symbol "nmol/(g.h)" . 49 | 50 | unit:NanoMOL-PER-M2-SEC 51 | qudt:symbol "nmol/(m²·s)" . 52 | 53 | 54 | -------------------------------------------------------------------------------- /qudtlib-data-gen/src/main/resources/delete-from-quantitykinds-by-query1_dontfind.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | prefix quantitykind: 4 | DELETE { ?qk ?b ?c . ?d ?e ?qk } 5 | WHERE { { ?qk ?b ?c .} union { ?d ?e ?qk } 6 | VALUES ?qk { quantitykind:VaporPermeability } 7 | } -------------------------------------------------------------------------------- /qudtlib-data-gen/src/main/resources/delete-from-quantitykinds.ttl: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /qudtlib-data-gen/src/main/resources/delete-from-units-by-query1.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | prefix quantitykind: 4 | DELETE { ?u qudt:symbol ?s } 5 | WHERE { ?u qudt:symbol ?s 6 | VALUES ?u { 7 | unit:DEG_C2 8 | unit:GM-PER-M2-HR 9 | unit:GM-PER-M2-YR 10 | unit:GM-PER-M3-CentiPOISE 11 | unit:GM-PER-M3-PA-SEC 12 | unit:KiloGM-PER-M2-DAY 13 | unit:KiloTONNE-PER-YR 14 | unit:MegaGM-PER-HA-YR 15 | unit:MegaJ-PER-M2-DAY 16 | unit:MicroGM-PER-L-DAY 17 | unit:MicroGM-PER-GM-HR 18 | unit:MicroMOL-PER-M2-SEC2 19 | unit:MilliM-PER-M2 20 | unit:MilliMOL-PER-M2-HR 21 | unit:NanoMOL-PER-GM-HR 22 | unit:NanoMOL-PER-M2-SEC 23 | } 24 | } -------------------------------------------------------------------------------- /qudtlib-data-gen/src/main/resources/delete-from-units-by-query2_dontfind.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | prefix quantitykind: 4 | DELETE { ?u qudt:symbol ?symb } 5 | INSERT { ?u qudt:symbol ?repl } 6 | WHERE { 7 | ?u qudt:symbol ?symb 8 | filter(regex(?symb, "^1/.+")) 9 | BIND (replace(?symb, "^1", "") as ?repl) 10 | } -------------------------------------------------------------------------------- /qudtlib-data-gen/src/main/resources/delete-from-units.ttl: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /qudtlib-data-gen/src/main/resources/delete-kiloGM-scalings.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | PREFIX prefix: 4 | PREFIX kind: 5 | PREFIX rdfs: 6 | 7 | DELETE { 8 | ?scaledUnit qudt:isScalingOf ?baseUnit . 9 | } 10 | where 11 | { 12 | ?scaledUnit 13 | a qudt:Unit ; 14 | qudt:isScalingOf ?baseUnit . 15 | ?baseUnit a qudt:Unit . 16 | OPTIONAL { 17 | ?scaledUnit qudt:convertsTo ?convertsToUnit . 18 | ?convertsToUnit a qudt:Unit. 19 | } 20 | FILTER (?baseUnit = unit:KiloGM) 21 | } 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /qudtlib-data-gen/src/main/resources/delete-units.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | PREFIX prefix: 4 | PREFIX kind: 5 | PREFIX rdfs: 6 | 7 | DELETE { 8 | ?unit ?p ?o. 9 | } 10 | where 11 | { 12 | ?unit a qudt:Unit; 13 | ?p ?o . 14 | } 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /qudtlib-data-gen/src/main/resources/factorUnit.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | PREFIX prefix: 4 | PREFIX kind: 5 | PREFIX rdfs: 6 | PREFIX xsd: 7 | 8 | CONSTRUCT { 9 | ?derivedUnit qudt:factorUnit [ 10 | qudt:unit ?baseUnit ; 11 | qudt:exponent ?exponent 12 | ] . 13 | } 14 | #SELECT * WHERE 15 | #SELECT ?derivedUnit ?baseUnitLocalNameExtracted ?newlyMintedBaseUnit ?existingBaseUnit ?existingBaseUnitLocalName ?baseUnit 16 | #select count(*) where 17 | { 18 | SELECT DISTINCT ?derivedUnit ?baseUnit ?exponent WHERE 19 | { 20 | { 21 | ?derivedUnit a qudt:Unit ; 22 | BIND(REPLACE(STR(?derivedUnit), "^.+/", "") as ?derivedUnitLocalName) 23 | FILTER(REPLACE(?derivedUnitLocalName, "(PER|2|3|4|5|6|-)\\b", "") != ?derivedUnitLocalName) 24 | FILTER(?derivedUnitLocalName NOT IN ( 25 | "Gold-OunceTroy", 26 | "Palladium-OunceTroy", 27 | "Silver-OunceTroy", 28 | "Platinum-OunceTroy", 29 | "failures-in-time", 30 | "USDollar-NextDay", 31 | "Kilo-FT3" 32 | )) 33 | 34 | VALUES ?skipUnits { 0 1 2 3 4 5 6 } 35 | BIND("(\\w+(_\\w+)?\\d?)" as ?baseUnitRegex) 36 | BIND("(\\w+(_\\w+)?\\d?|PER)" as ?skipUnitRegex) 37 | BIND(CONCAT("^(",?skipUnitRegex,"-){", STR(?skipUnits), "}", ?baseUnitRegex, "(-" ,?skipUnitRegex, ")*$") as ?selectUnitRegex ) 38 | BIND(REPLACE(?derivedUnitLocalName, ?selectUnitRegex, "$4") as ?baseUnitLocalNameExtractedTmp) 39 | BIND(REPLACE(?baseUnitLocalNameExtractedTmp, "^(\\w*[^\\d])(\\d?)$", "$1") as ?baseUnitLocalNameExtracted) 40 | BIND(REPLACE(?baseUnitLocalNameExtractedTmp, "^(\\w*[^\\d])(\\d?)$", "$2") as ?exponentTmpStr) 41 | BIND(IF(?exponentTmpStr = "", STRDT("1",xsd:integer), STRDT(?exponentTmpStr,xsd:integer)) as ?exponentTmp) 42 | VALUES ( ?matchString ?dontMatchString ?expFactor) { 43 | ( "^.*PER-.*\\b@@UNIT@@\\b.*$" "dontfindthis" -1 ) 44 | ( "^.*\\b@@UNIT@@\\b.*PER.*$" "dontfindthis" 1 ) 45 | ( ".+" "\\bPER\\b" 1 ) 46 | } 47 | FILTER(REPLACE(?derivedUnitLocalName, REPLACE(?matchString, "@@UNIT@@", ?baseUnitLocalNameExtractedTmp), "") != ?derivedUnitLocalName) 48 | FILTER(REPLACE(?derivedUnitLocalName, ?dontMatchString, "") = ?derivedUnitLocalName) 49 | BIND(?exponentTmp * ?expFactor as ?exponent) 50 | FILTER( ?baseUnitLocalNameExtractedTmp != "PER" ) 51 | FILTER( ! CONTAINS(?baseUnitLocalNameExtractedTmp, "-") ) 52 | BIND(IRI(CONCAT("http://qudt.org/vocab/unit/", ?baseUnitLocalNameExtracted)) as ?newlyMintedBaseUnit) 53 | # find an existing unit or currencyunit with the localname we have determined. if we find none, we will 54 | # assume that the factor unit is a normal unit and that it is missing. 55 | OPTIONAL { 56 | { 57 | ?existingBaseUnit a qudt:Unit 58 | BIND(REPLACE(STR(?existingBaseUnit), "^.+/", "") AS ?existingBaseUnitLocalName) 59 | } 60 | UNION 61 | { 62 | ?existingBaseUnit a qudt:CurrencyUnit 63 | BIND(REPLACE(STR(?existingBaseUnit), "^.+/", "") AS ?existingBaseUnitLocalName) 64 | } 65 | FILTER(?existingBaseUnitLocalName = ?baseUnitLocalNameExtracted) 66 | } 67 | # did we find an existing unit/currencyunit with that localname? use it. Otherwise: use newly minted unit iri. 68 | BIND(IF(BOUND(?existingBaseUnit), ?existingBaseUnit, ?newlyMintedBaseUnit) as ?baseUnit) 69 | } 70 | 71 | FILTER NOT EXISTS { 72 | ?derivedUnit qudt:factorUnit [ 73 | qudt:unit ?baseUnit ; 74 | qudt:exponent ?exponent 75 | ] . 76 | } 77 | 78 | FILTER NOT EXISTS { 79 | ?derivedUnit qudt:isScalingOf ?someOtherUnit 80 | } 81 | } 82 | } 83 | order by ?derivedUnit ?baseUnit 84 | -------------------------------------------------------------------------------- /qudtlib-data-gen/src/main/resources/isScalingOf.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | PREFIX prefix: 4 | PREFIX kind: 5 | PREFIX rdfs: 6 | 7 | CONSTRUCT { 8 | ?scaledUnit 9 | qudt:isScalingOf ?baseUnit ; 10 | qudt:conversionMultiplier ?scaledUnitConversionMultiplier ; 11 | qudt:conversionOffset ?scaledUnitConversionOffset ; 12 | qudt:prefix ?prefix . 13 | } 14 | #SELECT ?scaledUnit ?baseUnit ?prefix ?scaledUnitConversionMultiplier ?scaledUnitConversionOffset 15 | where 16 | { 17 | { 18 | { SELECT DISTINCT ?scaledUnit ?scaledUnitLocalName ?prefixRegex 19 | WHERE 20 | { 21 | 22 | # select all base units (not using prefixes) 23 | { 24 | ?scaledUnit a qudt:Unit . 25 | } UNION { 26 | ?factor qudt:unit ?scaledUnit ; 27 | FILTER NOT EXISTS { 28 | ?scaledUnit a qudt:Unit . 29 | } 30 | } 31 | BIND(REPLACE(STR(?scaledUnit), "^.+/", "") as ?scaledUnitLocalName) 32 | FILTER(REPLACE(?scaledUnitLocalName, ?prefixRegex, "") != ?scaledUnitLocalName) 33 | { 34 | SELECT (CONCAT("\\b(",GROUP_CONCAT(STR(?prefixLabel); separator ="|"), ")") as ?prefixRegex) where 35 | { 36 | ?prefix 37 | a qudt:Prefix ; 38 | rdfs:label ?prefixLabel . 39 | } 40 | } 41 | } 42 | } 43 | 44 | # select all base units (not using prefixes) 45 | # special handling for prefix + time, e.g. 46 | # 'unit:MegaYR qudt:isScalingOf unit:YR', not unit:SEC 47 | 48 | ?baseUnit a qudt:Unit ; 49 | BIND(REPLACE(STR(?baseUnit), "^.+/", "") as ?baseUnitLocalName) 50 | # we don't generate isScalingOf for bases that are derived units 51 | FILTER(! CONTAINS(?baseUnitLocalName, "-")) 52 | # we don't generate isScalingOf for bases with a non-1 exponent (because then we cannot use the existing factor as would have to be exponentiated) 53 | FILTER(! REGEX(?baseUnitLocalName,".+\\d+")) 54 | BIND("(YR|MO|DAY|HR|MIN)\\b" as ?timeRegex) 55 | FILTER ( 56 | ( 57 | REPLACE(?scaledUnitLocalName, CONCAT(?prefixRegex, ?timeRegex), "") = ?scaledUnitLocalName 58 | && ?baseUnitLocalName = REPLACE(REPLACE(?scaledUnitLocalName, ?prefixRegex, ""), ?timeRegex, "SEC") 59 | ) || ( 60 | REPLACE(?scaledUnitLocalName, CONCAT(?prefixRegex, ?timeRegex), "") != ?scaledUnitLocalName 61 | && ?baseUnitLocalName = REPLACE(?scaledUnitLocalName, ?prefixRegex, "") 62 | ) 63 | ) 64 | } 65 | OPTIONAL { 66 | # if the scaled unit has a prefix, match it so we can add the triple 67 | ?prefix a qudt:Prefix ; 68 | rdfs:label ?prefixLabel ; 69 | FILTER (!CONTAINS(?baseUnitLocalName, "-")) 70 | FILTER (CONTAINS(?scaledUnitLocalName, STR(?prefixLabel))) 71 | } 72 | OPTIONAL { 73 | # if the scaled unit does not have a conversionMultiplier, generate it 74 | FILTER NOT EXISTS { 75 | ?scaledUnit qudt:conversionMultiplier ?any . 76 | } 77 | ?baseUnit qudt:conversionMultiplier ?cm . 78 | optional { 79 | ?baseUnit qudt:conversionOffset ?co 80 | } 81 | ?prefix a qudt:Prefix ; 82 | qudt:prefixMultiplier ?prefixMultiplier ; 83 | rdfs:label ?prefixLabel ; 84 | FILTER (!CONTAINS(?baseUnitLocalName, "-")) 85 | FILTER (CONTAINS(?scaledUnitLocalName, STR(?prefixLabel))) 86 | BIND (?cm * ?prefixMultiplier as ?scaledUnitConversionMultiplier ) 87 | BIND (?co as ?scaledUnitConversionOffset ) 88 | } 89 | 90 | OPTIONAL { 91 | ?baseUnit qudt:dimensionVector ?dv . 92 | } 93 | FILTER NOT EXISTS { 94 | ?scaledUnit qudt:isScalingOf ?baseUnit . 95 | { 96 | ?scaledUnit qudt:prefix ?prefix 97 | } UNION { 98 | ?scaledUnit qudt:factorUnit ?x . # for derived units, we don't generate a prefix. 99 | } 100 | } 101 | } 102 | order by ?baseUnit ?scaledUnit -------------------------------------------------------------------------------- /qudtlib-data-gen/src/main/resources/missing-units.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | PREFIX prefix: 4 | PREFIX kind: 5 | PREFIX rdfs: 6 | PREFIX xsd: 7 | 8 | CONSTRUCT { 9 | ?unit a qudt:Unit ; 10 | qudt:hasDimensionVector ?dimensionVector ; 11 | rdfs:label ?unitLocalName; 12 | rdfs:comment ?comment ; 13 | qudt:generated true . 14 | } 15 | #SELECT distinct ?unit WHERE 16 | #select count(*) where 17 | { 18 | 19 | { 20 | ?x qudt:factorUnit/qudt:unit ?unit . 21 | BIND("factor unit" as ?reason) 22 | } UNION { 23 | ?unit qudt:factorUnit/qudt:unit ?x . 24 | BIND("derived unit" as ?reason) 25 | } UNION { 26 | ?x qudt:isScalingOf ?unit . 27 | BIND("base unit" as ?reason) 28 | } UNION { 29 | ?unit qudt:isScalingOf ?x . 30 | BIND("scaled unit" as ?reason) 31 | } 32 | FILTER NOT EXISTS { 33 | ?unit a qudt:Unit 34 | } 35 | FILTER NOT EXISTS { 36 | ?unit a qudt:CurrencyUnit 37 | } 38 | OPTIONAL { 39 | ?unit qudt:isScalingOf/qudt:hasDimensionVector ?dimensionVector . 40 | } 41 | BIND(REPLACE(STR(?unit), "^.+/", "") as ?unitLocalName) 42 | BIND(STRLANG(CONCAT("This unit was added while generating qudt:factorUnit. This unit is a ", ?reason, " of ", (REPLACE(STR(?x), "http://qudt.org/vocab/unit/", "unit:")), ", missing from the original QUDT data."), "en") as ?comment) 43 | } 44 | order by ?unit -------------------------------------------------------------------------------- /qudtlib-data-gen/src/main/resources/tmpExpected/README.md: -------------------------------------------------------------------------------- 1 | Used for TTL files containing the expected output of the data-gen process, for comparison between versions, if necessary. 2 | -------------------------------------------------------------------------------- /qudtlib-data/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | qudtlib-java 5 | io.github.qudtlib 6 | 6.8.2-SNAPSHOT 7 | 8 | 4.0.0 9 | qudtlib-data 10 | jar 11 | 12 | 13 | ${project.build.directory}/generated-resources/qudtlib 14 | 15 | 16 | 17 | 18 | 19 | org.codehaus.mojo 20 | exec-maven-plugin 21 | 22 | 23 | 24 | java 25 | 26 | generate-resources 27 | 28 | 29 | 30 | true 31 | true 32 | io.github.qudtlib.data.DataGenerator 33 | 34 | ${qudtlib.generate.dir} 35 | 36 | 37 | 38 | 39 | io.github.qudtlib 40 | qudtlib-data-gen 41 | ${project.version} 42 | 43 | 44 | 45 | 46 | org.apache.maven.plugins 47 | maven-jar-plugin 48 | 49 | ${project.build.directory}/generated-resources 50 | 51 | qudtlib/** 52 | 53 | 54 | 55 | 56 | org.codehaus.mojo 57 | build-helper-maven-plugin 58 | 59 | 60 | generate-resources 61 | 62 | add-source 63 | 64 | 65 | 66 | ${project.build.directory}/generated-resources/ 67 | 68 | 69 | 70 | 71 | 72 | 73 | org.apache.maven.plugins 74 | maven-deploy-plugin 75 | 76 | true 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /qudtlib-example/README.md: -------------------------------------------------------------------------------- 1 | # QUDTLib Example 2 | 3 | Here are the important bits: 4 | 5 | ## maven 6 | 7 | ``` 8 | 9 | io.github.qudtlib 10 | qudtlib 11 | ${project.version} 12 | 13 | ``` 14 | 15 | ## Java 16 | 17 | ```java 18 | public static void main(String[] args) { 19 | System.out.println( 20 | "Converting 38.5° Celsius into Fahrenheit: " 21 | + Qudt.convert( 22 | new BigDecimal("38.5"), 23 | Qudt.Units.DEG_C, 24 | Qudt.Units.DEG_F)); 25 | } 26 | ``` 27 | 28 | there is a bit more code to look at in [src/main/java/org/example/qudlib/QudtlibExample.java](src/main/java/org/example/qudlib/QudtlibExample.java) 29 | -------------------------------------------------------------------------------- /qudtlib-example/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | qudtlib-java 5 | io.github.qudtlib 6 | 6.8.2-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | qudtlib-example 11 | 12 | 13 | 14 | io.github.qudtlib 15 | qudtlib 16 | ${project.version} 17 | 18 | 19 | 20 | 21 | 22 | org.apache.maven.plugins 23 | maven-deploy-plugin 24 | 25 | true 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /qudtlib-example/src/main/java/org/example/qudlib/QudtlibExample.java: -------------------------------------------------------------------------------- 1 | package org.example.qudlib; 2 | 3 | import io.github.qudtlib.Qudt; 4 | import io.github.qudtlib.model.DerivedUnitSearchMode; 5 | import io.github.qudtlib.model.FactorUnit; 6 | import io.github.qudtlib.model.QuantityValue; 7 | import io.github.qudtlib.model.Unit; 8 | import java.math.BigDecimal; 9 | import java.util.List; 10 | 11 | /** 12 | * Simple demo of the QUDTLib usage. 13 | * 14 | * @author Florian Kleedorfer 15 | * @version 1.0 16 | */ 17 | public class QudtlibExample { 18 | public static void main(String[] args) { 19 | System.out.println(Qudt.getGreeting()); 20 | System.out.println("---"); 21 | System.out.println( 22 | "Converting 38.5° Celsius into Fahrenheit: " 23 | + Qudt.convert(new BigDecimal("38.5"), Qudt.Units.DEG_C, Qudt.Units.DEG_F)); 24 | System.out.println("---"); 25 | System.out.println("finding unit for factors: m, kg, and s^-2:"); 26 | List myUnits = 27 | Qudt.unitsFromUnitExponentPairs( 28 | DerivedUnitSearchMode.BEST_MATCH, 29 | Qudt.Units.M, 30 | 1, 31 | Qudt.Units.KiloGM, 32 | 1, 33 | Qudt.Units.SEC, 34 | -2); 35 | for (Unit unit : myUnits) { 36 | System.out.println("unit : " + unit); 37 | } 38 | System.out.println("---"); 39 | List myFactorUnits = Qudt.Units.N.getFactorUnits().getFactorUnits(); 40 | System.out.println("finding factors of unit " + Qudt.Units.N); 41 | for (FactorUnit factorUnit : myFactorUnits) { 42 | System.out.println("factor unit:" + factorUnit); 43 | } 44 | System.out.println("---"); 45 | System.out.print("Converting 1N into kN: "); 46 | QuantityValue quantityValue = new QuantityValue(new BigDecimal("1"), Qudt.Units.N); 47 | QuantityValue converted = Qudt.convert(quantityValue, Qudt.Units.KiloN); 48 | System.out.println(converted); 49 | System.out.println("---"); 50 | System.out.print("Converting 1L into US Gallon: "); 51 | quantityValue = new QuantityValue(new BigDecimal("1"), Qudt.Units.L); 52 | converted = Qudt.convert(quantityValue, Qudt.Units.GAL_US); 53 | System.out.println(converted); 54 | System.out.println("---"); 55 | System.out.println("Which units can we convert to from " + Qudt.Units.L + "?"); 56 | Unit fromUnit = Qudt.Units.L; 57 | for (Unit unit : Qudt.allUnits()) { 58 | if (Qudt.isConvertible(fromUnit, unit)) { 59 | System.out.println(" " + unit + " (" + unit.getIri() + ")"); 60 | } 61 | } 62 | System.out.println("---"); 63 | System.out.println( 64 | "Which units are applicable for " + Qudt.QuantityKinds.PressureRatio + "?"); 65 | for (Unit unit : Qudt.QuantityKinds.PressureRatio.getApplicableUnits()) { 66 | System.out.println(" " + unit + " (" + unit.getIri() + ")"); 67 | } 68 | System.out.println("---"); 69 | System.out.println( 70 | "Instantiating unit by label 'Pint (UK)':" + Qudt.unitFromLabel("Pint (UK)")); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /qudtlib-hardcoded-model-gen/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | qudtlib-java 5 | io.github.qudtlib 6 | 6.8.2-SNAPSHOT 7 | 8 | 4.0.0 9 | qudtlib-hardcoded-model-gen 10 | jar 11 | 12 | 13 | io.github.qudtlib 14 | qudtlib-main-rdf 15 | ${project.version} 16 | 17 | 18 | io.github.qudtlib 19 | qudtlib-common-rdf 20 | ${project.version} 21 | 22 | 23 | io.github.qudtlib 24 | qudtlib-common-codegen 25 | ${project.version} 26 | 27 | 28 | org.freemarker 29 | freemarker 30 | 31 | 32 | 33 | 34 | 35 | org.apache.maven.plugins 36 | maven-deploy-plugin 37 | 38 | true 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /qudtlib-hardcoded-model-gen/src/main/java/io/github/qudtlib/HardcodedModelGenerator.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib; 2 | 3 | import freemarker.template.Configuration; 4 | import freemarker.template.TemplateException; 5 | import io.github.qudtlib.common.CodeGen; 6 | import io.github.qudtlib.common.RdfOps; 7 | import java.io.File; 8 | import java.io.IOException; 9 | import java.nio.file.Path; 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | import java.util.TreeMap; 13 | import java.util.regex.Pattern; 14 | 15 | /** 16 | * Generates a Java class that instantiates all QUDT individuals and relationships needed for 17 | * QUDTLib from hardcoded data, i.e. without the need to process RDF. 18 | * 19 | *

This generator uses a functioning QUDTLib implementation that instantiates all individuals 20 | * from RDF (module qudtlib-main-rdf) to generate the 'hardcoded' class, which can 21 | * subsequently be used to initialize the internal model (as is done in module qudtlib 22 | * ). 23 | * 24 | * @author Florian Kleedorfer 25 | * @version 1.0 26 | */ 27 | public class HardcodedModelGenerator { 28 | private final Path outputDir; 29 | // output 30 | private static final String DESTINATION_PACKAGE = "io.github.qudtlib.init"; 31 | private static final String FILENAME = "InitializerImpl.java"; 32 | // template 33 | private static final String TEMPLATE_FILE = "template/InitializerImpl.ftl"; 34 | 35 | public HardcodedModelGenerator(Path outputDir) { 36 | this.outputDir = outputDir; 37 | } 38 | 39 | public static void main(String[] args) { 40 | try { 41 | if (args.length == 0) { 42 | throw new IllegalArgumentException("missing argument"); 43 | } 44 | if (args.length > 1) { 45 | throw new IllegalArgumentException(" too many arguments"); 46 | } 47 | String outputDir = args[0]; 48 | HardcodedModelGenerator generator = new HardcodedModelGenerator(Path.of(outputDir)); 49 | generator.generate(); 50 | } catch (Exception e) { 51 | System.err.println("\n\n\tusage: HardcodedModelGenerator [output-dir]\n\n"); 52 | e.printStackTrace(); 53 | System.exit(1); 54 | } 55 | } 56 | 57 | public void generate() throws IOException, TemplateException { 58 | Configuration cfg = CodeGen.getFreemarkerConfiguration(); 59 | generateInitializer(cfg); 60 | } 61 | 62 | private void generateInitializer(Configuration config) throws IOException, TemplateException { 63 | Map templateVars = new HashMap<>(); 64 | templateVars.put("prefixes", new TreeMap<>(Qudt.getPrefixesMap())); 65 | templateVars.put("quantityKinds", new TreeMap<>(Qudt.getQuantityKindsMap())); 66 | templateVars.put("units", new TreeMap<>(Qudt.getUnitsMap())); 67 | templateVars.put("systemsOfUnits", new TreeMap<>(Qudt.getSystemsOfUnitsMap())); 68 | templateVars.put("constantValues", new TreeMap<>(Qudt.getConstantValuesMap())); 69 | templateVars.put("physicalConstants", new TreeMap<>(Qudt.getPhysicalConstantsMap())); 70 | generateJavaFile(config, templateVars); 71 | } 72 | 73 | private void generateJavaFile(Configuration config, Map templateVars) 74 | throws IOException, TemplateException { 75 | RdfOps.message("Generating " + FILENAME); 76 | File packageFile = 77 | new File(outputDir + "/" + DESTINATION_PACKAGE.replaceAll(Pattern.quote("."), "/")); 78 | if (!packageFile.exists()) { 79 | if (!packageFile.mkdirs()) { 80 | throw new IOException( 81 | "Could not create output dir " + packageFile.getAbsolutePath()); 82 | } 83 | } 84 | RdfOps.message("output dir: " + packageFile.getAbsolutePath()); 85 | templateVars.put("package", DESTINATION_PACKAGE); 86 | File outFile = new File(packageFile, FILENAME); 87 | CodeGen.generateFileFromTemplate(config, TEMPLATE_FILE, templateVars, outFile); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /qudtlib-ingest-qudt/src/test/resources/query/README.md: -------------------------------------------------------------------------------- 1 | # Queries 2 | 3 | This folder contains queries to be run against the qudt data as downloaded into during a maven build 4 | 5 | ```` 6 | qudtlib-ingest-qudt/target/generated-resources/qudt/vocab 7 | ```` 8 | 9 | The queries only serve the purpose of understanding the data. They are not meant to be used anywhere else in the project. 10 | 11 | With the jena commandline tools installed, a query can be executed from this folder as follows: 12 | 13 | ``` 14 | sparql --data=../../../../target/generated-resources/qudt/vocab/unit/VOCAB_QUDT-UNITS-ALL.ttl --query=allScalingOf.rq 15 | ``` 16 | 17 | or, if more data is needed, 18 | 19 | ``` 20 | sparql --data=../../../../target/generated-resources/qudt/vocab/unit/VOCAB_QUDT-UNITS-ALL.ttl\ 21 | --data=../../../../target/generated-resources/qudt/vocab/prefixes/VOCAB_QUDT-PREFIXES.ttl\ 22 | --query=allScalingOf.rq 23 | ``` 24 | 25 | -------------------------------------------------------------------------------- /qudtlib-ingest-qudt/src/test/resources/query/allPrefixes.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | PREFIX kind: 4 | PREFIX rdfs: 5 | prefix skos: 6 | 7 | SELECT where 8 | { 9 | ?prefix a qudt:Prefix ; 10 | rdfs:label ?label ; 11 | qudt:symbol ?symbol ; 12 | qudt:prefixMultiplier ?prefixMultiplier . 13 | optional { 14 | ?prefix qudt:ucumCode ?ucumCode . 15 | } 16 | } order by ?prefix 17 | -------------------------------------------------------------------------------- /qudtlib-ingest-qudt/src/test/resources/query/allScalingOf.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | 3 | SELECT * where 4 | { 5 | ?unit a qudt:Unit. 6 | optional { 7 | ?unit qudt:isScalingOf ?base . 8 | } 9 | optional { 10 | ?unit qudt:prefix ?prefix . 11 | } 12 | optional { 13 | ?unit qudt:conversionMultiplier ?conversionMultiplier . 14 | } 15 | 16 | 17 | } order by ?prefix ?base ?unit ?conversionMultiplier -------------------------------------------------------------------------------- /qudtlib-ingest-qudt/src/test/resources/query/isScalingOf-inconsistencies.rq: -------------------------------------------------------------------------------- 1 | PREFIX unit: 2 | PREFIX qudt: 3 | 4 | SELECT * where 5 | { 6 | ?unit a qudt:Unit. 7 | optional { 8 | ?unit qudt:isScalingOf ?base . 9 | } 10 | optional { 11 | ?unit qudt:prefix ?prefix . 12 | } 13 | optional { 14 | ?unit qudt:conversionMultiplier ?conversionMultiplier . 15 | } 16 | filter(?unit in (unit:GM, unit:DecaGM, unit:LB, unit:Stone_UK, unit:CentiM, unit:MicroIN, unit:IN, unit:A_Ab, unit:PA-PER-MIN, unit:TONNE-PER-MIN, unit:KiloGM-PER-SEC, unit:KiloGM-PER-MIN)) 17 | } order by ?prefix ?base ?unit ?conversionMultiplier -------------------------------------------------------------------------------- /qudtlib-ingest-qudt/src/test/resources/query/missingConversionMultiplier.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX qk: 3 | 4 | SELECT ?u where 5 | { 6 | ?u a qudt:Unit ; 7 | FILTER NOT EXISTS { 8 | ?u qudt:conversionMultiplier ?multiplier 9 | } 10 | FILTER NOT EXISTS { 11 | ?u qudt:hasQuantityKind qk:Currency 12 | } 13 | } 14 | order by str(?u) -------------------------------------------------------------------------------- /qudtlib-ingest-qudt/src/test/resources/query/missingScalingTriples.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | 3 | SELECT * where 4 | { 5 | ?unit a qudt:Unit. 6 | optional { 7 | ?unit qudt:isScalingOf ?base . 8 | } 9 | optional { 10 | ?unit qudt:prefix ?prefix . 11 | } 12 | optional { 13 | ?unit qudt:conversionMultiplier ?conversionMultiplier . 14 | } 15 | filter(!contains(str(?unit), "-")) 16 | filter(regex(str(?unit), "(.+/Atto.+|.+/Centi.+|.+/Deca.+|.+/Deci.+|.+/Deka.+|.+/Exa.+|.+/Exbi.+|.+/Femto.+|.+/Gibi.+|.+/Giga.+|.+/Hecto.+|.+/Kibi.+|.+/Kilo.+|.+/Mebi.+|.+/Mega.+|.+/Micro.+|.+/Milli.+|.+/Nano.+|.+/Pebi.+|.+/Peta.+|.+/Pico.+|.+/Tebi.+|.+/Tera.+|.+/Yobi.+|.+/Yocto.+|.+/Yotta.+|.+/Zebi.+|.+/Zepto.+|.+/Zetta.+)")) 17 | filter(!bound(?base) || !bound (?prefix) || ! bound (?conversionMultiplier)) 18 | } order by ?prefix ?base ?unit ?conversionMultiplier -------------------------------------------------------------------------------- /qudtlib-ingest-qudt/src/test/resources/query/unitDimensionVectors.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX qkdv: 3 | PREFIX qk: 4 | PREFIX unit: 5 | 6 | 7 | SELECT ?unit ?hasDimensionVector ?qkHasDimensionVector ?hasQuantityKind where 8 | { 9 | ?unit a qudt:Unit. 10 | ?unit qudt:hasQuantityKind ?hasQuantityKind . 11 | ?hasQuantityKind qudt:hasDimensionVector ?qkHasDimensionVector . 12 | optional { 13 | ?unit qudt:hasDimensionVector ?hasDimensionVector . 14 | } 15 | filter(! bound (?hasDimensionVector)) 16 | } order by ?unit ?hasDimensionVector -------------------------------------------------------------------------------- /qudtlib-ingest-qudt/src/test/resources/query/unitDimensionVectorsMissing.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX qkdv: 3 | PREFIX unit: 4 | 5 | 6 | SELECT ?unit ?hasDimensionVector where 7 | { 8 | ?unit a qudt:Unit. 9 | optional { 10 | ?unit qudt:hasDimensionVector ?hasDimensionVector . 11 | } 12 | } order by ?hasDimensionVector ?unit -------------------------------------------------------------------------------- /qudtlib-init-hardcoded/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | qudtlib-java 5 | io.github.qudtlib 6 | 6.8.2-SNAPSHOT 7 | 8 | 4.0.0 9 | qudtlib-init-hardcoded 10 | jar 11 | 12 | 13 | io.github.qudtlib 14 | qudtlib-model 15 | ${project.version} 16 | 17 | 18 | 19 | 20 | src/main/java 21 | 22 | 23 | org.codehaus.mojo 24 | exec-maven-plugin 25 | 26 | 27 | 28 | java 29 | 30 | generate-sources 31 | 32 | 33 | 34 | false 35 | true 36 | true 37 | io.github.qudtlib.HardcodedModelGenerator 38 | 39 | ${project.build.directory}/generated-sources 40 | 41 | 42 | 43 | 44 | io.github.qudtlib 45 | qudtlib-hardcoded-model-gen 46 | ${project.version} 47 | 48 | 49 | 50 | 51 | org.codehaus.mojo 52 | build-helper-maven-plugin 53 | 54 | 55 | generate-sources 56 | 57 | add-source 58 | 59 | 60 | 61 | ${project.build.directory}/generated-sources/ 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /qudtlib-init-rdf/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | qudtlib-java 5 | io.github.qudtlib 6 | 6.8.2-SNAPSHOT 7 | 8 | 4.0.0 9 | qudtlib-init-rdf 10 | jar 11 | 12 | 13 | 14 | io.github.qudtlib 15 | qudtlib-model 16 | ${project.version} 17 | 18 | 19 | org.slf4j 20 | slf4j-reload4j 21 | 22 | 23 | org.eclipse.rdf4j 24 | rdf4j-runtime 25 | pom 26 | 27 | 28 | org.eclipse.rdf4j 29 | rdf4j-rio-turtle 30 | 31 | 32 | org.eclipse.rdf4j 33 | rdf4j-rio-api 34 | 35 | 36 | io.github.qudtlib 37 | qudtlib-data 38 | ${project.version} 39 | 40 | 41 | 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-deploy-plugin 46 | 47 | true 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /qudtlib-init-rdf/src/main/resources/qudtlib/query/constantValue.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | PREFIX kind: 4 | PREFIX rdfs: 5 | 6 | SELECT * where 7 | { 8 | ?constantValue 9 | a qudt:ConstantValue ; 10 | qudt:hasUnit ?unit ; 11 | qudt:value ?value . 12 | OPTIONAL { 13 | ?constantValue qudt:standardUncertainty ?standardUncertainty ; 14 | } 15 | OPTIONAL { 16 | ?constantValue qudt:deprecated ?deprecated ; 17 | } 18 | } order by ?constantValue 19 | -------------------------------------------------------------------------------- /qudtlib-init-rdf/src/main/resources/qudtlib/query/factor-units.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | PREFIX kind: 4 | PREFIX rdfs: 5 | PREFIX xsd: 6 | 7 | SELECT DISTINCT 8 | ?derivedUnit 9 | ?factorUnit 10 | ?exponent 11 | ?scaleFactor 12 | WHERE 13 | { 14 | ?derivedUnit qudt:factorUnit ?endFactor . 15 | ?endFactor 16 | qudt:unit ?factorUnit ; 17 | qudt:exponent ?exponent . 18 | OPTIONAL { 19 | ?derivedUnit qudt:factorUnitScalar ?scaleFactor 20 | } 21 | } 22 | ORDER BY ?derivedUnit ?factorUnit 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /qudtlib-init-rdf/src/main/resources/qudtlib/query/physicalConstant.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | PREFIX kind: 4 | PREFIX rdfs: 5 | PREFIX dcterms: 6 | 7 | SELECT * where 8 | { 9 | ?physicalConstant 10 | a qudt:PhysicalConstant ; 11 | qudt:hasQuantityKind ?quantityKind ; 12 | qudt:quantityValue ?quantityValue ; 13 | rdfs:label ?label . 14 | OPTIONAL { 15 | ?physicalConstant qudt:deprecated ?deprecated ; 16 | } 17 | OPTIONAL { 18 | ?physicalConstant dcterms:description ?description ; 19 | } 20 | } order by ?physicalConstant 21 | 22 | -------------------------------------------------------------------------------- /qudtlib-init-rdf/src/main/resources/qudtlib/query/prefix.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | PREFIX kind: 4 | PREFIX rdfs: 5 | prefix skos: 6 | 7 | SELECT * where 8 | { 9 | ?prefix a qudt:Prefix ; 10 | rdfs:label ?label ; 11 | qudt:symbol ?symbol ; 12 | qudt:prefixMultiplier ?prefixMultiplier . 13 | optional { 14 | ?prefix qudt:ucumCode ?ucumCode . 15 | } 16 | } order by ?prefix 17 | -------------------------------------------------------------------------------- /qudtlib-init-rdf/src/main/resources/qudtlib/query/quantitykind.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | PREFIX kind: 4 | PREFIX rdfs: 5 | prefix skos: 6 | PREFIX dcterms: 7 | 8 | 9 | SELECT DISTINCT * where 10 | { 11 | ?quantityKind a qudt:QuantityKind; 12 | { 13 | optional { 14 | ?quantityKind rdfs:label ?label . 15 | } 16 | optional { 17 | ?quantityKind qudt:deprecated ?deprecated 18 | } 19 | optional { 20 | ?quantityKind qudt:applicableUnit ?applicableUnit 21 | } 22 | optional { 23 | ?quantityKind qudt:hasDimensionVector ?dimensionVector 24 | } 25 | optional { 26 | ?quantityKind qudt:qkdvNumerator ?qkdvNumerator 27 | } 28 | optional { 29 | ?quantityKind qudt:qkdvDenominator ?qkdvDenominator 30 | } 31 | optional { 32 | ?quantityKind qudt:symbol ?symbol 33 | } 34 | optional { 35 | ?quantityKind skos:broader ?broaderQuantityKind 36 | } 37 | OPTIONAL { 38 | ?quantityKind dcterms:description ?description ; 39 | } 40 | } UNION { 41 | optional { 42 | ?quantityKind qudt:exactMatch ?exactMatch 43 | optional { 44 | ?exactMatch qudt:applicableUnit ?applicableUnit 45 | } 46 | optional { 47 | ?quantityKind qudt:deprecated ?deprecated 48 | } 49 | optional { 50 | ?exactMatch qudt:hasDimensionVector ?dimensionVector 51 | } 52 | optional { 53 | ?exactMatch qudt:qkdvNumerator ?qkdvNumerator 54 | } 55 | optional { 56 | ?exactMatch qudt:qkdvDenominator ?qkdvDenominator 57 | } 58 | optional { 59 | ?exactMatch qudt:symbol ?symbol 60 | } 61 | optional { 62 | ?exactMatch skos:broader ?broaderQuantityKind 63 | } 64 | OPTIONAL { 65 | ?quantityKind dcterms:description ?description ; 66 | } 67 | } 68 | } 69 | } order by ?quantityKind 70 | -------------------------------------------------------------------------------- /qudtlib-init-rdf/src/main/resources/qudtlib/query/system-of-units.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | PREFIX kind: 4 | PREFIX rdfs: 5 | prefix skos: 6 | 7 | SELECT * where 8 | { 9 | ?systemOfUnits a qudt:SystemOfUnits; 10 | rdfs:label ?label . 11 | 12 | optional { 13 | ?systemOfUnits qudt:abbreviation ?abbreviation 14 | } 15 | optional { 16 | ?systemOfUnits qudt:hasBaseUnit ?baseUnit 17 | } 18 | } order by ?systemOfUnits 19 | -------------------------------------------------------------------------------- /qudtlib-init-rdf/src/main/resources/qudtlib/query/unit.rq: -------------------------------------------------------------------------------- 1 | PREFIX qudt: 2 | PREFIX unit: 3 | PREFIX kind: 4 | PREFIX rdfs: 5 | PREFIX dcterms: 6 | 7 | 8 | 9 | SELECT * where 10 | { 11 | { 12 | ?unit a qudt:Unit; 13 | rdfs:label ?label . 14 | } UNION { 15 | ?unit a qudt:CurrencyUnit; 16 | rdfs:label ?label . 17 | } 18 | optional { 19 | ?unit qudt:exactMatch ?exactMatch 20 | } 21 | optional { 22 | ?unit qudt:generated ?generated 23 | } 24 | optional { 25 | ?unit qudt:deprecated ?deprecated 26 | } 27 | optional { 28 | ?unit qudt:hasQuantityKind ?quantityKind 29 | } 30 | optional { 31 | ?unit qudt:conversionMultiplier ?conversionMultiplier 32 | } 33 | optional { 34 | ?unit qudt:conversionOffset ?conversionOffset 35 | } 36 | optional { 37 | ?unit qudt:symbol ?symbol 38 | } 39 | optional { 40 | ?unit qudt:altSymbol ?altSymbol 41 | } 42 | optional { 43 | ?unit qudt:ucumCode ?ucumCode 44 | } 45 | optional { 46 | ?unit qudt:prefix ?prefix 47 | } 48 | optional { 49 | ?unit qudt:isScalingOf ?scalingOf 50 | } 51 | optional { 52 | ?unit qudt:hasDimensionVector ?dimensionVector 53 | } 54 | optional { 55 | ?unit qudt:currencyCode ?currencyCode 56 | } 57 | optional { 58 | ?unit qudt:currencyNumber ?currencyNumber 59 | } 60 | OPTIONAL { 61 | ?unit dcterms:description ?description ; 62 | } 63 | optional { 64 | ?unit qudt:applicableSystem|qudt:systemOfUnit|qudt:baseUnitOfSystem|qudt:derivedCoherentUnitOfSystem|qudt:derivedNonCoherentUnitOfSystem|qudt:derivedUnitOfSystem|qudt:coherentUnitOfSystem|qudt:definedUnitOfSystem|qudt:allowedUnitOfSystem ?systemOfUnits 65 | } 66 | } order by ?unit 67 | -------------------------------------------------------------------------------- /qudtlib-js-gen/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | qudtlib-java 5 | io.github.qudtlib 6 | 6.8.2-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | qudtlib-js-gen 11 | 12 | 13 | 14 | io.github.qudtlib 15 | qudtlib-init-hardcoded 16 | ${project.version} 17 | 18 | 19 | io.github.qudtlib 20 | qudtlib-main 21 | ${project.version} 22 | 23 | 24 | io.github.qudtlib 25 | qudtlib-common-codegen 26 | ${project.version} 27 | 28 | 29 | 30 | 31 | 32 | org.codehaus.mojo 33 | exec-maven-plugin 34 | 35 | 36 | 37 | java 38 | 39 | prepare-package 40 | 41 | 42 | 43 | false 44 | true 45 | true 46 | io.github.qudtlib.HardcodedTypescriptModelGenerator 47 | 48 | ${project.build.directory}/../../qudtlib-js/allunits/src/ 49 | 50 | 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-deploy-plugin 55 | 56 | true 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /qudtlib-main-rdf/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | qudtlib-java 5 | io.github.qudtlib 6 | 6.8.2-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | qudtlib-main-rdf 11 | jar 12 | 13 | 14 | 15 | io.github.qudtlib 16 | qudtlib-main 17 | ${project.version} 18 | 19 | 20 | io.github.qudtlib 21 | qudtlib-init-rdf 22 | ${project.version} 23 | 24 | 25 | io.github.qudtlib 26 | qudtlib-test 27 | ${project.version} 28 | tests 29 | test-jar 30 | test 31 | 32 | 33 | org.junit.jupiter 34 | junit-jupiter 35 | test 36 | 37 | 38 | 39 | 40 | 41 | 42 | org.apache.maven.plugins 43 | maven-surefire-plugin 44 | 45 | 46 | io.github.qudtlib:qudtlib-test:test-jar:tests 47 | 48 | 49 | 50 | 51 | org.apache.maven.plugins 52 | maven-assembly-plugin 53 | 54 | 55 | package 56 | 57 | single 58 | 59 | 60 | 61 | 62 | 63 | jar-with-dependencies 64 | 65 | 66 | 67 | 68 | org.apache.maven.plugins 69 | maven-deploy-plugin 70 | 71 | true 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /qudtlib-main-rdf/src/test/java/io/github/qudtlib/QudtMainForDebugging.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib; 2 | 3 | import io.github.qudtlib.model.Unit; 4 | import java.util.stream.Collectors; 5 | 6 | public class QudtMainForDebugging { 7 | public static void main(String[] args) { 8 | System.out.println("Initializing QUDT"); 9 | Unit unit = Qudt.Units.M; 10 | System.out.println("All qudt units in QUDTLib:"); 11 | System.out.println( 12 | Qudt.allUnits().stream() 13 | .map(Unit::getIriAbbreviated) 14 | .collect(Collectors.joining("\n"))); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /qudtlib-main/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | qudtlib-java 5 | io.github.qudtlib 6 | 6.8.2-SNAPSHOT 7 | 8 | 4.0.0 9 | qudtlib-main 10 | jar 11 | 12 | 13 | io.github.qudtlib 14 | qudtlib-model 15 | ${project.version} 16 | 17 | 18 | org.apache.commons 19 | commons-collections4 20 | 21 | 22 | 23 | src/main/java 24 | 25 | 26 | org.codehaus.mojo 27 | exec-maven-plugin 28 | 29 | 30 | 31 | java 32 | 33 | generate-resources 34 | 35 | 36 | 37 | true 38 | true 39 | io.github.qudtlib.constgen.ConstantsGenerator 40 | 41 | ${project.build.directory}/generated-sources 42 | 43 | 44 | 45 | 46 | io.github.qudtlib 47 | qudtlib-constants-gen 48 | ${project.version} 49 | 50 | 51 | 52 | 53 | org.codehaus.mojo 54 | build-helper-maven-plugin 55 | 56 | 57 | generate-sources 58 | 59 | add-source 60 | 61 | 62 | 63 | ${project.build.directory}/generated-sources/ 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /qudtlib-main/src/main/java/io/github/qudtlib/support/fractional/FractionalDimensionVector.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.support.fractional; 2 | 3 | import io.github.qudtlib.model.FactorUnit; 4 | import io.github.qudtlib.model.FactorUnits; 5 | import java.util.List; 6 | import java.util.Objects; 7 | import java.util.Optional; 8 | 9 | public class FractionalDimensionVector { 10 | private String numerator; 11 | private String denominator; 12 | 13 | public FractionalDimensionVector(String numerator, String denominator) { 14 | this.numerator = numerator; 15 | this.denominator = denominator; 16 | } 17 | 18 | public FractionalDimensionVector(FactorUnits numerator, FactorUnits denominator) { 19 | this.numerator = numerator.getDimensionVectorIri(); 20 | this.denominator = denominator.getDimensionVectorIri(); 21 | } 22 | 23 | public FractionalDimensionVector(List numerator, List denominator) { 24 | this.numerator = new FactorUnits(numerator).getDimensionVectorIri(); 25 | this.denominator = new FactorUnits(denominator).getDimensionVectorIri(); 26 | } 27 | 28 | public static FractionalDimensionVector onlyNumerator(String dimensionVector) { 29 | return new FractionalDimensionVector(dimensionVector, null); 30 | } 31 | 32 | public static FractionalDimensionVector onlyDenominator(String dimensionVector) { 33 | return new FractionalDimensionVector(null, dimensionVector); 34 | } 35 | 36 | public Optional getNumerator() { 37 | return Optional.ofNullable(numerator); 38 | } 39 | 40 | public Optional getDenominator() { 41 | return Optional.ofNullable(denominator); 42 | } 43 | 44 | @Override 45 | public boolean equals(Object o) { 46 | if (this == o) return true; 47 | if (!(o instanceof FractionalDimensionVector)) return false; 48 | FractionalDimensionVector that = (FractionalDimensionVector) o; 49 | return Objects.equals(getNumerator(), that.getNumerator()) 50 | && Objects.equals(getDenominator(), that.getDenominator()); 51 | } 52 | 53 | @Override 54 | public int hashCode() { 55 | return Objects.hash(getNumerator(), getDenominator()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /qudtlib-main/src/main/java/io/github/qudtlib/support/fractional/FractionalUnits.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.support.fractional; 2 | 3 | import io.github.qudtlib.Qudt; 4 | import io.github.qudtlib.exception.NotFoundException; 5 | import io.github.qudtlib.model.FactorUnit; 6 | import io.github.qudtlib.model.Unit; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.regex.Matcher; 10 | import java.util.regex.Pattern; 11 | 12 | public class FractionalUnits { 13 | 14 | public static FractionalDimensionVector getFractionalDimensionVector(Unit unit) { 15 | String[] unitNameConstituents = getIriLocalname(unit.getIri()).split("-"); 16 | List numerator = new ArrayList<>(); 17 | List denominator = new ArrayList<>(); 18 | List currentFactors = numerator; 19 | for (String currentUnitNameConstituent : unitNameConstituents) { 20 | FactorUnit found = null; 21 | if (currentUnitNameConstituent.equals("PER")) { 22 | currentFactors = denominator; 23 | continue; 24 | } 25 | Pattern p = Pattern.compile("(.+)(-?\\d)?"); 26 | Matcher m = p.matcher(currentUnitNameConstituent); 27 | if (!m.find()) { 28 | throw new RuntimeException( 29 | String.format( 30 | "Name particle %s of unit %s does not seem to be a factor unit", 31 | currentUnitNameConstituent, unit.getIri())); 32 | } 33 | String unitName = m.group(1); 34 | Unit currentFactorUnit = null; 35 | try { 36 | currentFactorUnit = Qudt.unitFromLocalnameRequired(unitName); 37 | } catch (NotFoundException e) { 38 | try { 39 | currentFactorUnit = Qudt.currencyFromLocalnameRequired(unitName); 40 | } catch (NotFoundException e2) { 41 | throw new RuntimeException( 42 | String.format( 43 | "Name particle %s of unit %s is not a QUDT unit or currency", 44 | currentUnitNameConstituent, unit.getIri()), 45 | e2); 46 | } 47 | } 48 | String exponentStr = m.group(2); 49 | int currentExponent = 1; 50 | if (exponentStr != null) { 51 | currentExponent = Integer.valueOf(exponentStr); 52 | } 53 | currentExponent = Math.abs(currentExponent); 54 | currentFactors.add(new FactorUnit(currentFactorUnit, currentExponent)); 55 | } 56 | return new FractionalDimensionVector(numerator, denominator); 57 | } 58 | 59 | private static String getIriLocalname(String iri) { 60 | if (iri == null) { 61 | return null; 62 | } 63 | for (int i = iri.length(); i >= 0; i--) { 64 | Character ch = iri.charAt(i - 1); 65 | if (ch == '/' || ch == '#') { 66 | return iri.substring(i); 67 | } 68 | } 69 | return ""; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /qudtlib-main/src/main/java/io/github/qudtlib/support/index/Flag.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.support.index; 2 | 3 | public enum Flag { 4 | NOTHING(0), 5 | CASE_INSENSITIVE(1), 6 | MATCH_PREFIX(2); 7 | 8 | private int bits; 9 | 10 | Flag(int bits) { 11 | this.bits = bits; 12 | } 13 | 14 | public int getBits() { 15 | return bits; 16 | } 17 | 18 | public static class FlagCombination { 19 | private int bits = 0; 20 | 21 | public int getBits() { 22 | return bits; 23 | } 24 | 25 | public FlagCombination matchPrefix(boolean chosen) { 26 | bits = combineIfChosen(chosen, MATCH_PREFIX); 27 | return this; 28 | } 29 | 30 | public FlagCombination caseInsensitive(boolean chosen) { 31 | bits = combineIfChosen(chosen, CASE_INSENSITIVE); 32 | return this; 33 | } 34 | 35 | private int combineIfChosen(boolean choose, Flag caseInsensitive) { 36 | return choose ? bits | caseInsensitive.getBits() : bits; 37 | } 38 | } 39 | 40 | public static FlagCombination caseInsensitive(boolean choose) { 41 | return combination().caseInsensitive(choose); 42 | } 43 | 44 | public static FlagCombination matchPrefix(boolean choose) { 45 | return combination().matchPrefix(choose); 46 | } 47 | 48 | public static FlagCombination combination() { 49 | return new FlagCombination(); 50 | } 51 | 52 | public static int combine(Flag... flags) { 53 | int result = 0; 54 | for (Flag flag : flags) { 55 | result = result | flag.bits; 56 | } 57 | return result; 58 | } 59 | 60 | public static boolean isSet(int bits, Flag flag) { 61 | return (bits & flag.bits) == flag.bits; 62 | } 63 | 64 | public static boolean isCaseInsensitive(int bits) { 65 | return isSet(bits, CASE_INSENSITIVE); 66 | } 67 | 68 | public static boolean isMatchPrefix(int bits) { 69 | return isSet(bits, MATCH_PREFIX); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /qudtlib-main/src/main/java/io/github/qudtlib/support/index/MultivaluePatriciaTrie.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.support.index; 2 | 3 | import java.util.*; 4 | import java.util.stream.Collectors; 5 | import org.apache.commons.collections4.trie.PatriciaTrie; 6 | 7 | public class MultivaluePatriciaTrie { 8 | 9 | private final PatriciaTrie> delegate = new PatriciaTrie<>(); 10 | 11 | public MultivaluePatriciaTrie() {} 12 | 13 | public void put(String key, V value) { 14 | delegate.compute( 15 | key, 16 | (k, values) -> { 17 | if (values == null) { 18 | values = new HashSet<>(); 19 | } 20 | values.add(value); 21 | return values; 22 | }); 23 | } 24 | 25 | public Set getByPrefixMatch(String prefix) { 26 | return delegate.prefixMap(prefix).values().stream() 27 | .flatMap(Set::stream) 28 | .collect(Collectors.toSet()); 29 | } 30 | 31 | public Set get(String k) { 32 | Set set = delegate.get(k); 33 | if (set == null) { 34 | return Set.of(); 35 | } 36 | return set.stream().collect(Collectors.toUnmodifiableSet()); 37 | } 38 | 39 | public void clear() { 40 | delegate.clear(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /qudtlib-main/src/main/java/io/github/qudtlib/support/index/SearchIndex.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.support.index; 2 | 3 | import java.util.Locale; 4 | import java.util.Set; 5 | 6 | public class SearchIndex { 7 | 8 | private MultivaluePatriciaTrie trie = new MultivaluePatriciaTrie(); 9 | private final boolean caseInsensitive; 10 | 11 | public void clear() { 12 | trie.clear(); 13 | } 14 | 15 | public SearchIndex(boolean caseInsensitive) { 16 | this.caseInsensitive = caseInsensitive; 17 | } 18 | 19 | public void put(String key, V value) { 20 | trie.put(key, value); 21 | if (this.caseInsensitive) { 22 | trie.put(key.toUpperCase(Locale.ROOT), value); 23 | } 24 | } 25 | 26 | public Set get(String prefix, int flags) { 27 | String search = prefix; 28 | if (Flag.isCaseInsensitive(flags)) { 29 | search = search.toUpperCase(Locale.ROOT); 30 | } 31 | if (Flag.isMatchPrefix(flags)) { 32 | return trie.getByPrefixMatch(search); 33 | } 34 | return trie.get(search); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /qudtlib-main/src/main/java/io/github/qudtlib/support/parse/AbstractStateTransition.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.support.parse; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Deque; 5 | import java.util.List; 6 | import java.util.regex.Matcher; 7 | import java.util.regex.Pattern; 8 | 9 | abstract class AbstractStateTransition implements StateTransition { 10 | private final String name; 11 | private final Pattern pattern; 12 | 13 | public AbstractStateTransition(String name, Pattern pattern) { 14 | this.name = name; 15 | this.pattern = pattern; 16 | } 17 | 18 | @Override 19 | public boolean mayMatchLater(String string) { 20 | return pattern.matcher(string).matches(); 21 | } 22 | 23 | @Override 24 | public final List apply(State state) { 25 | Matcher m = getMatcher(state); 26 | String matchedToken = null; 27 | if (!m.matches()) { 28 | return List.of(); 29 | } 30 | matchedToken = m.group(); 31 | List result = 32 | parse( 33 | state, 34 | matchedToken, 35 | new ArrayList<>(getAllowedNextTransitions()), 36 | new ArrayList<>(getRequiredClosingTransitions())); 37 | return result; 38 | } 39 | 40 | protected abstract List parse( 41 | State state, 42 | String matchedToken, 43 | List nextTransitions, 44 | List requiredClosingTransitions); 45 | 46 | /** 47 | * Used to enforce ')' when '(' is encountered 48 | * 49 | * @return 50 | */ 51 | protected abstract List getRequiredClosingTransitions(); 52 | 53 | protected abstract List getAllowedNextTransitions(); 54 | 55 | private Matcher getMatcher(State state) { 56 | return getPattern().matcher(state.getMatchableInput()); 57 | } 58 | 59 | private Pattern getPattern() { 60 | return this.pattern; 61 | } 62 | 63 | protected void pushTransitions( 64 | Deque> transitionStack, List transitions) { 65 | if (transitions != null && !transitions.isEmpty()) { 66 | transitionStack.push(transitions); 67 | } 68 | } 69 | 70 | public String toString() { 71 | return name; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /qudtlib-main/src/main/java/io/github/qudtlib/support/parse/ClosingBracketTransition.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.support.parse; 2 | 3 | import java.util.ArrayDeque; 4 | import java.util.Deque; 5 | import java.util.List; 6 | import java.util.regex.Pattern; 7 | 8 | class ClosingBracketTransition extends AbstractStateTransition { 9 | private static final Pattern P_CLOSING_BRACKET = Pattern.compile("\\)"); 10 | 11 | public ClosingBracketTransition() { 12 | super("ClosingBracket", P_CLOSING_BRACKET); 13 | } 14 | 15 | @Override 16 | public boolean mayMatchLater(String string) { 17 | return P_CLOSING_BRACKET.matcher(string).matches(); 18 | } 19 | 20 | @Override 21 | protected List parse( 22 | State state, 23 | String matchedToken, 24 | List nextTransitions, 25 | List requiredClosingTransitions) { 26 | Deque> transitionStack = 27 | new ArrayDeque<>(state.getStateTransitionStack()); 28 | if (!state.isDividerSeen() && !state.isNegativeExponentSeen()) { 29 | nextTransitions.add(StateTransition.DIVIDER); 30 | } 31 | pushTransitions(transitionStack, requiredClosingTransitions); 32 | pushTransitions(transitionStack, nextTransitions); 33 | return List.of( 34 | new State( 35 | state.remainingInputForNextState(), 36 | null, 37 | state.getParsedUnits(), 38 | state.isDividerSeen(), 39 | state.isNegativeExponentSeen(), 40 | transitionStack)); 41 | } 42 | 43 | @Override 44 | protected List getRequiredClosingTransitions() { 45 | return List.of(); 46 | } 47 | 48 | @Override 49 | protected List getAllowedNextTransitions() { 50 | return List.of( 51 | StateTransition.UNIT, StateTransition.WHITESPACE, StateTransition.OPENING_BRACKET); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /qudtlib-main/src/main/java/io/github/qudtlib/support/parse/DividerTransition.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.support.parse; 2 | 3 | import java.util.ArrayDeque; 4 | import java.util.Deque; 5 | import java.util.List; 6 | import java.util.regex.Pattern; 7 | 8 | class DividerTransition extends AbstractStateTransition { 9 | 10 | private static final Pattern P_DIVIDER = 11 | Pattern.compile("(/|per|pro|je|par|por)", Pattern.CASE_INSENSITIVE); 12 | 13 | public DividerTransition() { 14 | super("Divider", P_DIVIDER); 15 | } 16 | 17 | @Override 18 | public boolean mayMatchLater(String string) { 19 | return List.of("/", "per", "pro", "je", "par", "por").stream() 20 | .anyMatch(s -> s.toUpperCase().startsWith(string.toUpperCase())); 21 | } 22 | 23 | @Override 24 | protected List parse( 25 | State state, 26 | String matchedToken, 27 | List nextTransitions, 28 | List requiredClosingTransitions) { 29 | if (state.isDividerSeen()) { 30 | throw new IllegalStateException( 31 | String.format("Already seen divider, not allowed twice! State: %s", state)); 32 | } 33 | Deque> transitionStack = 34 | new ArrayDeque<>(state.getStateTransitionStack()); 35 | pushTransitions(transitionStack, requiredClosingTransitions); 36 | pushTransitions(transitionStack, nextTransitions); 37 | return List.of(state.withDividerSeen(state.remainingInputForNextState(), transitionStack)); 38 | } 39 | 40 | @Override 41 | protected List getRequiredClosingTransitions() { 42 | return List.of(); 43 | } 44 | 45 | @Override 46 | protected List getAllowedNextTransitions() { 47 | return List.of( 48 | StateTransition.UNIT, StateTransition.WHITESPACE, StateTransition.OPENING_BRACKET); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /qudtlib-main/src/main/java/io/github/qudtlib/support/parse/DotTransition.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.support.parse; 2 | 3 | import java.util.ArrayDeque; 4 | import java.util.Deque; 5 | import java.util.List; 6 | import java.util.regex.Pattern; 7 | 8 | class DotTransition extends AbstractStateTransition { 9 | private static final Pattern P_DOT = Pattern.compile("[·*.]"); 10 | 11 | public DotTransition() { 12 | super("Dot", P_DOT); 13 | } 14 | 15 | @Override 16 | protected List parse( 17 | State state, 18 | String matchedToken, 19 | List nextTransitions, 20 | List requiredClosingTransitions) { 21 | Deque> transitionStack = 22 | new ArrayDeque<>(state.getStateTransitionStack()); 23 | pushTransitions(transitionStack, requiredClosingTransitions); 24 | pushTransitions(transitionStack, nextTransitions); 25 | return List.of( 26 | new State( 27 | state.remainingInputForNextState(), 28 | null, 29 | state.getParsedUnits(), 30 | state.isDividerSeen(), 31 | state.isNegativeExponentSeen(), 32 | transitionStack)); 33 | } 34 | 35 | @Override 36 | protected List getRequiredClosingTransitions() { 37 | return List.of(); 38 | } 39 | 40 | @Override 41 | protected List getAllowedNextTransitions() { 42 | return List.of( 43 | StateTransition.UNIT, StateTransition.WHITESPACE, StateTransition.OPENING_BRACKET); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /qudtlib-main/src/main/java/io/github/qudtlib/support/parse/ExponentTransition.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.support.parse; 2 | 3 | import java.util.*; 4 | import java.util.regex.Pattern; 5 | 6 | class ExponentTransition extends AbstractStateTransition { 7 | private static final Pattern P_EXPONENT = Pattern.compile("\\^?[-⁻]?[\\d¹²³⁴⁵⁶⁷⁸⁹⁰]"); 8 | private static final Pattern P_PARTIAL = Pattern.compile("\\^?[-⁻]?"); 9 | 10 | public ExponentTransition() { 11 | super("Exponent", P_EXPONENT); 12 | } 13 | 14 | @Override 15 | public boolean mayMatchLater(String string) { 16 | return P_PARTIAL.matcher(string).matches() || P_EXPONENT.matcher(string).matches(); 17 | } 18 | 19 | @Override 20 | protected List parse( 21 | State state, 22 | String matchedToken, 23 | List nextTransitions, 24 | List requiredClosingTransitions) { 25 | String sanitizedExponent = 26 | matchedToken 27 | .replaceFirst("\\^", "") 28 | .replaceAll("¹", "1") 29 | .replaceAll("²", "2") 30 | .replaceAll("³", "3") 31 | .replaceAll("⁴", "4") 32 | .replaceAll("⁵", "5") 33 | .replaceAll("⁶", "6") 34 | .replaceAll("⁷", "7") 35 | .replaceAll("⁸", "8") 36 | .replaceAll("⁹", "9") 37 | .replaceAll("⁰", "0") 38 | .replaceAll("⁻", "-"); 39 | int parsedExponent = Integer.valueOf(sanitizedExponent); 40 | if (state.isDividerSeen() && parsedExponent < 0) { 41 | return List.of(); 42 | } 43 | if (parsedExponent == 0) { 44 | return List.of(); 45 | } 46 | List parsedUnitsBase = state.getParsedUnits(); 47 | if (parsedUnitsBase.isEmpty()) { 48 | return List.of(); 49 | } 50 | ParsedUnit toModify = parsedUnitsBase.remove(parsedUnitsBase.size() - 1); 51 | ParsedUnit modified = toModify.pow(parsedExponent, matchedToken); 52 | parsedUnitsBase.add(modified); 53 | Deque> transitionStack = 54 | new ArrayDeque<>(state.getStateTransitionStack()); 55 | if (!state.isAtEnd() 56 | && !state.isDividerSeen() 57 | && parsedExponent > 0 58 | && !state.isNegativeExponentSeen()) { 59 | nextTransitions.add(StateTransition.DIVIDER); 60 | } 61 | pushTransitions(transitionStack, requiredClosingTransitions); 62 | pushTransitions(transitionStack, nextTransitions); 63 | return List.of( 64 | new State( 65 | state.remainingInputForNextState(), 66 | null, 67 | parsedUnitsBase, 68 | state.isDividerSeen(), 69 | parsedExponent < 0, 70 | transitionStack)); 71 | } 72 | 73 | @Override 74 | protected List getRequiredClosingTransitions() { 75 | return List.of(); 76 | } 77 | 78 | @Override 79 | protected List getAllowedNextTransitions() { 80 | return List.of( 81 | StateTransition.UNIT, 82 | StateTransition.DOT, 83 | StateTransition.WHITESPACE, 84 | StateTransition.OPENING_BRACKET); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /qudtlib-main/src/main/java/io/github/qudtlib/support/parse/OneTransition.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.support.parse; 2 | 3 | import java.util.ArrayDeque; 4 | import java.util.Deque; 5 | import java.util.List; 6 | import java.util.regex.Pattern; 7 | 8 | class OneTransition extends AbstractStateTransition { 9 | private static final Pattern P_ONE = Pattern.compile("1"); 10 | 11 | public OneTransition() { 12 | super("One", P_ONE); 13 | } 14 | 15 | @Override 16 | protected List parse( 17 | State state, 18 | String matchedToken, 19 | List nextTransitions, 20 | List requiredClosingTransitions) { 21 | Deque> transitionStack = 22 | new ArrayDeque<>(state.getStateTransitionStack()); 23 | if (!state.isDividerSeen() && !state.isNegativeExponentSeen()) { 24 | nextTransitions.add(StateTransition.DIVIDER); 25 | } 26 | pushTransitions(transitionStack, requiredClosingTransitions); 27 | pushTransitions(transitionStack, nextTransitions); 28 | return List.of( 29 | new State( 30 | state.remainingInputForNextState(), 31 | null, 32 | state.getParsedUnits(), 33 | state.isDividerSeen(), 34 | state.isNegativeExponentSeen(), 35 | transitionStack)); 36 | } 37 | 38 | @Override 39 | protected List getRequiredClosingTransitions() { 40 | return List.of(); 41 | } 42 | 43 | @Override 44 | protected List getAllowedNextTransitions() { 45 | return List.of(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /qudtlib-main/src/main/java/io/github/qudtlib/support/parse/OpeningBracketTransition.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.support.parse; 2 | 3 | import java.util.ArrayDeque; 4 | import java.util.Deque; 5 | import java.util.List; 6 | import java.util.regex.Pattern; 7 | 8 | class OpeningBracketTransition extends AbstractStateTransition { 9 | private static final Pattern P_OPENING_BRACKET = Pattern.compile("\\("); 10 | 11 | public OpeningBracketTransition() { 12 | super("OpeningBracket", P_OPENING_BRACKET); 13 | } 14 | 15 | @Override 16 | protected List parse( 17 | State state, 18 | String matchedToken, 19 | List nextTransitions, 20 | List requiredClosingTransitions) { 21 | Deque> transitionStack = 22 | new ArrayDeque<>(state.getStateTransitionStack()); 23 | pushTransitions(transitionStack, requiredClosingTransitions); 24 | pushTransitions(transitionStack, nextTransitions); 25 | return List.of( 26 | new State( 27 | state.remainingInputForNextState(), 28 | null, 29 | state.getParsedUnits(), 30 | state.isDividerSeen(), 31 | state.isNegativeExponentSeen(), 32 | transitionStack)); 33 | } 34 | 35 | @Override 36 | protected List getRequiredClosingTransitions() { 37 | return List.of(StateTransition.CLOSING_BRACKET); 38 | } 39 | 40 | @Override 41 | protected List getAllowedNextTransitions() { 42 | return List.of(StateTransition.UNIT, StateTransition.WHITESPACE); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /qudtlib-main/src/main/java/io/github/qudtlib/support/parse/ParsedUnit.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.support.parse; 2 | 3 | import io.github.qudtlib.model.FactorUnit; 4 | import java.util.Objects; 5 | 6 | public class ParsedUnit { 7 | private final FactorUnit factorUnit; 8 | private final String token; 9 | 10 | public ParsedUnit(FactorUnit factorUnit, String token) { 11 | this.factorUnit = factorUnit; 12 | this.token = token; 13 | } 14 | 15 | public FactorUnit getFactorUnit() { 16 | return factorUnit; 17 | } 18 | 19 | public String getToken() { 20 | return token; 21 | } 22 | 23 | public ParsedUnit pow(int exponent, String token) { 24 | return new ParsedUnit(factorUnit.pow(exponent), this.token + token); 25 | } 26 | 27 | @Override 28 | public boolean equals(Object o) { 29 | if (this == o) return true; 30 | if (o == null || getClass() != o.getClass()) return false; 31 | ParsedUnit that = (ParsedUnit) o; 32 | return Objects.equals(factorUnit, that.factorUnit) && Objects.equals(token, that.token); 33 | } 34 | 35 | @Override 36 | public int hashCode() { 37 | return Objects.hash(factorUnit, token); 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return "ParsedUnit{" + "factorUnit=" + factorUnit + ", token='" + token + '\'' + '}'; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /qudtlib-main/src/main/java/io/github/qudtlib/support/parse/StateTransition.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.support.parse; 2 | 3 | import java.util.List; 4 | import java.util.function.Function; 5 | 6 | interface StateTransition extends Function> { 7 | 8 | boolean mayMatchLater(String string); 9 | 10 | DividerTransition DIVIDER = new DividerTransition(); 11 | UnitTransition UNIT = new UnitTransition(); 12 | ExponentTransition EXPONENT = new ExponentTransition(); 13 | DotTransition DOT = new DotTransition(); 14 | WhitespaceTransition WHITESPACE = new WhitespaceTransition(); 15 | OpeningBracketTransition OPENING_BRACKET = new OpeningBracketTransition(); 16 | ClosingBracketTransition CLOSING_BRACKET = new ClosingBracketTransition(); 17 | OneTransition ONE = new OneTransition(); 18 | } 19 | -------------------------------------------------------------------------------- /qudtlib-main/src/main/java/io/github/qudtlib/support/parse/WhitespaceTransition.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.support.parse; 2 | 3 | import java.util.ArrayDeque; 4 | import java.util.Deque; 5 | import java.util.List; 6 | import java.util.regex.Pattern; 7 | 8 | class WhitespaceTransition extends AbstractStateTransition { 9 | private static final Pattern P_SPACE = Pattern.compile("\\s"); 10 | 11 | public WhitespaceTransition() { 12 | super("Whitespace", P_SPACE); 13 | } 14 | 15 | @Override 16 | protected List parse( 17 | State state, 18 | String matchedToken, 19 | List nextTransitions, 20 | List requiredClosingTransitions) { 21 | Deque> transitionStack = 22 | new ArrayDeque<>(state.getStateTransitionStack()); 23 | if (!state.isDividerSeen() && !state.isNegativeExponentSeen()) { 24 | nextTransitions.add(StateTransition.DIVIDER); 25 | } 26 | pushTransitions(transitionStack, requiredClosingTransitions); 27 | pushTransitions(transitionStack, nextTransitions); 28 | return List.of( 29 | new State( 30 | state.remainingInputForNextState(), 31 | null, 32 | state.getParsedUnits(), 33 | state.isDividerSeen(), 34 | state.isNegativeExponentSeen(), 35 | transitionStack)); 36 | } 37 | 38 | @Override 39 | protected List getRequiredClosingTransitions() { 40 | return List.of(); 41 | } 42 | 43 | @Override 44 | protected List getAllowedNextTransitions() { 45 | return List.of( 46 | StateTransition.UNIT, 47 | StateTransition.DOT, 48 | StateTransition.EXPONENT, 49 | StateTransition.WHITESPACE, 50 | StateTransition.OPENING_BRACKET); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /qudtlib-model/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | qudtlib-java 5 | io.github.qudtlib 6 | 6.8.2-SNAPSHOT 7 | 8 | 4.0.0 9 | jar 10 | qudtlib-model 11 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/exception/IncompleteDataException.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.exception; 2 | 3 | public class IncompleteDataException extends QudtException { 4 | public IncompleteDataException() {} 5 | 6 | public IncompleteDataException(String message) { 7 | super(message); 8 | } 9 | 10 | public IncompleteDataException(String message, Throwable cause) { 11 | super(message, cause); 12 | } 13 | 14 | public IncompleteDataException(Throwable cause) { 15 | super(cause); 16 | } 17 | 18 | public IncompleteDataException( 19 | String message, 20 | Throwable cause, 21 | boolean enableSuppression, 22 | boolean writableStackTrace) { 23 | super(message, cause, enableSuppression, writableStackTrace); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/exception/InconvertibleQuantitiesException.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.exception; 2 | 3 | /** 4 | * Indicates that quantities cannot be converted. 5 | * 6 | * @author Florian Kleedorfer 7 | * @version 1.0 8 | */ 9 | public class InconvertibleQuantitiesException extends QudtException { 10 | public InconvertibleQuantitiesException() {} 11 | 12 | public InconvertibleQuantitiesException(String message) { 13 | super(message); 14 | } 15 | 16 | public InconvertibleQuantitiesException(String message, Throwable cause) { 17 | super(message, cause); 18 | } 19 | 20 | public InconvertibleQuantitiesException(Throwable cause) { 21 | super(cause); 22 | } 23 | 24 | public InconvertibleQuantitiesException( 25 | String message, 26 | Throwable cause, 27 | boolean enableSuppression, 28 | boolean writableStackTrace) { 29 | super(message, cause, enableSuppression, writableStackTrace); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/exception/NonUniqueResultException.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.exception; 2 | 3 | /** 4 | * Indicates that a unique result was expected, but multiple found. 5 | * 6 | * @author Florian Kleedorfer 7 | * @version 1.0 8 | */ 9 | public class NonUniqueResultException extends QudtException { 10 | public NonUniqueResultException() {} 11 | 12 | public NonUniqueResultException(String message) { 13 | super(message); 14 | } 15 | 16 | public NonUniqueResultException(String message, Throwable cause) { 17 | super(message, cause); 18 | } 19 | 20 | public NonUniqueResultException(Throwable cause) { 21 | super(cause); 22 | } 23 | 24 | public NonUniqueResultException( 25 | String message, 26 | Throwable cause, 27 | boolean enableSuppression, 28 | boolean writableStackTrace) { 29 | super(message, cause, enableSuppression, writableStackTrace); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/exception/NotFoundException.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.exception; 2 | 3 | /** 4 | * Indicates that an expected result was not found. 5 | * 6 | * @author Florian Kleedorfer 7 | * @version 1.0 8 | */ 9 | public class NotFoundException extends QudtException { 10 | public NotFoundException() {} 11 | 12 | public NotFoundException(String message) { 13 | super(message); 14 | } 15 | 16 | public NotFoundException(String message, Throwable cause) { 17 | super(message, cause); 18 | } 19 | 20 | public NotFoundException(Throwable cause) { 21 | super(cause); 22 | } 23 | 24 | public NotFoundException( 25 | String message, 26 | Throwable cause, 27 | boolean enableSuppression, 28 | boolean writableStackTrace) { 29 | super(message, cause, enableSuppression, writableStackTrace); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/exception/QudtException.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.exception; 2 | 3 | /** 4 | * Base excetpion for QUDTLib. 5 | * 6 | * @author Florian Kleedorfer 7 | * @version 1.0 8 | */ 9 | public class QudtException extends RuntimeException { 10 | public QudtException() {} 11 | 12 | public QudtException(String message) { 13 | super(message); 14 | } 15 | 16 | public QudtException(String message, Throwable cause) { 17 | super(message, cause); 18 | } 19 | 20 | public QudtException(Throwable cause) { 21 | super(cause); 22 | } 23 | 24 | public QudtException( 25 | String message, 26 | Throwable cause, 27 | boolean enableSuppression, 28 | boolean writableStackTrace) { 29 | super(message, cause, enableSuppression, writableStackTrace); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/exception/QudtInitializationException.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.exception; 2 | 3 | /** 4 | * Indicates that something went wrong during intialization of the QUDTLib system. 5 | * 6 | * @author Florian Kleedorfer 7 | * @version 1.0 8 | */ 9 | public class QudtInitializationException extends QudtException { 10 | public QudtInitializationException() {} 11 | 12 | public QudtInitializationException(String message) { 13 | super(message); 14 | } 15 | 16 | public QudtInitializationException(String message, Throwable cause) { 17 | super(message, cause); 18 | } 19 | 20 | public QudtInitializationException(Throwable cause) { 21 | super(cause); 22 | } 23 | 24 | public QudtInitializationException( 25 | String message, 26 | Throwable cause, 27 | boolean enableSuppression, 28 | boolean writableStackTrace) { 29 | super(message, cause, enableSuppression, writableStackTrace); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/math/BigDec.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.math; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.MathContext; 5 | import java.util.Objects; 6 | 7 | public class BigDec { 8 | 9 | public static final BigDecimal ONE_THOUSANDTH = new BigDecimal("0.001"); 10 | public static final BigDecimal ONE_MILLIONTH = new BigDecimal("0.000001"); 11 | 12 | public static boolean isRelativeDifferenceGreaterThan( 13 | BigDecimal left, BigDecimal right, BigDecimal epsilon) { 14 | return greaterThan(relativeValueDifference(left, right), epsilon); 15 | } 16 | 17 | /** 18 | * Returns the difference between the two values in relation to the value of their mean 19 | * 20 | * @return 21 | */ 22 | static BigDecimal relativeValueDifference(BigDecimal left, BigDecimal right) { 23 | Objects.requireNonNull(left); 24 | Objects.requireNonNull(right); 25 | BigDecimal mean = 26 | left.add(right) 27 | .divide(BigDecimal.valueOf(2), MathContext.DECIMAL128) 28 | .abs(MathContext.DECIMAL128); 29 | BigDecimal diff = 30 | left.abs(MathContext.DECIMAL128) 31 | .subtract(right.abs(MathContext.DECIMAL128)) 32 | .abs(MathContext.DECIMAL128); 33 | if (BigDecimal.ZERO.compareTo(mean) == 0) { 34 | return diff.abs(MathContext.DECIMAL128); 35 | } 36 | return diff.divide(mean, MathContext.DECIMAL128).abs(); 37 | } 38 | 39 | static boolean greaterThan(BigDecimal left, BigDecimal right) { 40 | Objects.requireNonNull(left); 41 | Objects.requireNonNull(right); 42 | return left.subtract(right).signum() > 0; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/model/DerivedUnitSearchMode.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.model; 2 | 3 | /** Governs the algorithm used to find units based on their derived units. */ 4 | public enum DerivedUnitSearchMode { 5 | /** Return all matching units. */ 6 | ALL, 7 | /** Return the best matching unit. */ 8 | BEST_MATCH 9 | } 10 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/model/FactorUnitMatch.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.model; 2 | 3 | import java.math.BigDecimal; 4 | import java.util.*; 5 | 6 | /** Represents a unit that has been matched in a FactorUnitSelection. */ 7 | public class FactorUnitMatch { 8 | private final FactorUnit matchedFactorUnit; 9 | private final List matchedPath; 10 | private final BigDecimal matchedMultiplier; 11 | 12 | public FactorUnitMatch( 13 | FactorUnit matchedFactorUnit, 14 | BigDecimal matchedMultiplier, 15 | Collection matchedPath) { 16 | Objects.requireNonNull(matchedFactorUnit); 17 | Objects.requireNonNull(matchedPath); 18 | Objects.requireNonNull(matchedMultiplier); 19 | this.matchedFactorUnit = matchedFactorUnit; 20 | this.matchedPath = Collections.unmodifiableList(new ArrayList<>(matchedPath)); 21 | this.matchedMultiplier = matchedMultiplier; 22 | } 23 | 24 | public FactorUnit getMatchedFactorUnit() { 25 | return matchedFactorUnit; 26 | } 27 | 28 | public BigDecimal getMatchedMultiplier() { 29 | return matchedMultiplier; 30 | } 31 | 32 | public List getMatchedPath() { 33 | return matchedPath; 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return getPathAsString() 39 | + (this.matchedMultiplier.compareTo(BigDecimal.ONE) == 0 40 | ? "" 41 | : "*" + this.matchedMultiplier); 42 | } 43 | 44 | private String getPathAsString() { 45 | StringBuilder sb = new StringBuilder("/"); 46 | if (matchedPath != null) { 47 | ListIterator li = matchedPath.listIterator(matchedPath.size()); 48 | while (li.hasPrevious()) { 49 | sb.append(li.previous()); 50 | if (li.hasPrevious()) { 51 | sb.append("/"); 52 | } 53 | } 54 | } 55 | return sb.toString(); 56 | } 57 | 58 | @Override 59 | public boolean equals(Object o) { 60 | if (this == o) return true; 61 | if (o == null || getClass() != o.getClass()) return false; 62 | FactorUnitMatch that = (FactorUnitMatch) o; 63 | return matchedFactorUnit.equals(that.matchedFactorUnit) 64 | && matchedPath.equals(that.matchedPath) 65 | && matchedMultiplier.equals(that.matchedMultiplier); 66 | } 67 | 68 | @Override 69 | public int hashCode() { 70 | return Objects.hash(matchedFactorUnit, matchedPath, matchedMultiplier); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/model/LangString.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.model; 2 | 3 | import java.util.Objects; 4 | import java.util.Optional; 5 | 6 | /** 7 | * Represents an RDF langString - a {@link String} with a language tag, such as "Unit"@en. 8 | * 9 | * @author Florian Kleedorfer 10 | * @version 1.0 11 | */ 12 | public class LangString { 13 | private final String string; 14 | private final String languageTag; 15 | 16 | public LangString(String string) { 17 | this(string, null); 18 | } 19 | 20 | public LangString(String string, String languageTag) { 21 | Objects.requireNonNull(string); 22 | this.string = string; 23 | this.languageTag = languageTag; 24 | } 25 | 26 | public String getString() { 27 | return string; 28 | } 29 | 30 | public Optional getLanguageTag() { 31 | return Optional.ofNullable(languageTag); 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return "'" + string + "'" + (languageTag == null ? "" : "@" + languageTag); 37 | } 38 | 39 | @Override 40 | public boolean equals(Object o) { 41 | if (this == o) return true; 42 | if (o == null || getClass() != o.getClass()) return false; 43 | LangString that = (LangString) o; 44 | return string.equals(that.string) && Objects.equals(languageTag, that.languageTag); 45 | } 46 | 47 | @Override 48 | public int hashCode() { 49 | return Objects.hash(string, languageTag); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/model/LangStrings.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.model; 2 | 3 | import static java.util.stream.Collectors.*; 4 | 5 | import java.util.*; 6 | 7 | public class LangStrings { 8 | private static final String KEY_NO_TAG = "no-language-tag"; 9 | private final Map> langStrings; 10 | 11 | public LangStrings(Collection langStrings) { 12 | this.langStrings = 13 | Collections.unmodifiableMap( 14 | langStrings.stream() 15 | .collect( 16 | groupingBy( 17 | l -> l.getLanguageTag().orElse(KEY_NO_TAG), 18 | toSet()))); 19 | } 20 | 21 | public Optional getStringForLanguageTag( 22 | String language, String fallbackLanguage, boolean allowAnyIfNoMatch) { 23 | return getLangStringForLanguageTag(language, fallbackLanguage, allowAnyIfNoMatch) 24 | .map(ls -> ls.getString()); 25 | } 26 | 27 | public Optional getLangStringForLanguageTag( 28 | String language, String fallbackLanguage, boolean allowAnyIfNoMatch) { 29 | if (language == null) { 30 | return getAnyLangString(); 31 | } 32 | Optional result = getAnyLangStringForLanguageTag(language); 33 | if (result.isPresent()) { 34 | return result; 35 | } 36 | if (fallbackLanguage != null) { 37 | result = getAnyLangStringForLanguageTag(fallbackLanguage); 38 | if (result != null) { 39 | return result; 40 | } 41 | } 42 | if (allowAnyIfNoMatch) { 43 | return getAnyLangString(); 44 | } 45 | return Optional.empty(); 46 | } 47 | 48 | private Optional getAnyLangStringForLanguageTag(String language) { 49 | return Optional.ofNullable(this.langStrings.get(language)) 50 | .map(s -> s.stream().findFirst().orElse(null)); 51 | } 52 | 53 | private Optional getAnyLangString() { 54 | return this.langStrings.values().stream() 55 | .findFirst() 56 | .map(s -> s.stream().findFirst().orElse(null)); 57 | } 58 | 59 | public boolean containsStringForLanguageTag(String languageTag) { 60 | return this.langStrings.containsKey(languageTag); 61 | } 62 | 63 | public Set getAll() { 64 | return this.langStrings.values().stream().flatMap(Collection::stream).collect(toSet()); 65 | } 66 | 67 | @Override 68 | public boolean equals(Object o) { 69 | if (this == o) return true; 70 | if (o == null || getClass() != o.getClass()) return false; 71 | LangStrings that = (LangStrings) o; 72 | return langStrings.equals(that.langStrings); 73 | } 74 | 75 | @Override 76 | public int hashCode() { 77 | return Objects.hash(langStrings); 78 | } 79 | 80 | public boolean containsString(String label) { 81 | return this.langStrings.values().stream() 82 | .flatMap(Collection::stream) 83 | .anyMatch(s -> s.getString().equals(label)); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/model/Namespace.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.model; 2 | 3 | /** Encapsulates an iri and the prefix that is used to abbreviate it. */ 4 | public class Namespace { 5 | private final String abbreviationPrefix; 6 | private final String baseIri; 7 | 8 | /** 9 | * Constructs a namespace instace with specified baseIri and abbreviation prefix. For example, 10 | * 11 | *

12 |      *     Namespace rdf = Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#", "rdf");
13 |      * 
14 | * 15 | * will provide abbreviation/expansion of IRIs in the RDF namespace. 16 | * 17 | * @param baseIri the base IRI of the namespece, e.g. 18 | * "http://www.w3.org/1999/02/22-rdf-syntax-ns#" 19 | * @param abbreviationPrefix the abbreviation prefix to use, e.g. "rdf" 20 | */ 21 | public Namespace(String baseIri, String abbreviationPrefix) { 22 | this.abbreviationPrefix = abbreviationPrefix; 23 | this.baseIri = baseIri; 24 | } 25 | 26 | /** 27 | * Returns the string used to abbreviate IRIs in this namespace. 28 | * 29 | * @return 30 | */ 31 | public String getAbbreviationPrefix() { 32 | return abbreviationPrefix; 33 | } 34 | 35 | /** 36 | * Returns the base IRI of the namespace. 37 | * 38 | * @return 39 | */ 40 | public String getBaseIri() { 41 | return baseIri; 42 | } 43 | 44 | /** 45 | * Returns an abbreviated IRI if the specified iri starts with the baseIri; the unchanged input 46 | * String otherwise; 47 | * 48 | * @param iri 49 | * @return 50 | */ 51 | public String abbreviate(String iri) { 52 | if (isFullNamespaceIri(iri)) { 53 | return this.abbreviationPrefix + ":" + iri.substring(this.baseIri.length()); 54 | } 55 | return new String(iri); 56 | } 57 | 58 | public String expand(String abbreviatedIri) { 59 | if (isAbbreviatedNamespaceIri(abbreviatedIri)) { 60 | return this.baseIri + abbreviatedIri.substring(this.abbreviationPrefix.length() + 1); 61 | } 62 | return new String(abbreviatedIri); 63 | } 64 | 65 | /** 66 | * Returns true if the specified abbreviatedIri starts with the namespace's abbreviation prefix. 67 | */ 68 | public boolean isAbbreviatedNamespaceIri(String abbreviatedIri) { 69 | return abbreviatedIri.startsWith(this.abbreviationPrefix + ':'); 70 | } 71 | 72 | /** Returns true if the specified iri starts with the namespace's baseIri. */ 73 | public boolean isFullNamespaceIri(String iri) { 74 | return iri.startsWith(this.baseIri); 75 | } 76 | 77 | /** 78 | * Prepends the namespace's baseIri to the specified localName. 79 | * 80 | * @param localName 81 | * @return 82 | */ 83 | public String makeIriInNamespace(String localName) { 84 | return this.baseIri + localName; 85 | } 86 | 87 | public String getLocalName(String fullIri) { 88 | return fullIri.replaceFirst(this.baseIri, ""); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/model/Quantity.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.model; 2 | 3 | import java.util.Collections; 4 | import java.util.Objects; 5 | import java.util.Set; 6 | import java.util.stream.Collectors; 7 | 8 | /** 9 | * Represents a QUDT Quantity - a set of {@link QuantityValue}s. 10 | * 11 | * @author Florian Kleedorfer 12 | * @version 1.0 13 | */ 14 | public class Quantity { 15 | final Set quantityValues; 16 | 17 | public Quantity(Set quantityValues) { 18 | this.quantityValues = quantityValues; 19 | } 20 | 21 | public Set getQuantityValues() { 22 | return Collections.unmodifiableSet(quantityValues); 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return "Quantity{" 28 | + quantityValues.stream().map(Objects::toString).collect(Collectors.joining(", ")) 29 | + '}'; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/model/QuantityValue.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.model; 2 | 3 | import io.github.qudtlib.exception.InconvertibleQuantitiesException; 4 | import java.math.BigDecimal; 5 | import java.util.Objects; 6 | 7 | /** 8 | * Represents a QUDT QuantityValue, ie. the combination of a {@link BigDecimal} value and a {@link 9 | * Unit}. 10 | * 11 | * @author Florian Kleedorfer 12 | * @version 1.0 13 | */ 14 | public class QuantityValue { 15 | private final BigDecimal value; 16 | private final Unit unit; 17 | 18 | public QuantityValue(BigDecimal value, Unit unit) { 19 | this.value = value; 20 | this.unit = unit; 21 | } 22 | 23 | public BigDecimal getValue() { 24 | return value; 25 | } 26 | 27 | public Unit getUnit() { 28 | return unit; 29 | } 30 | 31 | @Override 32 | public boolean equals(Object o) { 33 | if (this == o) return true; 34 | if (o == null || getClass() != o.getClass()) return false; 35 | QuantityValue that = (QuantityValue) o; 36 | return value.compareTo(that.value) == 0 && Objects.equals(unit, that.unit); 37 | } 38 | 39 | public QuantityValue convert(Unit toUnit) throws InconvertibleQuantitiesException { 40 | return convert(toUnit, null); 41 | } 42 | 43 | /** 44 | * @param toUnit 45 | * @param quantityKind optional quantity kind for handling edge cases 46 | * @return 47 | * @throws InconvertibleQuantitiesException 48 | */ 49 | public QuantityValue convert(Unit toUnit, QuantityKind quantityKind) 50 | throws InconvertibleQuantitiesException { 51 | return new QuantityValue(this.unit.convert(this.value, toUnit, quantityKind), toUnit); 52 | } 53 | 54 | @Override 55 | public int hashCode() { 56 | return Objects.hash(value, unit); 57 | } 58 | 59 | public String toString() { 60 | return value.toString() + unit.toString(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/model/QudtNamespaces.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.model; 2 | 3 | public class QudtNamespaces { 4 | public static final Namespace quantityKind = 5 | new Namespace("http://qudt.org/vocab/quantitykind/", "qk"); 6 | public static final Namespace unit = new Namespace("http://qudt.org/vocab/unit/", "unit"); 7 | public static final Namespace currency = 8 | new Namespace("http://qudt.org/vocab/currency/", "cur"); 9 | public static final Namespace prefix = new Namespace("http://qudt.org/vocab/prefix/", "prefix"); 10 | public static final Namespace systemOfUnits = 11 | new Namespace("http://qudt.org/vocab/sou/", "sou"); 12 | public static final Namespace qudt = new Namespace("http://qudt.org/schema/qudt/", "qudt"); 13 | public static final Namespace dimensionVector = 14 | new Namespace("http://qudt.org/vocab/dimensionvector/", "qkdv"); 15 | public static final Namespace constant = 16 | new Namespace("http://qudt.org/vocab/constant/", "constant"); 17 | } 18 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/nodedef/Builder.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.nodedef; 2 | 3 | import java.util.List; 4 | import java.util.Set; 5 | import java.util.stream.Collectors; 6 | 7 | public interface Builder { 8 | static Set buildSet(Set> builders) { 9 | return builders.stream().map(Builder::build).collect(Collectors.toSet()); 10 | } 11 | 12 | static List buildList(List> builders) { 13 | return builders.stream().map(Builder::build).collect(Collectors.toList()); 14 | } 15 | 16 | public T build(); 17 | } 18 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/nodedef/EmptyBuilder.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.nodedef; 2 | 3 | public class EmptyBuilder implements Builder { 4 | public EmptyBuilder() {} 5 | 6 | @Override 7 | public T build() { 8 | return null; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/nodedef/MapBackedNodeDefinition.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.nodedef; 2 | 3 | import java.util.Map; 4 | import java.util.Objects; 5 | import java.util.Optional; 6 | import java.util.function.Supplier; 7 | 8 | public class MapBackedNodeDefinition implements NodeDefinition { 9 | 10 | private final Map> builders; 11 | private final K key; 12 | private final Supplier notFoundExceptionSupplier; 13 | 14 | public MapBackedNodeDefinition( 15 | Map> builders, 16 | K key, 17 | Supplier notFoundExceptionSupplier) { 18 | Objects.requireNonNull(builders); 19 | Objects.requireNonNull(key); 20 | this.builders = builders; 21 | this.key = key; 22 | this.notFoundExceptionSupplier = 23 | notFoundExceptionSupplier != null 24 | ? notFoundExceptionSupplier 25 | : () -> 26 | new IllegalArgumentException( 27 | String.format( 28 | "Expected entity %s not found", key.toString())); 29 | } 30 | 31 | @Override 32 | public T build() { 33 | return Optional.ofNullable(this.builders.get(this.key)) 34 | .orElseThrow(this.notFoundExceptionSupplier) 35 | .build(); 36 | } 37 | 38 | @Override 39 | public boolean equals(Object o) { 40 | if (this == o) return true; 41 | if (o == null || getClass() != o.getClass()) return false; 42 | NodeDefinition that = (NodeDefinition) o; 43 | return getId().equals(that.getId()); 44 | } 45 | 46 | @Override 47 | public int hashCode() { 48 | return Objects.hash(getId()); 49 | } 50 | 51 | @Override 52 | public K getId() { 53 | return key; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/nodedef/NodeDefinition.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.nodedef; 2 | 3 | public interface NodeDefinition extends Builder { 4 | I getId(); 5 | } 6 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/nodedef/NodeDefinitionBase.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.nodedef; 2 | 3 | import java.util.Objects; 4 | 5 | public abstract class NodeDefinitionBase extends SettableBuilderBase 6 | implements NodeDefinition { 7 | final I id; 8 | 9 | public NodeDefinitionBase(I id, T presetProduct) { 10 | super(presetProduct); 11 | Objects.requireNonNull(id); 12 | this.id = id; 13 | } 14 | 15 | public NodeDefinitionBase(I id) { 16 | Objects.requireNonNull(id); 17 | this.id = id; 18 | } 19 | 20 | @Override 21 | public final T build() { 22 | if (this.getProduct() == null) { 23 | T built = doBuild(); 24 | // the product may have been set by a SelfSmuggler. In that case, don't overwrite it. 25 | if (this.getProduct() == null) { 26 | this.setProduct(built); 27 | } 28 | } 29 | return getProduct(); 30 | } 31 | 32 | public I getId() { 33 | return id; 34 | } 35 | 36 | @Override 37 | public boolean equals(Object o) { 38 | if (this == o) return true; 39 | if (!(o instanceof NodeDefinitionBase)) return false; 40 | NodeDefinitionBase that = (NodeDefinitionBase) o; 41 | return getId().equals(that.getId()); 42 | } 43 | 44 | @Override 45 | public int hashCode() { 46 | return Objects.hash(getId()); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/nodedef/SelfSmuggler.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.nodedef; 2 | 3 | public class SelfSmuggler { 4 | public , T extends SelfSmuggler> SelfSmuggler(B builder) { 5 | builder.setProduct((T) this); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/nodedef/SettableBuilder.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.nodedef; 2 | 3 | public interface SettableBuilder extends Builder { 4 | void setProduct(T product); 5 | } 6 | -------------------------------------------------------------------------------- /qudtlib-model/src/main/java/io/github/qudtlib/nodedef/SettableBuilderBase.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.nodedef; 2 | 3 | import java.util.Objects; 4 | import java.util.function.Consumer; 5 | 6 | public abstract class SettableBuilderBase implements SettableBuilder { 7 | 8 | private volatile T product; 9 | 10 | public SettableBuilderBase(T presetProduct) { 11 | Objects.requireNonNull(presetProduct); 12 | this.product = presetProduct; 13 | } 14 | 15 | public SettableBuilderBase() {} 16 | 17 | protected void resetProduct() { 18 | this.product = null; 19 | } 20 | 21 | @Override 22 | public void setProduct(T product) { 23 | this.product = product; 24 | } 25 | 26 | protected abstract T doBuild(); 27 | 28 | protected T getProduct() { 29 | return product; 30 | } 31 | 32 | protected void doIfPresent(T val, Consumer setter) { 33 | if (val != null) { 34 | setter.accept(val); 35 | } 36 | } 37 | 38 | @Override 39 | public T build() { 40 | if (this.product == null) { 41 | this.product = doBuild(); 42 | } 43 | return product; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /qudtlib-test/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | qudtlib-java 5 | io.github.qudtlib 6 | 6.8.2-SNAPSHOT 7 | 8 | 4.0.0 9 | qudtlib-test 10 | jar 11 | 12 | 13 | io.github.qudtlib 14 | qudtlib-main 15 | ${project.version} 16 | 17 | 18 | org.junit.jupiter 19 | junit-jupiter 20 | 21 | 22 | org.hamcrest 23 | hamcrest-library 24 | 25 | 26 | 27 | 28 | 29 | org.apache.maven.plugins 30 | maven-jar-plugin 31 | 32 | 33 | 34 | test-jar 35 | 36 | 37 | 38 | 39 | 40 | org.apache.maven.plugins 41 | maven-surefire-plugin 42 | 3.0.0-M7 43 | 44 | 49 | true 50 | 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-deploy-plugin 55 | 56 | true 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /qudtlib-test/src/test/java/io/github/qudtlib/ConstantTests.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import io.github.qudtlib.model.PhysicalConstant; 6 | import java.math.BigDecimal; 7 | import org.hamcrest.MatcherAssert; 8 | import org.hamcrest.Matchers; 9 | import org.junit.jupiter.api.Test; 10 | 11 | public class ConstantTests { 12 | @Test 13 | public void vanillaConstantTest() { 14 | PhysicalConstant g = 15 | Qudt.physicalConstantRequired( 16 | Qudt.NAMESPACES.constant.makeIriInNamespace( 17 | "StandardAccelerationOfGravity")); 18 | assertEquals(Qudt.QuantityKinds.LinearAcceleration, g.getQuantityKind()); 19 | MatcherAssert.assertThat( 20 | new BigDecimal("9.80665"), 21 | Matchers.comparesEqualTo(g.getConstantValue().getValue())); 22 | } 23 | 24 | public void descriptionTest() { 25 | assertTrue(Qudt.PhysicalConstants.AvogadroConstant.getDescription().isPresent()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /qudtlib-test/src/test/java/io/github/qudtlib/CurrencyTests.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib; 2 | 3 | import io.github.qudtlib.model.Unit; 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.Test; 6 | 7 | public class CurrencyTests { 8 | 9 | @Test 10 | public void testCurrency() { 11 | Unit euro = Qudt.Units.EUR_Currency; 12 | Assertions.assertTrue(euro.hasLabel("Euro")); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /qudtlib-test/src/test/java/io/github/qudtlib/FactorUnitTests.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertTrue; 4 | 5 | import io.github.qudtlib.model.FactorUnit; 6 | import java.math.BigDecimal; 7 | import java.util.stream.Stream; 8 | import org.hamcrest.MatcherAssert; 9 | import org.hamcrest.Matchers; 10 | import org.junit.jupiter.api.Test; 11 | import org.junit.jupiter.params.ParameterizedTest; 12 | import org.junit.jupiter.params.provider.Arguments; 13 | import org.junit.jupiter.params.provider.MethodSource; 14 | 15 | public class FactorUnitTests { 16 | public static Stream testConversionMultiplier() { 17 | return Stream.of( 18 | Arguments.of(new FactorUnit(Qudt.Units.KiloM, 2), BigDecimal.valueOf(1000000)), 19 | Arguments.of(new FactorUnit(Qudt.Units.KiloM, -2), BigDecimal.valueOf(0.000001))); 20 | } 21 | 22 | @ParameterizedTest 23 | @MethodSource 24 | public void testConversionMultiplier(FactorUnit factorUnit, BigDecimal expectedResult) { 25 | MatcherAssert.assertThat( 26 | factorUnit.conversionMultiplier(), Matchers.comparesEqualTo(expectedResult)); 27 | } 28 | 29 | @Test 30 | public void testDefinedAsOtherUnit() { 31 | assertTrue(Qudt.Units.L.isDefinedAsOtherUnit()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /qudtlib-test/src/test/java/io/github/qudtlib/NamespaceTests.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib; 2 | 3 | import io.github.qudtlib.model.QudtNamespaces; 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.Test; 6 | 7 | public class NamespaceTests { 8 | 9 | @Test 10 | public void testMakeNamespaceIri() { 11 | String mIriFull = QudtNamespaces.unit.makeIriInNamespace("M"); 12 | Assertions.assertEquals("http://qudt.org/vocab/unit/M", mIriFull); 13 | } 14 | 15 | @Test 16 | public void testAbbreviate() { 17 | String mIriAbbreviated = QudtNamespaces.unit.abbreviate("http://qudt.org/vocab/unit/M"); 18 | Assertions.assertEquals("unit:M", mIriAbbreviated); 19 | } 20 | 21 | @Test 22 | public void testExpand() { 23 | String mIriFull = QudtNamespaces.unit.expand("unit:M"); 24 | Assertions.assertEquals("http://qudt.org/vocab/unit/M", mIriFull); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /qudtlib-test/src/test/java/io/github/qudtlib/NumericStabilityTests.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | 6 | public class NumericStabilityTests { 7 | 8 | @Test 9 | public void testStabilitiyOfSimpleFractions() { 10 | Assertions.assertEquals( 11 | "0.0010", 12 | Qudt.Prefixes.Milli.getMultiplier().toString(), 13 | "Numerically instable multiplier detected"); 14 | /* 15 | Assertions.assertEquals( 16 | "0.0010", 17 | new BigDecimal("1.0E-3").toString(), 18 | "Numerically instable multiplier detected"); 19 | Assertions.assertEquals( 20 | "0.001", 21 | BigDecimal.valueOf(1.0E-3).toString(), 22 | "Numerically instable multiplier detected"); 23 | Assertions.assertEquals( 24 | "0.001", 25 | BigDecimal.valueOf(0.001).toString(), 26 | "Numerically instable multiplier detected"); 27 | 28 | Assertions.assertEquals( 29 | "0.0010", 30 | new BigDecimal(0.001).toString(), 31 | "Numerically instable multiplier detected"); 32 | Assertions.assertEquals( 33 | "0.0010", 34 | new BigDecimal(1.0E-3).toString(), 35 | "Numerically instable multiplier detected"); 36 | 37 | */ 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /qudtlib-test/src/test/java/io/github/qudtlib/QuantityKindTests.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib; 2 | 3 | import static io.github.qudtlib.model.QuantityKinds.*; 4 | import static org.junit.jupiter.api.Assertions.assertTrue; 5 | 6 | import io.github.qudtlib.model.QuantityKind; 7 | import java.lang.reflect.Array; 8 | import java.util.stream.IntStream; 9 | import java.util.stream.Stream; 10 | import org.junit.jupiter.api.Test; 11 | import org.junit.jupiter.api.extension.ParameterContext; 12 | import org.junit.jupiter.params.ParameterizedTest; 13 | import org.junit.jupiter.params.aggregator.AggregateWith; 14 | import org.junit.jupiter.params.aggregator.ArgumentsAccessor; 15 | import org.junit.jupiter.params.aggregator.ArgumentsAggregationException; 16 | import org.junit.jupiter.params.aggregator.ArgumentsAggregator; 17 | import org.junit.jupiter.params.provider.Arguments; 18 | import org.junit.jupiter.params.provider.MethodSource; 19 | import org.junit.platform.commons.util.Preconditions; 20 | 21 | public class QuantityKindTests { 22 | @MethodSource 23 | @ParameterizedTest 24 | public void testExactMatches( 25 | @AggregateWith(VarargsAggregator.class) QuantityKind... quantityKinds) { 26 | for (int i = 0; i < quantityKinds.length; i++) { 27 | for (int j = i + 1; j < quantityKinds.length; j++) { 28 | QuantityKind qk1 = quantityKinds[i]; 29 | QuantityKind qk2 = quantityKinds[j]; 30 | if (i != j) { 31 | assertTrue( 32 | qk1.getExactMatches().contains(qk2), 33 | String.format( 34 | "(%s).getExactMatches().contains(%s)", 35 | Qudt.NAMESPACES.quantityKind.abbreviate(qk1.getIri()), 36 | Qudt.NAMESPACES.quantityKind.abbreviate(qk2.getIri()))); 37 | assertTrue( 38 | qk2.getExactMatches().contains(qk1), 39 | String.format( 40 | "(%s).getExactMatches().contains(%s)", 41 | Qudt.NAMESPACES.quantityKind.abbreviate(qk2.getIri()), 42 | Qudt.NAMESPACES.quantityKind.abbreviate(qk1.getIri()))); 43 | } 44 | } 45 | } 46 | } 47 | 48 | public static Stream testExactMatches() { 49 | return Stream.of( 50 | Arguments.of(Velocity, LinearVelocity), 51 | Arguments.of(PlaneAngle, Angle), 52 | Arguments.of(AngularImpulse, AngularMomentum), 53 | Arguments.of(Density, MassDensity), 54 | Arguments.of(ElectricFluxDensity, ElectricDisplacement), 55 | Arguments.of( 56 | ElectricPotential, 57 | Voltage, 58 | ElectricPotentialDifference, 59 | EnergyPerElectricCharge), 60 | Arguments.of(ElectromagneticEnergyDensity, VolumicElectromagneticEnergy), 61 | Arguments.of(Permeability, ElectromagneticPermeability), 62 | Arguments.of(EnergyInternal, InternalEnergy, ThermodynamicEnergy), 63 | Arguments.of(InversePressure, IsothermalCompressibility)); 64 | } 65 | 66 | static class VarargsAggregator implements ArgumentsAggregator { 67 | @Override 68 | public Object aggregateArguments(ArgumentsAccessor accessor, ParameterContext context) 69 | throws ArgumentsAggregationException { 70 | Class parameterType = context.getParameter().getType(); 71 | Preconditions.condition( 72 | parameterType.isArray(), 73 | () -> "must be an array type, but was " + parameterType); 74 | Class componentType = parameterType.getComponentType(); 75 | return IntStream.range(context.getIndex(), accessor.size()) 76 | .mapToObj(index -> accessor.get(index, componentType)) 77 | .toArray(size -> (Object[]) Array.newInstance(componentType, size)); 78 | } 79 | } 80 | 81 | @Test 82 | public void testDescription() { 83 | assertTrue(Qudt.QuantityKinds.Length.getDescription().isPresent()); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /qudtlib-test/src/test/java/io/github/qudtlib/UnitTests.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertTrue; 4 | 5 | import org.junit.jupiter.api.Test; 6 | 7 | public class UnitTests { 8 | 9 | @Test 10 | public void testDescription() { 11 | assertTrue(Qudt.Units.M.getDescription().isPresent()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /qudtlib-tools/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | qudtlib-java 5 | io.github.qudtlib 6 | 6.8.2-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | qudtlib-tools 11 | jar 12 | 13 | 14 | 15 | io.github.qudtlib 16 | qudtlib-init-hardcoded 17 | ${project.version} 18 | 19 | 20 | io.github.qudtlib 21 | qudtlib-model 22 | ${project.version} 23 | 24 | 25 | io.github.qudtlib 26 | qudtlib-vocab 27 | ${project.version} 28 | 29 | 30 | io.github.qudtlib 31 | qudtlib-main 32 | ${project.version} 33 | 34 | 35 | org.eclipse.rdf4j 36 | rdf4j-model 37 | 38 | 39 | org.eclipse.rdf4j 40 | rdf4j-runtime 41 | pom 42 | 43 | 44 | org.eclipse.rdf4j 45 | rdf4j-rio-turtle 46 | 47 | 48 | org.eclipse.rdf4j 49 | rdf4j-rio-api 50 | 51 | 52 | org.junit.jupiter 53 | junit-jupiter 54 | 55 | 56 | 57 | 58 | src/main/java 59 | src/test/java 60 | 61 | 62 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/QudtEntityAtRuntimeAdder.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib; 2 | 3 | import io.github.qudtlib.model.QuantityKind; 4 | import io.github.qudtlib.model.Unit; 5 | 6 | public class QudtEntityAtRuntimeAdder { 7 | public static void addUnit(Unit unit) { 8 | Qudt.addUnit(unit); 9 | } 10 | 11 | public static void addQuantityKind(QuantityKind quantityKind) { 12 | Qudt.addQuantityKind(quantityKind); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contribute/QudtContribution_symbol.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contribute; 2 | 3 | import io.github.qudtlib.Qudt; 4 | import io.github.qudtlib.model.FactorUnit; 5 | import io.github.qudtlib.model.FactorUnits; 6 | import io.github.qudtlib.model.Unit; 7 | import io.github.qudtlib.vocab.QUDT; 8 | import java.util.ArrayList; 9 | import java.util.Comparator; 10 | import java.util.List; 11 | import java.util.Optional; 12 | import java.util.function.Consumer; 13 | 14 | public class QudtContribution_symbol { 15 | public static void main(String[] args) throws Exception { 16 | QudtEntityGenerator entityGenerator = new QudtEntityGenerator(false); 17 | 18 | Consumer symbolAndUcumGenerator = 19 | new Consumer() { 20 | @Override 21 | public void accept(Tool tool) { 22 | List allUnits = new ArrayList<>(Qudt.allUnits()); 23 | allUnits.stream() 24 | .sorted(Comparator.comparing(Unit::getIri)) 25 | .filter(u -> u.getSymbol().isEmpty()) 26 | .forEach( 27 | u -> { 28 | final String symbol = getSymbol(u).orElse(null); 29 | FactorUnits factorUnits = u.getFactorUnits(); 30 | try { 31 | if (symbol != null) { 32 | tool.addDerivedUnit( 33 | factorUnits, ud -> ud.symbol(symbol)); 34 | } else { 35 | System.err.println( 36 | String.format( 37 | "Cannot add symbol for %s: one of the constituent units has no symbol", 38 | u.getIri())); 39 | } 40 | } catch (Exception e) { 41 | System.err.println( 42 | String.format( 43 | "Cannot add symbol for %s", 44 | u.getIri())); 45 | } 46 | }); 47 | } 48 | }; 49 | 50 | for (int i = 0; i < 5; i++) { 51 | entityGenerator.unitOfWork(symbolAndUcumGenerator); 52 | } 53 | entityGenerator.writeRdf(s -> s.getPredicate().equals(QUDT.symbol)); 54 | } 55 | 56 | private static Optional getSymbol(Unit u) { 57 | List factorUnitList = u.getFactorUnits().getFactorUnits(); 58 | if (!factorUnitList.isEmpty()) { 59 | // System.err.println(String.format("Cannot add symbol for %s: unit has no factor 60 | // units", u.getIri())); 61 | return new FactorUnits(factorUnitList).getSymbol(); 62 | } 63 | if (u.isScaled()) { 64 | String baseUnitSymbol = 65 | u.getScalingOf().map(base -> base.getSymbol().orElse(null)).orElse(null); 66 | if (baseUnitSymbol != null) { 67 | String prefixSymbol = u.getPrefix().map(p -> p.getSymbol()).orElse(null); 68 | if (prefixSymbol != null) { 69 | return Optional.ofNullable(prefixSymbol + baseUnitSymbol); 70 | } 71 | } 72 | } 73 | return Optional.empty(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contribute/QudtContribution_ucumCode.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contribute; 2 | 3 | import io.github.qudtlib.Qudt; 4 | import io.github.qudtlib.model.FactorUnits; 5 | import io.github.qudtlib.model.Unit; 6 | import io.github.qudtlib.vocab.QUDT; 7 | import java.util.ArrayList; 8 | import java.util.Comparator; 9 | import java.util.List; 10 | import java.util.Optional; 11 | import java.util.function.Consumer; 12 | 13 | public class QudtContribution_ucumCode { 14 | public static void main(String[] args) throws Exception { 15 | QudtEntityGenerator entityGenerator = new QudtEntityGenerator(false); 16 | 17 | Consumer symbolAndUcumGenerator = 18 | new Consumer() { 19 | @Override 20 | public void accept(Tool tool) { 21 | List allUnits = new ArrayList<>(Qudt.allUnits()); 22 | allUnits.stream() 23 | .sorted(Comparator.comparing(Unit::getIri)) 24 | .filter(u -> u.getUcumCode().isEmpty()) 25 | .forEach( 26 | u -> { 27 | final String ucumCode = getUcumCode(u).orElse(null); 28 | FactorUnits factorUnits = u.getFactorUnits(); 29 | try { 30 | if (ucumCode != null) { 31 | tool.addDerivedUnit( 32 | factorUnits, 33 | ud -> ud.ucumCode(ucumCode)); 34 | } else { 35 | System.err.println( 36 | String.format( 37 | "Cannot add ucum code for %s: one of the constituent units has no ucum code", 38 | u.getIri())); 39 | } 40 | } catch (Exception e) { 41 | System.err.println( 42 | String.format( 43 | "Cannot add ucum code for %s", 44 | u.getIri())); 45 | } 46 | }); 47 | } 48 | }; 49 | 50 | for (int i = 0; i < 5; i++) { 51 | entityGenerator.unitOfWork(symbolAndUcumGenerator); 52 | } 53 | entityGenerator.writeRdf(s -> s.getPredicate().equals(QUDT.ucumCode)); 54 | } 55 | 56 | private static Optional getUcumCode(Unit u) { 57 | if (u.hasFactorUnits()) { 58 | // System.err.println(String.format("Cannot add symbol for %s: unit has no factor 59 | // units", u.getIri())); 60 | return u.getFactorUnits().getUcumCode(); 61 | } 62 | if (u.isScaled()) { 63 | String baseUnitSymbol = 64 | u.getScalingOf() 65 | .map(base -> Qudt.unitRequired(base.getIri())) 66 | .map(base -> base.getUcumCode().orElse(null)) 67 | .orElse(null); 68 | if (baseUnitSymbol != null) { 69 | String prefixSymbol = 70 | u.getPrefix().map(p -> p.getUcumCode().orElse(null)).orElse(null); 71 | if (prefixSymbol != null) { 72 | return Optional.ofNullable(prefixSymbol + baseUnitSymbol); 73 | } 74 | } 75 | } 76 | return Optional.empty(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contribute/QudtEntityGenerator.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contribute; 2 | 3 | import java.util.function.Consumer; 4 | import java.util.function.Predicate; 5 | import org.eclipse.rdf4j.model.Statement; 6 | 7 | public class QudtEntityGenerator { 8 | 9 | private ToolImpl tool; 10 | 11 | public QudtEntityGenerator() { 12 | this(true); 13 | } 14 | 15 | public QudtEntityGenerator(boolean performShaclValidation) { 16 | this.tool = new ToolImpl(performShaclValidation); 17 | } 18 | 19 | public void unitOfWork(Consumer configurer) { 20 | configurer.accept(this.tool); 21 | } 22 | 23 | public void writeRdf(Predicate statementPredicate) { 24 | this.tool.writeRdf(System.out, statementPredicate); 25 | } 26 | 27 | public void writeRdf() { 28 | this.writeRdf(s -> true); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contribute/Tool.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contribute; 2 | 3 | import io.github.qudtlib.model.*; 4 | import io.github.qudtlib.tools.contribute.model.QuantityKindMetadata; 5 | import io.github.qudtlib.tools.contribute.model.UnitMetadata; 6 | import java.io.OutputStream; 7 | import java.util.List; 8 | import java.util.Set; 9 | import java.util.function.Consumer; 10 | import java.util.function.Function; 11 | import java.util.function.Predicate; 12 | import org.eclipse.rdf4j.model.Model; 13 | import org.eclipse.rdf4j.model.Statement; 14 | 15 | public interface Tool { 16 | Unit addDerivedUnit( 17 | FactorUnits factorUnits, 18 | Consumer unitConfigurer, 19 | Consumer metadataConfigurer, 20 | String nonstandardLocalname); 21 | 22 | Unit addDerivedUnit( 23 | FactorUnits factorUnits, 24 | Consumer unitConfigurer, 25 | Consumer metadataConfigurer); 26 | 27 | Unit addDerivedUnit(FactorUnits factorUnits, Consumer unitConfigurer); 28 | 29 | QuantityKind addQuantityKind( 30 | FactorUnits factorUnits, 31 | String localname, 32 | Consumer quantityKindConfigurer, 33 | Consumer metadataConfigurer); 34 | 35 | QuantityKind addQuantityKind( 36 | FactorUnits factorUnits, 37 | String localname, 38 | Consumer quantityKindConfigurer); 39 | 40 | Set findUnitBySymbolOrUcumCode(String symbol); 41 | 42 | boolean checkUnitExists(FactorUnits factorUnits); 43 | 44 | boolean checkUnitExists(FactorUnits factorUnits, DerivedUnitSearchMode mode); 45 | 46 | void printFactorUnitTree(Unit unit); 47 | 48 | void printFactorUnitTree(Unit unit, Function unitFormatter); 49 | 50 | void printFactorUnitTree( 51 | Unit unit, Function unitFormatter, OutputStream out); 52 | 53 | List listUnitsWithSameDimensions(Unit unit); 54 | 55 | boolean checkQuantityKindExists(FactorUnits factorUnits); 56 | 57 | List searchQuantityKinds(String nameRegex); 58 | 59 | String generateJavaCodeStringForFactorUnits(FactorUnits factorUnits); 60 | 61 | void addUnitsForUcumCodeBestEffort(String ucumCode, boolean force); 62 | 63 | void addUnitsForFactorUnitsBestEffort(FactorUnits factorUnits, boolean force); 64 | 65 | Set findExistingQudtUnitsForFactorUnits(FactorUnits factorUnits); 66 | 67 | List parseUcumCodeToFactorUnits(String ucumCode); 68 | 69 | List searchQuantityKinds(Predicate filter); 70 | 71 | void writeOut(Model model, OutputStream out, Predicate statementPredicate); 72 | 73 | void writeOut(Model model, OutputStream out); 74 | } 75 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contribute/model/MetadataBuilder.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contribute.model; 2 | 3 | public abstract class MetadataBuilder { 4 | protected T product; 5 | 6 | public MetadataBuilder(T product) { 7 | this.product = product; 8 | } 9 | 10 | public T build() { 11 | return product; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contribute/model/QuantityKindForContribution.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contribute.model; 2 | 3 | import io.github.qudtlib.model.FactorUnits; 4 | import io.github.qudtlib.model.QuantityKind; 5 | 6 | public class QuantityKindForContribution { 7 | private QuantityKind quantityKind; 8 | private QuantityKindMetadata quantityKindMetadata; 9 | 10 | public QuantityKindForContribution( 11 | QuantityKind quantityKind, QuantityKindMetadata quantityKindMetadata) { 12 | this.quantityKind = quantityKind; 13 | this.quantityKindMetadata = quantityKindMetadata; 14 | } 15 | 16 | public static Builder builder(String iri) { 17 | return new Builder(QuantityKind.definition(iri), QuantityKindMetadata.builder()); 18 | } 19 | 20 | public static Builder builder(FactorUnits factorUnits, String localName) { 21 | return new Builder( 22 | QuantityKind.definition(factorUnits, localName), QuantityKindMetadata.builder()); 23 | } 24 | 25 | public QuantityKind getQuantityKind() { 26 | return quantityKind; 27 | } 28 | 29 | public QuantityKindMetadata getQuantityKindMetadata() { 30 | return quantityKindMetadata; 31 | } 32 | 33 | public static class Builder { 34 | private QuantityKind.Definition quantityKindDefinition; 35 | private QuantityKindMetadata.Builder metadataBuilder; 36 | 37 | private Builder( 38 | QuantityKind.Definition quantityKindDefinition, 39 | QuantityKindMetadata.Builder metadataBuilder) { 40 | this.quantityKindDefinition = quantityKindDefinition; 41 | this.metadataBuilder = metadataBuilder; 42 | } 43 | 44 | public QuantityKindMetadata.Builder metadata() { 45 | return this.metadataBuilder; 46 | } 47 | 48 | public QuantityKind.Definition quantityKind() { 49 | return quantityKindDefinition; 50 | } 51 | 52 | public QuantityKindForContribution build() { 53 | return new QuantityKindForContribution( 54 | this.quantityKindDefinition.build(), this.metadataBuilder.build()); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contribute/model/QuantityKindMetadata.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contribute.model; 2 | 3 | public class QuantityKindMetadata extends CommonEntityMetadata { 4 | public QuantityKindMetadata() {} 5 | 6 | public static Builder builder() { 7 | return new Builder(); 8 | } 9 | 10 | public static class Builder extends CommonEntityMetadata.Builder { 11 | public Builder() { 12 | super(new QuantityKindMetadata()); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contribute/model/TypedLiteral.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contribute.model; 2 | 3 | import org.eclipse.rdf4j.model.base.CoreDatatype; 4 | 5 | public class TypedLiteral { 6 | private String literal; 7 | private String typeIRI; 8 | 9 | public TypedLiteral(String literal, String typeIRI) { 10 | this.literal = literal; 11 | this.typeIRI = typeIRI; 12 | } 13 | 14 | public TypedLiteral(String literal) { 15 | this.literal = literal; 16 | this.typeIRI = CoreDatatype.XSD.STRING.toString(); 17 | } 18 | 19 | public String getLiteral() { 20 | return literal; 21 | } 22 | 23 | public String getTypeIRI() { 24 | return typeIRI; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contribute/model/UnitForContribution.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contribute.model; 2 | 3 | import io.github.qudtlib.model.FactorUnits; 4 | import io.github.qudtlib.model.Unit; 5 | import io.github.qudtlib.tools.contribute.support.ContributionHelper; 6 | 7 | public class UnitForContribution { 8 | 9 | private UnitMetadata metadata; 10 | private Unit unit; 11 | 12 | public UnitForContribution(Unit unit, UnitMetadata metadata) { 13 | this.metadata = metadata; 14 | this.unit = unit; 15 | } 16 | 17 | public UnitMetadata getMetadata() { 18 | return metadata; 19 | } 20 | 21 | public Unit getUnit() { 22 | return unit; 23 | } 24 | 25 | public static Builder builder(String iri) { 26 | return new Builder(iri); 27 | } 28 | 29 | public static Builder builder(FactorUnits factorUnits, String nonstandardLocalname) { 30 | return new Builder(factorUnits, nonstandardLocalname); 31 | } 32 | 33 | public static class Builder { 34 | private Unit.Definition unitDefinition; 35 | private UnitMetadata.Builder metadataBuilder; 36 | 37 | private Builder(Unit.Definition unitDefinition, UnitMetadata.Builder metadataBuilder) { 38 | this.unitDefinition = unitDefinition; 39 | this.metadataBuilder = metadataBuilder; 40 | } 41 | 42 | public Builder(String iri) { 43 | this(Unit.definition(iri), UnitMetadata.builder()); 44 | } 45 | 46 | public Builder(FactorUnits factorUnits, String nonstandardLocalname) { 47 | this( 48 | ContributionHelper.derivedUnitDefinition(factorUnits, nonstandardLocalname), 49 | UnitMetadata.builder()); 50 | } 51 | 52 | public Unit.Definition unit() { 53 | return this.unitDefinition; 54 | } 55 | 56 | public UnitMetadata.Builder metadata() { 57 | return this.metadataBuilder; 58 | } 59 | 60 | public UnitForContribution build() { 61 | return new UnitForContribution( 62 | this.unitDefinition.build(), this.metadataBuilder.build()); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contribute/model/UnitMetadata.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contribute.model; 2 | 3 | import io.github.qudtlib.vocab.QUDT; 4 | import org.eclipse.rdf4j.model.IRI; 5 | import org.eclipse.rdf4j.model.impl.SimpleValueFactory; 6 | 7 | public class UnitMetadata extends CommonEntityMetadata { 8 | protected TypedLiteral qudtUcumCode; 9 | protected String qudtIec61360Code; 10 | protected String qudtUneceCommonCode; 11 | protected IRI qudtOmUnit; 12 | 13 | public static Builder builder() { 14 | return new Builder(); 15 | } 16 | 17 | public TypedLiteral getQudtUcumCode() { 18 | return qudtUcumCode; 19 | } 20 | 21 | public String getQudtIec61360Code() { 22 | return qudtIec61360Code; 23 | } 24 | 25 | public String getQudtUneceCommonCode() { 26 | return qudtUneceCommonCode; 27 | } 28 | 29 | public IRI getQudtOmUnit() { 30 | return qudtOmUnit; 31 | } 32 | 33 | public static class Builder extends CommonEntityMetadata.Builder { 34 | public Builder() { 35 | super(new UnitMetadata()); 36 | } 37 | 38 | public T QudtUcumCode(TypedLiteral qudtUcumCode) { 39 | this.product.qudtUcumCode = qudtUcumCode; 40 | return (T) this; 41 | } 42 | 43 | public T QudtUcumCode(String qudtUcumCode) { 44 | this.product.qudtUcumCode = new TypedLiteral(qudtUcumCode, QUDT.UCUMcs.toString()); 45 | return (T) this; 46 | } 47 | 48 | public T QudtIec61360Code( 49 | String qudtIec61360Code) { 50 | this.product.qudtIec61360Code = qudtIec61360Code; 51 | return (T) this; 52 | } 53 | 54 | public T QudtUneceCommonCode( 55 | String qudtUneceCommonCode) { 56 | this.product.qudtUneceCommonCode = qudtUneceCommonCode; 57 | return (T) this; 58 | } 59 | 60 | public T QudtOmUnit(String omUnitIri) { 61 | this.product.qudtOmUnit = SimpleValueFactory.getInstance().createIRI(omUnitIri); 62 | return (T) this; 63 | } 64 | 65 | public T QudtOmUnit(IRI omUnitIri) { 66 | this.product.qudtOmUnit = omUnitIri; 67 | return (T) this; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contribute/support/FormattingHelper.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contribute.support; 2 | 3 | import java.math.BigDecimal; 4 | import java.text.DecimalFormat; 5 | import java.text.DecimalFormatSymbols; 6 | 7 | public class FormattingHelper { 8 | 9 | private static final DecimalFormat decimalFormat; 10 | private static final DecimalFormatSymbols symbols; 11 | 12 | static { 13 | symbols = new DecimalFormatSymbols(); 14 | symbols.setDecimalSeparator('.'); 15 | decimalFormat = 16 | new DecimalFormat( 17 | "0.0#####################################################################################################################################################", 18 | symbols); 19 | } 20 | 21 | public static String format(BigDecimal bigDecimal) { 22 | return decimalFormat.format(bigDecimal); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contribute/support/IndentedOutputStream.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contribute.support; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | import java.io.PrintStream; 6 | 7 | public class IndentedOutputStream extends OutputStream { 8 | private OutputStream delegate; 9 | private String indentString; 10 | 11 | private boolean isNewLine = true; 12 | 13 | public IndentedOutputStream(PrintStream delegate, String indentString) { 14 | this.delegate = delegate; 15 | this.indentString = indentString; 16 | } 17 | 18 | public PrintStream printStream() { 19 | return new PrintStream(this); 20 | } 21 | 22 | public static OutputStream nullOutputStream() { 23 | return OutputStream.nullOutputStream(); 24 | } 25 | 26 | @Override 27 | public void write(int b) throws IOException { 28 | if (isNewLine) { 29 | for (int i = 0; i < indentString.getBytes().length; i++) { 30 | delegate.write(indentString.getBytes()[i]); 31 | } 32 | isNewLine = false; 33 | } 34 | if (b == '\n') { 35 | isNewLine = true; 36 | } 37 | delegate.write(b); 38 | } 39 | 40 | @Override 41 | public void flush() throws IOException { 42 | delegate.flush(); 43 | } 44 | 45 | @Override 46 | public void close() throws IOException { 47 | delegate.close(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contribute/support/QuantityKindBuilderFacade.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contribute.support; 2 | 3 | import io.github.qudtlib.model.FactorUnits; 4 | import io.github.qudtlib.model.QuantityKind; 5 | import io.github.qudtlib.model.QudtNamespaces; 6 | 7 | public class QuantityKindBuilderFacade { 8 | private QuantityKind.Definition definition; 9 | 10 | public QuantityKindBuilderFacade(FactorUnits factorUnits, String localName) { 11 | this.definition = 12 | QuantityKind.definition(QudtNamespaces.quantityKind.makeIriInNamespace(localName)); 13 | this.definition.dimensionVectorIri(factorUnits.getDimensionVectorIri()); 14 | } 15 | 16 | public QuantityKindBuilderFacade addBroaderQuantityKind(QuantityKind quantityKind) { 17 | this.definition.addBroaderQuantityKind(QuantityKind.definition(quantityKind)); 18 | return this; 19 | } 20 | 21 | public QuantityKindBuilderFacade label(String label, String languageTag) { 22 | this.definition.addLabel(label, languageTag); 23 | return this; 24 | } 25 | 26 | public QuantityKindBuilderFacade addExactMatch(QuantityKind quantityKind) { 27 | this.definition.addExactMatch(QuantityKind.definition(quantityKind)); 28 | return this; 29 | } 30 | 31 | public QuantityKindBuilderFacade symbol(String symbol) { 32 | this.definition.symbol(symbol); 33 | return this; 34 | } 35 | 36 | public QuantityKind build() { 37 | return this.definition.build(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contribute/support/SelectionHelper.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contribute.support; 2 | 3 | import io.github.qudtlib.Qudt; 4 | import io.github.qudtlib.model.QuantityKind; 5 | import io.github.qudtlib.model.Unit; 6 | import java.util.List; 7 | import java.util.Set; 8 | import java.util.stream.Collectors; 9 | 10 | public class SelectionHelper { 11 | public static List getUnitsAssociatedWithQuantityKind(QuantityKind quantityKind) { 12 | return Qudt.allUnits().stream() 13 | .filter(u -> u.getQuantityKinds().contains(quantityKind)) 14 | .collect(Collectors.toList()); 15 | } 16 | 17 | public static Set getQuantityKindsByDimensionVector(String dimensionVectorIri) { 18 | return Qudt.allQuantityKinds().stream() 19 | .filter( 20 | qk -> 21 | qk.getDimensionVectorIri() 22 | .map(dv -> dv.equals(dimensionVectorIri)) 23 | .orElse(false)) 24 | .collect(Collectors.toSet()); 25 | } 26 | 27 | public static Set getUnitsByDimensionVector(String dimensionVectorIri) { 28 | return Qudt.allUnits().stream() 29 | .filter( 30 | unit -> 31 | unit.getDimensionVectorIri() 32 | .map(dv -> dv.equals(dimensionVectorIri)) 33 | .orElse(false)) 34 | .collect(Collectors.toSet()); 35 | } 36 | 37 | public static boolean hasOtherUnitsAssociated(QuantityKind quantityKind, Unit except) { 38 | List ret = getUnitsAssociatedWithQuantityKind(quantityKind); 39 | ret.remove(except); 40 | return !ret.isEmpty(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contribute/support/tree/NodeVisitor.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contribute.support.tree; 2 | 3 | public interface NodeVisitor { 4 | void enter(NodeAndPositionInTree nodeAndPosition); 5 | 6 | void exit(NodeAndPositionInTree nodeAndPosition); 7 | 8 | static class NodeAndPositionInTree { 9 | private final Node node; 10 | private final int depth; 11 | private final int siblings; 12 | private final int orderInSiblings; 13 | 14 | public NodeAndPositionInTree(Node node, int depth, int siblings, int orderInSiblings) { 15 | this.node = node; 16 | this.depth = depth; 17 | this.siblings = siblings; 18 | this.orderInSiblings = orderInSiblings; 19 | } 20 | 21 | public Node getNode() { 22 | return node; 23 | } 24 | 25 | public int getDepth() { 26 | return depth; 27 | } 28 | 29 | public int getSiblings() { 30 | return siblings; 31 | } 32 | 33 | public int getOrderInSiblings() { 34 | return orderInSiblings; 35 | } 36 | 37 | public boolean isFirstOrOnlyNode() { 38 | return orderInSiblings == 0; 39 | } 40 | 41 | public boolean isLastOrOnlyNode() { 42 | return orderInSiblings == siblings; 43 | } 44 | 45 | public boolean isNeitherFirstNorLast() { 46 | return orderInSiblings > 0 && orderInSiblings < siblings; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contribute/support/tree/TreeWalker.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contribute.support.tree; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Comparator; 5 | import java.util.List; 6 | import java.util.Objects; 7 | 8 | public class TreeWalker { 9 | private Node root; 10 | private Comparator> iterationOrderComparator = null; 11 | 12 | public TreeWalker(Node root) { 13 | Objects.requireNonNull(root); 14 | this.root = root; 15 | } 16 | 17 | public TreeWalker sorted(Comparator> comparator) { 18 | this.iterationOrderComparator = comparator; 19 | return this; 20 | } 21 | 22 | public static TreeWalker of(Node root) { 23 | return new TreeWalker(root); 24 | } 25 | 26 | public void walkDepthFirst(NodeVisitor visitor) { 27 | walkDepthFirstInternal(root, visitor, 0, 0, 0); 28 | } 29 | 30 | private void walkDepthFirstInternal( 31 | Node node, NodeVisitor visitor, int depth, int siblings, int orderInSiblings) { 32 | NodeVisitor.NodeAndPositionInTree nodeAndPositionInTree = 33 | new NodeVisitor.NodeAndPositionInTree<>(node, depth, siblings, orderInSiblings); 34 | visitor.enter(nodeAndPositionInTree); 35 | List> children = new ArrayList<>(node.getChildren()); 36 | if (this.iterationOrderComparator != null) { 37 | children.sort(this.iterationOrderComparator); 38 | } 39 | for (int i = 0; i < children.size(); i++) { 40 | walkDepthFirstInternal(children.get(i), visitor, depth + 1, children.size() - 1, i); 41 | } 42 | visitor.exit(nodeAndPositionInTree); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contributions/GlobalData.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contributions; 2 | 3 | import io.github.qudtlib.Qudt; 4 | import io.github.qudtlib.model.FactorUnit; 5 | import io.github.qudtlib.model.Unit; 6 | import java.util.*; 7 | import java.util.stream.Collectors; 8 | 9 | public class GlobalData { 10 | final Map> missingData = new HashMap<>(); 11 | 12 | final Map> unitDependencies; 13 | final String relativeDifferenceThreshold = "0.001"; 14 | final Set correctUnits = new HashSet<>(); 15 | 16 | final Set wasIncorrect = new HashSet<>(); 17 | final Set wasMissing = new HashSet<>(); 18 | 19 | public GlobalData() { 20 | this.unitDependencies = calculateUnitDependencies(); 21 | } 22 | 23 | public boolean trustCalculationForUnit(Unit u) { 24 | Set dependencies = unitDependencies.get(u); 25 | if (dependencies == null) { 26 | return false; 27 | } 28 | if (dependencies.equals(Set.of(u))) { 29 | return true; 30 | } 31 | return dependencies.stream().allMatch(dependency -> correctUnits.contains(dependency)); 32 | } 33 | 34 | private static Map> calculateUnitDependencies() { 35 | return Qudt.allUnits().stream() 36 | .collect( 37 | Collectors.toMap( 38 | u -> u, 39 | u -> 40 | u.getFactorUnits() 41 | .streamAllFactorUnitsRecursively() 42 | .map(FactorUnit::getUnit) 43 | .collect(Collectors.toSet()))); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contributions/archive/ContributeFixedPrefixes.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contributions.archive; 2 | 3 | import io.github.qudtlib.Qudt; 4 | import io.github.qudtlib.tools.contribute.QudtEntityGenerator; 5 | 6 | public class ContributeFixedPrefixes { 7 | public static void main(String[] args) { 8 | QudtEntityGenerator entityGenerator = new QudtEntityGenerator(); 9 | entityGenerator.unitOfWork( 10 | tool -> { 11 | Qudt.allUnits().stream() 12 | .filter(u -> u.getPrefix().isPresent()) 13 | .filter( 14 | u -> 15 | u.getIriLocalname() 16 | .toLowerCase() 17 | .indexOf( 18 | u 19 | .getPrefix() 20 | .get() 21 | .getLabels() 22 | .stream() 23 | .findFirst() 24 | .get() 25 | .getString() 26 | .toLowerCase()) 27 | == -1) 28 | .forEach( 29 | u -> { 30 | System.err.println( 31 | String.format( 32 | "check unit %s: prefix label %s not found in localname", 33 | u.getIriAbbreviated(), 34 | u.getPrefix().get().getLabels().stream() 35 | .findFirst() 36 | .get())); 37 | }); 38 | }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contributions/archive/ContributeMissingUcumCode.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contributions.archive; 2 | 3 | import io.github.qudtlib.Qudt; 4 | import io.github.qudtlib.model.FactorUnit; 5 | import io.github.qudtlib.model.FactorUnits; 6 | import io.github.qudtlib.model.Unit; 7 | import io.github.qudtlib.tools.contribute.QudtEntityGenerator; 8 | import io.github.qudtlib.vocab.QUDT; 9 | import java.util.ArrayList; 10 | import java.util.Comparator; 11 | import java.util.List; 12 | 13 | public class ContributeMissingUcumCode { 14 | 15 | public static void main(String[] args) throws Exception { 16 | QudtEntityGenerator entityGenerator = new QudtEntityGenerator(false); 17 | 18 | entityGenerator.unitOfWork( 19 | tool -> { 20 | List allUnits = new ArrayList<>(Qudt.allUnits()); 21 | allUnits.stream() 22 | .sorted(Comparator.comparing(Unit::getIri)) 23 | .filter(u -> u.getUcumCode().isEmpty()) 24 | .forEach( 25 | u -> { 26 | List factorUnitList = 27 | u.getFactorUnits().getFactorUnits(); 28 | if (factorUnitList.isEmpty()) { 29 | System.err.println( 30 | String.format( 31 | "Cannot add ucumCode for %s: unit has no factor units", 32 | u.getIri())); 33 | return; 34 | } 35 | FactorUnits factorUnits = 36 | new FactorUnits( 37 | FactorUnits.sortAccordingToUnitLocalname( 38 | u.getIriLocalname(), 39 | factorUnitList)); 40 | try { 41 | String ucumCode = 42 | factorUnits.getUcumCode().orElse(null); 43 | if (ucumCode != null) { 44 | tool.addDerivedUnit( 45 | factorUnits, ud -> ud.ucumCode(ucumCode)); 46 | } else { 47 | System.err.println( 48 | String.format( 49 | "Cannot add ucumCode for %s: one of the constituent units has no ucumCode", 50 | u.getIri())); 51 | } 52 | } catch (Exception e) { 53 | System.err.println( 54 | String.format( 55 | "Cannot add ucum code for %s", 56 | u.getIri())); 57 | } 58 | }); 59 | }); 60 | entityGenerator.writeRdf(s -> s.getPredicate().equals(QUDT.ucumCode)); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/java/io/github/qudtlib/tools/contributions/archive/ContributeRman.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.tools.contributions.archive; 2 | 3 | import static io.github.qudtlib.model.Units.MilliR_man; 4 | import static io.github.qudtlib.model.Units.SV; 5 | 6 | import io.github.qudtlib.model.FactorUnits; 7 | import io.github.qudtlib.tools.contribute.QudtEntityGenerator; 8 | import java.math.BigDecimal; 9 | 10 | public class ContributeRman { 11 | public static void main(String[] args) { 12 | QudtEntityGenerator entityGenerator = new QudtEntityGenerator(); 13 | entityGenerator.unitOfWork( 14 | tool -> { 15 | FactorUnits fu = 16 | FactorUnits.builder() 17 | .scaleFactor(new BigDecimal("0.01")) 18 | .factor(SV) 19 | .build(); 20 | tool.addDerivedUnit( 21 | fu, 22 | def -> { 23 | MilliR_man.getQuantityKinds().forEach(def::addQuantityKind); 24 | def.symbol("rem") 25 | .ucumCode("REM") 26 | .clearLabels() 27 | .addLabel("roentgen equivalent man", "en"); 28 | }, 29 | meta -> 30 | meta.plainTextDescription( 31 | "The roentgen equivalent man (rem)[1][2] is a CGS unit of equivalent dose, effective dose, and committed dose, which are dose measures used to estimate potential health effects of low levels of ionizing radiation on the human body.") 32 | .qudtInformativeReference( 33 | "https://en.wikipedia.org/wiki/Roentgen_equivalent_man"), 34 | "R_man"); 35 | }); 36 | entityGenerator.writeRdf(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /qudtlib-tools/src/main/resources/contribute/contribution-shapes.ttl: -------------------------------------------------------------------------------- 1 | @prefix rdf: . 2 | @prefix rdfs: . 3 | @prefix xsd: . 4 | @prefix qls: . 5 | @prefix qudt: . 6 | @prefix sh: . 7 | 8 | qls:QuantityKindForContributionShape 9 | a sh:NodeShape ; 10 | sh:property [ 11 | sh:datatype rdf:langString ; 12 | sh:message "rdfs:label is missing" ; 13 | sh:minCount 1 ; 14 | sh:path rdfs:label ; 15 | ] ; 16 | sh:property [ 17 | sh:maxCount 1 ; 18 | sh:message "qudt:hasDimensionVector is missing or not an IRI" ; 19 | sh:minCount 1 ; 20 | sh:nodeKind sh:IRI ; 21 | sh:path qudt:hasDimensionVector ; 22 | ] ; 23 | sh:property [ 24 | sh:datatype xsd:string ; 25 | sh:maxCount 1 ; 26 | sh:message "qudt:plainTextDescription is missing or not of datatype xsd:string" ; 27 | sh:minCount 1 ; 28 | sh:path qudt:plainTextDescription ; 29 | ] ; 30 | sh:property [ 31 | sh:maxCount 1 ; 32 | sh:message "qudt:isDefinedBy is missing or not an IRI" ; 33 | sh:minCount 1 ; 34 | sh:nodeKind sh:IRI ; 35 | sh:path rdfs:isDefinedBy ; 36 | ] ; 37 | sh:targetClass qudt:QuantityKind . 38 | 39 | qls:UnitForContributionShape 40 | a sh:NodeShape ; 41 | sh:property [ 42 | sh:datatype rdf:langString ; 43 | sh:message "rdfs:label is missing" ; 44 | sh:minCount 1 ; 45 | sh:path rdfs:label ; 46 | ] ; 47 | sh:property [ 48 | sh:datatype xsd:decimal ; 49 | sh:maxCount 1 ; 50 | sh:message "qudt:conversionMultiplier is missing, duplicated, or not of datatype xsd:decimal" ; 51 | sh:minCount 1 ; 52 | sh:path qudt:conversionMultiplier ; 53 | ] ; 54 | sh:property [ 55 | sh:datatype xsd:decimal ; 56 | sh:maxCount 1 ; 57 | sh:message "qudt:conversionOffset is duplicated or not of datatype xsd:decimal" ; 58 | sh:path qudt:conversionOffset ; 59 | ] ; 60 | sh:property [ 61 | sh:maxCount 1 ; 62 | sh:message "qudt:hasDimensionVector is missing or not an IRI" ; 63 | sh:minCount 1 ; 64 | sh:nodeKind sh:IRI ; 65 | sh:path qudt:hasDimensionVector ; 66 | ] ; 67 | sh:property [ 68 | sh:datatype xsd:string ; 69 | sh:maxCount 1 ; 70 | sh:message "qudt:plainTextDescription is missing or not of datatype xsd:string" ; 71 | sh:minCount 1 ; 72 | sh:path qudt:plainTextDescription ; 73 | ] ; 74 | sh:property [ 75 | sh:maxCount 1 ; 76 | sh:message "qudt:hasQuantityKind is missing or not an IRI" ; 77 | sh:minCount 1 ; 78 | sh:nodeKind sh:IRI ; 79 | sh:path qudt:hasQuantityKind ; 80 | ] ; 81 | sh:property [ 82 | sh:maxCount 1 ; 83 | sh:message "qudt:isDefinedBy is missing or not an IRI" ; 84 | sh:minCount 1 ; 85 | sh:nodeKind sh:IRI ; 86 | sh:path rdfs:isDefinedBy ; 87 | ] ; 88 | sh:property [ 89 | sh:datatype xsd:string ; 90 | sh:maxCount 1 ; 91 | sh:message "qudt:symbol is missing or not of datatype xsd:string" ; 92 | sh:minCount 1 ; 93 | sh:path qudt:symbol ; 94 | ] ; 95 | sh:targetClass qudt:Unit . 96 | 97 | 98 | -------------------------------------------------------------------------------- /qudtlib-tools/src/test/java/io/github/qudtlib/model/DimensionVectorTest.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.model; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import org.junit.jupiter.api.Assertions; 6 | import org.junit.jupiter.api.Test; 7 | 8 | class DimensionVectorTest { 9 | 10 | @Test 11 | void getDimensionVectorIri() { 12 | DimensionVector dimensionVector = 13 | new DimensionVector(new float[] {0f, 1f, -0f, 0.5f, -1, 2.5f, 0, 0}); 14 | 15 | String iri = dimensionVector.getDimensionVectorIri(); 16 | 17 | Assertions.assertEquals( 18 | "http://qudt.org/vocab/dimensionvector/A0E1L0I0dot5M-1H2dot5T0D0", iri); 19 | 20 | DimensionVector fromString = new DimensionVector(iri); 21 | 22 | Assertions.assertEquals(dimensionVector, fromString); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /qudtlib-tools/src/test/java/some/pkg/QudtContributionExample.java: -------------------------------------------------------------------------------- 1 | package some.pkg; 2 | 3 | import io.github.qudtlib.Qudt; 4 | import io.github.qudtlib.model.FactorUnits; 5 | import io.github.qudtlib.model.QuantityKind; 6 | import io.github.qudtlib.model.Units; 7 | import io.github.qudtlib.tools.contribute.QudtEntityGenerator; 8 | 9 | public class QudtContributionExample { 10 | public static void main(String[] args) { 11 | QudtEntityGenerator contributionTool = new QudtEntityGenerator(); 12 | 13 | // add entities 14 | contributionTool.unitOfWork( 15 | tool -> { 16 | // Case #3: Regression test for rule Wärmekapazität pro Fläche zu Wärmekapazität 17 | // pro Fläche_J/m²K 18 | // IFC: no IFC MEASURE (userdefined) 19 | FactorUnits jPerM2K = 20 | FactorUnits.ofFactorUnitSpec(Units.J, 1, Units.M, -2, Units.K, -1); 21 | QuantityKind qk = 22 | tool.addQuantityKind( 23 | jPerM2K, 24 | "HeatCapacityPerArea", 25 | unitDef -> 26 | unitDef.addLabel("heat capacity per area", "en") 27 | .addLabel("Wärmekapazität je Fläche", "de")); 28 | tool.addDerivedUnit( 29 | jPerM2K, 30 | unitDef -> 31 | unitDef.addSystemOfUnits(Qudt.SystemsOfUnits.SI) 32 | .addQuantityKind(qk)); 33 | tool.addDerivedUnit( 34 | FactorUnits.ofFactorUnitSpec(Units.KiloJ, 1, Units.M, -2, Units.K, -1), 35 | unitDef -> 36 | unitDef.addSystemOfUnits(Qudt.SystemsOfUnits.SI) 37 | .addQuantityKind(qk)); 38 | tool.addDerivedUnit( 39 | FactorUnits.ofFactorUnitSpec(Units.MegaJ, 1, Units.M, -2, Units.K, -1), 40 | unitDef -> 41 | unitDef.addSystemOfUnits(Qudt.SystemsOfUnits.SI) 42 | .addQuantityKind(qk)); 43 | }); 44 | 45 | // write RDF 46 | contributionTool.writeRdf(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /qudtlib-vocab/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | qudtlib-java 5 | io.github.qudtlib 6 | 6.8.2-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | qudtlib-vocab 11 | jar 12 | 13 | 14 | 15 | org.eclipse.rdf4j 16 | rdf4j-model 17 | 18 | 19 | 20 | 21 | 22 | 23 | org.codehaus.mojo 24 | exec-maven-plugin 25 | 26 | 27 | 28 | java 29 | 30 | 31 | 32 | none 33 | 34 | 35 | 36 | true 37 | true 38 | be.belgif.vocgen.Main 39 | 40 | --filequdt/schema/SCHEMA_QUDT.ttl 41 | --searchClasspath 42 | --long"Quantities, Units, Dimensions and Data Types Ontology" 43 | --shortQUDT 44 | --nshttp://qudt.org/schema/qudt/ 45 | --prefixqudt 46 | --dochttps://www.qudt.org/ 47 | --packageio.github.qudtlib.vocab 48 | --output-dir${project.build.directory}/generated-sources/com/github/qudtlib/vocab 49 | --templaterdf4j 50 | 51 | 52 | 60 | 61 | 62 | org.codehaus.mojo 63 | build-helper-maven-plugin 64 | 65 | 66 | generate-sources 67 | 68 | add-source 69 | 70 | 71 | 72 | ${project.build.directory}/generated-sources/ 73 | ${project.build.directory}/generated-resources/ 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /qudtlib-vocab/src/main/java/io/github/qudtlib/vocab/QUDTX.java: -------------------------------------------------------------------------------- 1 | package io.github.qudtlib.vocab; 2 | 3 | import org.eclipse.rdf4j.model.IRI; 4 | import org.eclipse.rdf4j.model.impl.SimpleValueFactory; 5 | 6 | /** 7 | * Vocabulary extending the QUDT ontology, as used in the QUDTLib's data generation module. 8 | * 9 | * @author Florian Kleedorfer 10 | * @since 1.0 11 | */ 12 | public class QUDTX { 13 | public static final IRI factorUnit = create("factorUnit"); 14 | public static final IRI convertsTo = create("convertsTo"); 15 | public static final IRI FactorUnit = create("FactorUnit"); 16 | public static final IRI exponent = create("exponent"); 17 | 18 | private static IRI create(String localname) { 19 | return SimpleValueFactory.getInstance().createIRI(QUDT.NAMESPACE + localname); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /qudtlib/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | qudtlib-java 5 | io.github.qudtlib 6 | 6.8.2-SNAPSHOT 7 | 8 | 4.0.0 9 | jar 10 | qudtlib 11 | 12 | 13 | io.github.qudtlib 14 | qudtlib-main 15 | ${project.version} 16 | 17 | 18 | io.github.qudtlib 19 | qudtlib-init-hardcoded 20 | ${project.version} 21 | 22 | 23 | io.github.qudtlib 24 | qudtlib-test 25 | ${project.version} 26 | tests 27 | test-jar 28 | test 29 | 30 | 31 | org.junit.jupiter 32 | junit-jupiter 33 | test 34 | 35 | 36 | 37 | 38 | 39 | 40 | org.apache.maven.plugins 41 | maven-surefire-plugin 42 | 43 | 44 | io.github.qudtlib:qudtlib-test:test-jar:tests 45 | 46 | 47 | 48 | 49 | org.apache.maven.plugins 50 | maven-assembly-plugin 51 | 52 | 53 | package 54 | 55 | single 56 | 57 | 58 | 59 | 60 | 61 | jar-with-dependencies 62 | 63 | 64 | 65 | 66 | 67 | --------------------------------------------------------------------------------