Skip to content

Commit 4578f4b

Browse files
committed
ont-converter: init gradle-kt building, add parsing Args via kotlin-cli
1 parent fb89d2b commit 4578f4b

File tree

7 files changed

+247
-0
lines changed

7 files changed

+247
-0
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@ target
99
.idea/
1010
/out*
1111
/logs/
12+
/gradlew.bat
13+
/gradlew
14+
/build/
15+
/gradle/

build.gradle.kts

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
2+
3+
plugins {
4+
kotlin("jvm") version "1.6.10"
5+
application
6+
}
7+
8+
group = "com.github.sszuev"
9+
version = "2.0.0-SNAPSHOT"
10+
description = "A simple command-line utility to convert any RDF graph to OWL2-DL ontology"
11+
12+
repositories {
13+
mavenCentral()
14+
}
15+
16+
dependencies {
17+
val kotlincliVersion = "0.3.4"
18+
val ontapiVersion = "3.0.0"
19+
val owlapiVersion = "5.1.20"
20+
21+
implementation("org.jetbrains.kotlinx:kotlinx-cli:$kotlincliVersion")
22+
implementation("com.github.owlcs:ontapi:$ontapiVersion")
23+
implementation("net.sourceforge.owlapi:owlapi-parsers:$owlapiVersion")
24+
25+
testImplementation(kotlin("test"))
26+
}
27+
28+
tasks.test {
29+
useJUnitPlatform()
30+
}
31+
32+
tasks.withType<KotlinCompile> {
33+
kotlinOptions.jvmTarget = "11"
34+
}
35+
36+
application {
37+
mainClass.set("com.github.sszuev.ontconverter.MainKt")
38+
}
39+
40+
tasks {
41+
val fatJar = register<Jar>("fatJar") {
42+
dependsOn.addAll(
43+
listOf(
44+
"compileJava",
45+
"compileKotlin",
46+
"processResources"
47+
)
48+
) // We need this for Gradle optimization to work
49+
archiveFileName.set(rootProject.name + ".jar")
50+
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
51+
manifest {
52+
attributes(mapOf("Main-Class" to application.mainClass))
53+
} // Provided we set it up in the application plugin configuration
54+
val sourcesMain = sourceSets.main.get()
55+
val contents = configurations.runtimeClasspath.get()
56+
.map { if (it.isDirectory) it else zipTree(it) } +
57+
sourcesMain.output
58+
from(contents)
59+
}
60+
build {
61+
dependsOn(fatJar) // Trigger fat jar creation during build
62+
}
63+
}

gradle.properties

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
kotlin.code.style=official

settings.gradle.kts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
rootProject.name = "ont-converter"
2+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.github.sszuev.ontconverter
2+
3+
import com.github.owlcs.ontapi.OntFormat
4+
import com.github.owlcs.ontapi.jena.impl.conf.OntModelConfig
5+
import java.nio.file.Path
6+
7+
data class Args(
8+
val inputFile: Path,
9+
val inputFormat: OntFormat?,
10+
val outputFile: Path,
11+
val outputFormat: OntFormat,
12+
val punnings: OntModelConfig.StdMode,
13+
val spin: Boolean,
14+
val refine: Boolean,
15+
val web: Boolean,
16+
val force: Boolean,
17+
val verbose: Boolean
18+
) {
19+
20+
fun printString(): String {
21+
return """
22+
|Arguments:
23+
| inputFile=$inputFile
24+
| inputFormat=$inputFormat
25+
| outputFile=$outputFile
26+
| outputFormat=$outputFormat
27+
| punnings=$punnings
28+
| spin=$spin
29+
| refine=$refine
30+
| web=$web
31+
| force=$force
32+
| verbose=$verbose
33+
""".trimMargin()
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package com.github.sszuev.ontconverter
2+
3+
import com.github.owlcs.ontapi.OntFormat
4+
import com.github.owlcs.ontapi.jena.impl.conf.OntModelConfig
5+
import com.github.sszuev.ontconverter.utils.supportedReadFormats
6+
import com.github.sszuev.ontconverter.utils.supportedWriteFormats
7+
import kotlinx.cli.ArgParser
8+
import kotlinx.cli.ArgType
9+
import kotlinx.cli.default
10+
import kotlinx.cli.required
11+
import java.nio.file.Files
12+
import java.nio.file.Path
13+
import java.nio.file.Paths
14+
import java.util.*
15+
16+
fun main(argsArray: Array<String>) {
17+
val args = parse(argsArray)
18+
println(args.printString())
19+
}
20+
21+
private fun parse(args: Array<String>): Args {
22+
val locale = Locale.ENGLISH
23+
val parser = ArgParser("java -jar ont-converter.jar")
24+
val inputStringPath by parser.option(
25+
ArgType.String, shortName = "i", fullName = "input",
26+
description = """
27+
The file path or not-empty directory to load ontology/ontologies.
28+
""".trimIndent()
29+
).required()
30+
val inputFormat by parser.option(
31+
ArgType.Choice(supportedReadFormats(), { e -> OntFormat.valueOf(e) }, { it.name }),
32+
shortName = "if", fullName = "input-format",
33+
description = """
34+
The input format. If not specified the program will choose
35+
the most suitable one to load ontology from a file.
36+
""".trimIndent()
37+
)
38+
val outputStringPath by parser.option(
39+
ArgType.String, shortName = "o", fullName = "output",
40+
description = """
41+
The file or directory path to store result ontology/ontologies.
42+
If the --input is a file then this parameter must also be a file.
43+
""".trimIndent()
44+
).required()
45+
val outputFormat by parser.option(
46+
ArgType.Choice(supportedWriteFormats(), { OntFormat.valueOf(it.uppercase(locale)) }, { it.name }),
47+
shortName = "of", fullName = "output-format",
48+
description = """
49+
The format of output ontology/ontologies.
50+
""".trimIndent()
51+
).required()
52+
53+
val punnings by parser.option(
54+
ArgType.Choice<OntModelConfig.StdMode>({ OntModelConfig.StdMode.valueOf(it.uppercase(locale)) }, { it.name }),
55+
shortName = "p", fullName = "punnings",
56+
description = """
57+
The punning mode. Could be used in conjunction with --refine option. Must be one of the following:
58+
Lax mode: allows any punnings, i.e. ontology is allowed to contain multiple entity declarations
59+
Middle mode: two forbidden intersections: Datatype <-> Class & NamedObjectProperty <-> DatatypeProperty
60+
Strict mode: all punnings are forbidden, i.e. Datatype <-> Class and rdf:Property intersections
61+
(any pairs of NamedObjectProperty, DatatypeProperty, AnnotationProperty).
62+
""".trimIndent()
63+
).default(OntModelConfig.StdMode.LAX)
64+
65+
val spin by parser.option(
66+
ArgType.Boolean, shortName = "s", fullName = "spin",
67+
description = """
68+
Use spin transformation to replace rdf:List based spin-constructs (e.g sp:Select)
69+
with their text-literal representation to produce compact axioms list.
70+
""".trimIndent()
71+
).default(false)
72+
73+
val refine by parser.option(
74+
ArgType.Boolean, shortName = "r", fullName = "refine",
75+
description = """
76+
Refine output:
77+
if specified the resulting ontologies will consist only of the OWL2-DL components (annotations and axioms),
78+
otherwise there could be some rdf-stuff (in case the output format is provided by jena)
79+
""".trimIndent()
80+
).default(false)
81+
82+
val web by parser.option(
83+
ArgType.Boolean, shortName = "w", fullName = "web",
84+
description = """
85+
Allow web/ftp diving to retrieve dependent ontologies from imports (owl:imports),
86+
otherwise the specified directory (see --input) will be used as the only source.
87+
""".trimIndent()
88+
).default(false)
89+
90+
val force by parser.option(
91+
ArgType.Boolean, shortName = "f", fullName = "force",
92+
description = "Ignore any exceptions while loading/saving and processing imports."
93+
).default(false)
94+
95+
val verbose by parser.option(
96+
ArgType.Boolean, shortName = "v", fullName = "verbose",
97+
description = "To print progress messages to console."
98+
).default(false)
99+
100+
parser.parse(args)
101+
102+
val input = Paths.get(inputStringPath).toRealPath()
103+
val output = parseOutput(outputStringPath, input)
104+
105+
return Args(input, inputFormat, output, outputFormat, punnings, spin, refine, web, force, verbose)
106+
}
107+
108+
private fun parseOutput(outputStringPath: String, input: Path): Path {
109+
var out: Path = Paths.get(outputStringPath)
110+
if (out.parent != null) {
111+
require(Files.exists(out.parent)) { "Directory ${out.parent} does not exist." }
112+
out = out.parent.toRealPath().resolve(out.fileName)
113+
}
114+
if (Files.isDirectory(input) &&
115+
Files.walk(input).filter { Files.isRegularFile(it) }.skip(1).findFirst().isPresent
116+
) {
117+
// if input is a directory with more than one file, then out should be a directory
118+
if (Files.exists(out)) {
119+
out = if (!Files.isDirectory(out)) {
120+
throw IllegalArgumentException("Output parameter is not a directory path: $out")
121+
} else {
122+
out.toRealPath()
123+
}
124+
} else {
125+
Files.createDirectory(out)
126+
}
127+
}
128+
return out
129+
}
130+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.github.sszuev.ontconverter.utils
2+
3+
import com.github.owlcs.ontapi.OntFormat
4+
import kotlin.streams.toList
5+
6+
fun supportedReadFormats(): List<OntFormat> {
7+
return OntFormat.formats().filter(OntFormat::isReadSupported).toList()
8+
}
9+
10+
fun supportedWriteFormats(): List<OntFormat> {
11+
return OntFormat.formats().filter(OntFormat::isWriteSupported).toList()
12+
}

0 commit comments

Comments
 (0)