Skip to content
Snippets Groups Projects
Commit 30a17af9 authored by Rico Bergmann's avatar Rico Bergmann
Browse files

Merge branch 'experimental' into 'develop'

Move away from experimental changes

See merge request !1
parents 3557b6af 516f567d
Branches
No related tags found
2 merge requests!2Publish v0.1,!1Move away from experimental changes
Showing
with 520 additions and 0 deletions
#### joe made this: http://goel.io/joe
#### scala ####
*.class
*.log
#### sbt ####
# Simple Build Tool
# http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html#configuring-version-control
dist/*
target/
lib_managed/
src_managed/
project/boot/
project/plugins/project/
.history
.cache
.lib/
#### jetbrains ####
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
#### java ####
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
#### eclipse ####
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# PyDev specific (Python IDE for Eclipse)
*.pydevproject
# CDT-specific (C/C++ Development Tooling)
.cproject
# CDT- autotools
.autotools
# Java annotation processor (APT)
.factorypath
# PDT-specific (PHP Development Tools)
.buildpath
# sbteclipse plugin
.target
# Tern plugin
.tern-project
# TeXlipse plugin
.texlipse
# STS (Spring Tool Suite)
.springBeans
# Code Recommenders
.recommenders/
# Annotation Processing
.apt_generated/
# Scala IDE specific (Scala & Java development for Eclipse)
.cache-main
.scala_dependencies
.worksheet
# Custom (user defined) insertions
.idea/
.classpath
.project
output/
[submodule "lib/ModelSyncProvider"]
path = lib/ModelSyncProvider
url = https://git-st.inf.tu-dresden.de/cwerner/role_model_synchronization_provider.git
[submodule "lib/SCROLL"]
path = lib/SCROLL
url = https://github.com/portux/SCROLL.git
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="ttc17" nsURI="http://www.example.org/ttc17" nsPrefix="ttc17">
<eClassifiers xsi:type="ecore:EClass" name="Person">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="fullName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="Male" eSuperTypes="#//Person"/>
<eClassifiers xsi:type="ecore:EClass" name="Female" eSuperTypes="#//Person"/>
</ecore:EPackage>
import sbt.Keys.{libraryDependencies, scalacOptions, version}
val emfcommonVersion = "2.12.0"
val emfecoreVersion = "2.12.0"
val scrollVersion = "1.6"
val scoptVersion = "3.7.0"
val syncProvider = RootProject(file("lib/ModelSyncProvider"))
lazy val generator = (project in file("."))
.settings(
name := "CodeGenerator",
version := "0.1",
scalaVersion := "2.12.6",
libraryDependencies ++= Seq(
"org.scala-lang" % "scala-reflect" % scalaVersion.value,
"org.scala-lang" % "scala-compiler" % scalaVersion.value,
"org.eclipse.emf" % "org.eclipse.emf.common" % emfcommonVersion,
"org.eclipse.emf" % "org.eclipse.emf.ecore" % emfecoreVersion,
"com.github.scopt" %% "scopt" % scoptVersion
),
scalacOptions ++= Seq(
"-language:implicitConversions"
),
mainClass in assembly := Some("org.rosi_project.model_sync.generator.Generator"),
assemblyMergeStrategy in assembly := {
case "MANIFEST.MF" => MergeStrategy.first
case "plugin.xml" => MergeStrategy.discard
case "plugin.properties" => MergeStrategy.discard
case "generated_package.exsd" => MergeStrategy.discard
case "dynamic_package.exsd" => MergeStrategy.discard
case PathList("schema", ps @ _ *) if ps.lastOption.exists(_.endsWith("generated_package.exsd")) => MergeStrategy.discard
case PathList("schema", ps @ _ *) if ps.lastOption.exists(_.endsWith("dynamic_package.exsd")) => MergeStrategy.discard
case x =>
val oldStrategy = (assemblyMergeStrategy in assembly).value
oldStrategy(x)
}
).dependsOn(syncProvider)
Subproject commit ace8bdf5799dd89bd66d01782237123172bb0ec0
Subproject commit 623765816af6d27387efb82dfb890bc4318c58a2
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.7")
sbt.version = 1.2.1
\ No newline at end of file
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.2.4")
addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "1.0.0")
package org.rosi_project.model_sync.generator
import java.io.File
/**
* @author Rico Bergmann
*/
case class Config(source: String = "", cleanUp: Boolean = false, outDir: File = new File(System.getProperty("user.dir"))) {
}
package org.rosi_project.model_sync.generator
import org.eclipse.emf.ecore._
import org.eclipse.emf.ecore.resource.Resource
import org.rosi_project.model_sync.generator.conversion.SModelGenerator
import org.rosi_project.model_sync.generator.io.SModelFSWriter
import org.rosi_project.model_sync.generator.sync_model.{GetterSetterGeneratingVisitor, SModel, SyncEnhancingVisitor}
import scopt.OptionParser
import scroll.internal.ecore.ECoreImporter
import scala.reflect.io.File
import java.{io => jio}
/**
* @author Rico Bergmann
*/
object Generator extends App {
// TODO CLI parser (scopt) here
// gen -c(leanup) -o [outdir] ECOREFILE
val parser = new OptionParser[Config](programName="modelgen") {
head("modelgen", "0.1")
arg[jio.File]("ecore").required().action( (ef, conf) =>
conf.copy(source = ef.getAbsolutePath)
).text("The ecore (XML) file of the model")
opt[jio.File]('o', "outdir").optional().action( (dir, conf) =>
conf.copy(outDir = dir)
).text("The directory to place the generated model in (current dir by default)")
opt[Unit]('c', "cleanup").optional().action( (_, conf) =>
conf.copy(cleanUp = true)
).text("Remove the generated .scala files and only keep the compiled .class files")
}
parser.parse(args, Config()) match {
case Some(config) =>
val ecoreModel = loadEcore(config.source)
val sModel = SModelGenerator.convert(ecoreModel)
prepareModel(sModel)
sModel.accept(new SModelFSWriter(outputDir = File(config.outDir).toDirectory, keepClassFiles = !config.cleanUp))
case None =>
}
def loadEcore(path: String = "assets/ttc17.ecore"): EPackage = {
val importer = new ECoreImporter {
def lm(): Resource = loadModel()
}
importer.path = path
val res = importer.lm()
res.getContents.toArray(new Array[EObject](0)).toList.find(_.isInstanceOf[EPackage]).map((p: EObject) => p.asInstanceOf[EPackage]).orNull
}
def prepareModel(sModel: SModel): Unit = {
val getterSetterVisitor = new GetterSetterGeneratingVisitor
val syncNotificationVisitor = new SyncEnhancingVisitor
sModel.accept(getterSetterVisitor)
sModel.accept(syncNotificationVisitor)
}
}
package org.rosi_project.model_sync.generator.acr
import org.rosi_project.model_sync.generator.sync_model.SModelVisitor
/**
* @author Rico Bergmann
*/
case class SAttribute(name: String, attrType: STypedElement) extends SModelElement {
def getType: String = attrType.getName
override def accept(visitor: SModelVisitor): Unit = visitor.visit(this)
}
package org.rosi_project.model_sync.generator.acr
import org.rosi_project.model_sync.generator.sync_model.SModelVisitor
/** Abstraction of a model element class which should be synced.
*
* @author Rico Bergmann
*/
class SClass(val name: String,
var attributes: Seq[SAttribute] = Seq.empty,
val sPackage: String = "",
var parent: STypedElement = null,
var methods: Seq[SMethod] = Seq.empty)
extends STypedElement {
private var constructorStatements: Seq[SMethodStatement] = Seq.empty
def getAdditionalConstructorStatements: Seq[SMethodStatement] = constructorStatements
def isDefaultPackage: Boolean = sPackage == ""
def isRootClass: Boolean = parent == null
def collectImports: Set[String] = {
val parentImport: List[String] = if (isRootClass) List() else includeImportIfNecessary(parent.getPackage, parent.getName)
val attrTypeImports: List[String] =
attributes
.map(attr => includeImportIfNecessary(attr.attrType.getPackage, attr.getType))
.fold(List())((l1, l2) => l1 ++ l2)
val methodResultImports: List[String] =
methods
.map(_.result)
.map(res => includeImportIfNecessary(res.getPackage, res.getName))
.fold(List())((l1, l2) => l1 ++ l2)
val methodParamImports: List[String] =
methods
.map(_.params)
.fold(List())((l1, l2) => l1 ++ l2)
.map(param => includeImportIfNecessary(param.paramType.getPackage, param.paramType.getName))
.fold(List())((l1, l2) => l1 ++ l2)
val methodImplImports: List[String] =
methods
.map(_.implementationUsedTypes.toList)
.fold(List())((l1, l2) => l1 ++ l2)
.map(typ => includeImportIfNecessary(typ.getName, typ.getPackage))
.fold(List())((l1, l2) => l1 ++ l2)
(parentImport ++ attrTypeImports ++ methodResultImports ++ methodParamImports ++ methodImplImports).toSet
}
def addMethod(m: SMethod): Unit = methods = methods :+ m
def augmentConstructor(statement: SMethodStatement): Unit = constructorStatements = constructorStatements :+ statement
def setParent(parent: STypedElement): Unit = this.parent = parent
def setAttributes(attrs: Seq[SAttribute]): Unit = this.attributes = attrs
override def getName: String = name
override def getPackage: String = sPackage
override def getConstructorParameters: Seq[SMethodParameter] = {
val ownParams = attributes.map(attr => SMethodParameter(attr.name, attr.attrType))
val parentParams = if (isRootClass) List() else parent.getConstructorParameters
ownParams ++ parentParams
}
override def getInheritanceHierarchy: Seq[STypedElement] = if (isRootClass) List(this) else this +: parent.getInheritanceHierarchy
override def accept(visitor: SModelVisitor): Unit = {
attributes.foreach(_.accept(visitor))
methods.foreach(_.accept(visitor))
visitor.visit(this)
}
private def includeImportIfNecessary(sPackage: String, sClass: String): List[String] = {
if (sPackage != this.sPackage && sPackage != "") List(s"$sPackage.$sClass") else List()
}
override def toString: String = s"$name"
}
package org.rosi_project.model_sync.generator.acr
import org.rosi_project.model_sync.generator.support.StringUtils
/**
* @author Rico Bergmann
*/
class SGetter(attr: SAttribute) extends SMethod(
name = s"get${StringUtils.firstLetterToUpperCase(attr.name)}",
result = attr.attrType,
params = Seq.empty,
implementation = Seq(SMethodStatement(attr.name))) {
}
package org.rosi_project.model_sync.generator.acr
import org.rosi_project.model_sync.generator.sync_model.SModelVisitor
// TODO use a simple DSL to represent the method body
/**
* @author Rico Bergmann
*/
class SMethod(val name: String,
val result: STypedElement,
val params: Seq[SMethodParameter],
var implementation: Seq[SMethodStatement],
var implementationUsedTypes: Set[STypedElement] = Set.empty)
extends SModelElement {
def getResultType: String = result.getName
def updateImplementation(impl: Seq[SMethodStatement]): Unit = this.implementation = impl
def augmentImplementation(statement: SMethodStatement): Unit = this.implementation = this.implementation :+ statement
override def accept(visitor: SModelVisitor): Unit = visitor.visit(this)
override def toString: String = s"$name"
}
package org.rosi_project.model_sync.generator.acr
/**
* @author Rico Bergmann
*/
case class SMethodParameter(name: String, paramType: STypedElement) {
def getType: String = paramType.getName
}
package org.rosi_project.model_sync.generator.acr
/**
* @author Rico Bergmann
*/
case class SMethodStatement(content: String) {
}
package org.rosi_project.model_sync.generator.acr
import org.rosi_project.model_sync.generator.sync_model.SModelVisitor
/**
* @author Rico Bergmann
*/
trait SModelElement {
def accept(visitor: SModelVisitor)
}
package org.rosi_project.model_sync.generator.acr
import org.rosi_project.model_sync.generator.support.StringUtils
/**
* @author Rico Bergmann
*/
class SSetter(attr: SAttribute) extends SMethod(
name = s"set${StringUtils.firstLetterToUpperCase(attr.name)}",
result = SType.UNIT,
params = Seq(SMethodParameter(attr.name.head.toString, attr.attrType)),
implementation = Seq(SMethodStatement(s"${attr.name} = ${attr.name.head}"))) {
}
package org.rosi_project.model_sync.generator.acr
import org.rosi_project.model_sync.generator.sync_model.SModelVisitor
/**
* @author Rico Bergmann
*/
case class SType(name: String, sPackage: String = "") extends STypedElement {
override def getName: String = name
override def getPackage: String = sPackage
override def accept(visitor: SModelVisitor): Unit = visitor.visit(this)
}
object SType {
val UNIT = SType("Unit")
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment