diff --git a/build.gradle.kts b/build.gradle.kts index a47a331b4e714b6efab5fb17efac3bcbb4e42023..dfe17d74308c25d41edc76559d3d2c18e687ae4e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,6 +2,8 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin("jvm") version "1.2.51" + `kotlin-dsl` + id("java-gradle-plugin") } repositories { @@ -24,3 +26,12 @@ dependencies { tasks.withType<KotlinCompile> { kotlinOptions.jvmTarget = "1.8" } + +gradlePlugin { + (plugins) { + "ecore2java-plugin" { + id = "ecore2java" + implementationClass = "ecore2java.Ecore2JavaPlugin" + } + } +} diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index dfc52b202062d85ac41f4ba8c315b832312b34a0..0000000000000000000000000000000000000000 --- a/settings.gradle +++ /dev/null @@ -1,2 +0,0 @@ -rootProject.name = 'ecore-to-java' - diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000000000000000000000000000000000000..55ebbbd37b8b85db3623ce4e4559c8910fd6cd32 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,2 @@ +rootProject.name = "ecore2java-gradle" + diff --git a/src/main/kotlin/ecore2java/Ecore2JavaGenerator.kt b/src/main/kotlin/ecore2java/Ecore2JavaGenerator.kt new file mode 100644 index 0000000000000000000000000000000000000000..a20760bb35e01e31805ab1ccd729d4b23ed20494 --- /dev/null +++ b/src/main/kotlin/ecore2java/Ecore2JavaGenerator.kt @@ -0,0 +1,103 @@ +package ecore2java + +import org.eclipse.emf.codegen.ecore.generator.Generator +import org.eclipse.emf.codegen.ecore.genmodel.GenModel +import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage +import org.eclipse.emf.codegen.ecore.genmodel.generator.GenBaseGeneratorAdapter +import org.eclipse.emf.codegen.merge.java.JControlModel +import org.eclipse.emf.common.util.BasicMonitor +import org.eclipse.emf.common.util.Diagnostic +import org.eclipse.emf.common.util.URI +import org.eclipse.emf.ecore.resource.Resource +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl +import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl +import org.gradle.api.logging.Logger +import java.io.ByteArrayOutputStream +import java.io.File +import java.io.PrintStream + +class Ecore2JavaGenerator(outputDir: File, logger: Logger) { + private val resourceSet = ResourceSetImpl().apply { + uriConverter.uriMap[URI.createURI("platform:/resource/")] = URI.createFileURI(outputDir.absolutePath + File.separator) + } + + private val generator = object : Generator() { + override fun getJControlModel() = JControlModel() + }.apply { + adapterFactoryDescriptorRegistry.addDescriptor(GenModelPackage.eNS_URI, OnlyCodeGenModelGeneratorAdapterFactory.Descriptor) + } + + private val monitor = Monitor(logger) + + init { + GenModelPackage.eINSTANCE + + Resource.Factory.Registry.INSTANCE.extensionToFactoryMap.let { + it["genmodel"] = XMIResourceFactoryImpl() + it["ecore"] = XMIResourceFactoryImpl() + } + } + + fun generate(genModelFile: File) { + var oldErr: PrintStream? = System.err + try { + System.setErr(PrintStream(ByteArrayOutputStream())) + } catch (_: Throwable) { + oldErr = null + } + + try { + val genModel = getGenModel(genModelFile) + generator.input = genModel + generator.generate(genModel, GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE, monitor) + } finally { + if (oldErr != null) { + System.setErr(oldErr) + } + } + } + + private fun getGenModel(file: File): GenModel { + val res = resourceSet.getResource(URI.createFileURI(file.absolutePath), true) + + return (res.contents[0] as GenModel).apply { + modelDirectory = "." + setCanGenerate(true) + } + } + + + private class Monitor(private val logger: Logger) : BasicMonitor() { + override fun beginTask(name: String?, totalWork: Int) { + if (name != null && name.isNotEmpty()) { + log(">>> $name") + } + } + + override fun setTaskName(name: String?) { + if (name != null && name.isNotEmpty()) { + log("<>> $name") + } + } + + override fun subTask(name: String?) { + if (name != null && name.isNotEmpty()) { + log(">> $name") + } + } + + override fun setBlocked(reason: Diagnostic) { + super.setBlocked(reason) + log("#> " + reason.message) + } + + override fun clearBlocked() { + log("=> " + blockedReason.message) + super.clearBlocked() + } + + private fun log(msg: String) { + logger.info(msg) + } + } +} diff --git a/src/main/kotlin/ecore2java/Ecore2JavaPlugin.kt b/src/main/kotlin/ecore2java/Ecore2JavaPlugin.kt new file mode 100644 index 0000000000000000000000000000000000000000..705f9dbcb510c04674f39252fdaa96082a09b2d6 --- /dev/null +++ b/src/main/kotlin/ecore2java/Ecore2JavaPlugin.kt @@ -0,0 +1,37 @@ +package ecore2java + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.plugins.JavaPlugin +import org.gradle.api.plugins.JavaPluginConvention +import org.gradle.kotlin.dsl.get +import org.gradle.kotlin.dsl.task +import org.gradle.kotlin.dsl.withConvention +import java.io.File + +@Suppress("unused") +open class Ecore2JavaPlugin : Plugin<Project> { + override fun apply(project: Project) { + project.pluginManager.apply(JavaPlugin::class.java) + + + val extension = project.extensions.create("ecore2java", Ecore2JavaPluginExtension::class.java, project) + + if (extension.genModels.isPresent) { + project.task("generateEcore") { + extension.genModels.get().forEach { inputs.file(it) } + outputs.dir(extension.outputDir) + + doFirst { + val generator = Ecore2JavaGenerator(File(extension.outputDir), logger) + + extension.genModels.get() + .map(::File) + .forEach(generator::generate) + } + } + + project.withConvention(JavaPluginConvention::class) { sourceSets["main"].java.srcDir(extension.outputDir) } + } + } +} diff --git a/src/main/kotlin/ecore2java/Ecore2JavaPluginExtension.kt b/src/main/kotlin/ecore2java/Ecore2JavaPluginExtension.kt new file mode 100644 index 0000000000000000000000000000000000000000..adf4b1f258d5b5862ab016c81188189710934b9e --- /dev/null +++ b/src/main/kotlin/ecore2java/Ecore2JavaPluginExtension.kt @@ -0,0 +1,11 @@ +package ecore2java + +import org.gradle.api.Project +import org.gradle.kotlin.dsl.listProperty + +open class Ecore2JavaPluginExtension(project: Project) { + val genModels = project.objects.listProperty<String>() + var outputDir = "${project.buildDir}/generated-src/ecore/java" + + fun genModel(genModelFile: String) = genModels.add(genModelFile) +} diff --git a/src/main/kotlin/fehnomenal/ecore2java/OnlyCodeGenModelGeneratorAdapterFactory.kt b/src/main/kotlin/ecore2java/OnlyCodeGenModelGeneratorAdapterFactory.kt similarity index 97% rename from src/main/kotlin/fehnomenal/ecore2java/OnlyCodeGenModelGeneratorAdapterFactory.kt rename to src/main/kotlin/ecore2java/OnlyCodeGenModelGeneratorAdapterFactory.kt index 22b3555b1e3ccd4d67003d0855d754aa8fa4709b..7527a3d75053e5999e6bf1ab856ab47729096069 100644 --- a/src/main/kotlin/fehnomenal/ecore2java/OnlyCodeGenModelGeneratorAdapterFactory.kt +++ b/src/main/kotlin/ecore2java/OnlyCodeGenModelGeneratorAdapterFactory.kt @@ -1,4 +1,4 @@ -package fehnomenal.ecore2java +package ecore2java import org.eclipse.emf.codegen.ecore.generator.GeneratorAdapterFactory import org.eclipse.emf.codegen.ecore.genmodel.GenModel diff --git a/src/main/kotlin/fehnomenal/ecore2java/Main.kt b/src/main/kotlin/fehnomenal/ecore2java/Main.kt deleted file mode 100644 index b12564c01d77be5818815577ed405ec202c0c7e5..0000000000000000000000000000000000000000 --- a/src/main/kotlin/fehnomenal/ecore2java/Main.kt +++ /dev/null @@ -1,43 +0,0 @@ -package fehnomenal.ecore2java - -import org.eclipse.emf.codegen.ecore.generator.Generator -import org.eclipse.emf.codegen.ecore.genmodel.GenModel -import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage -import org.eclipse.emf.codegen.ecore.genmodel.generator.GenBaseGeneratorAdapter -import org.eclipse.emf.codegen.merge.java.JControlModel -import org.eclipse.emf.common.util.BasicMonitor -import org.eclipse.emf.common.util.URI -import org.eclipse.emf.ecore.resource.Resource -import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl -import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl -import java.io.File - -fun main(args: Array<String>) { - GenModelPackage.eINSTANCE - - Resource.Factory.Registry.INSTANCE.extensionToFactoryMap.let { - it["genmodel"] = XMIResourceFactoryImpl() - it["ecore"] = XMIResourceFactoryImpl() - } - - generate(File(args[0]), File(args[1])) -} - -private fun generate(genModelFile: File, targetFolder: File) { - val genModel = ResourceSetImpl().run { - uriConverter.uriMap[URI.createURI("platform:/resource/")] = URI.createFileURI(targetFolder.absolutePath + File.separator) - - val rs = getResource(URI.createFileURI(genModelFile.absolutePath), true) - (rs.contents[0] as GenModel).apply { - modelDirectory = "." - setCanGenerate(true) - } - } - - val generator = object : Generator() { - override fun getJControlModel() = JControlModel() - } - generator.adapterFactoryDescriptorRegistry.addDescriptor(GenModelPackage.eNS_URI, OnlyCodeGenModelGeneratorAdapterFactory.Descriptor) - generator.input = genModel - generator.generate(genModel, GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE, BasicMonitor.Printing(System.out)) -}