diff --git a/build/de.cau.cs.kieler.spviz.repository/pom.xml b/build/de.cau.cs.kieler.spviz.repository/pom.xml index 6ae1c31..aa08210 100644 --- a/build/de.cau.cs.kieler.spviz.repository/pom.xml +++ b/build/de.cau.cs.kieler.spviz.repository/pom.xml @@ -8,8 +8,8 @@ Kieler Software Project Visualization Repository - de.cau.cs.kieler.spviz - parent + de.cau.cs.kieler + spviz-parent 0.3.1-SNAPSHOT ../pom.xml diff --git a/build/de.cau.cs.kieler.spviz.targetplatform/pom.xml b/build/de.cau.cs.kieler.spviz.targetplatform/pom.xml index 228d5df..54509eb 100644 --- a/build/de.cau.cs.kieler.spviz.targetplatform/pom.xml +++ b/build/de.cau.cs.kieler.spviz.targetplatform/pom.xml @@ -8,8 +8,8 @@ Software Project Visualization Target Platform - de.cau.cs.kieler.spviz - parent + de.cau.cs.kieler + spviz-parent 0.3.1-SNAPSHOT ../pom.xml diff --git a/build/pom.xml b/build/pom.xml index 616d640..b2744fd 100644 --- a/build/pom.xml +++ b/build/pom.xml @@ -2,20 +2,25 @@ 4.0.0 - de.cau.cs.kieler.spviz - parent + de.cau.cs.kieler + spviz-parent 0.3.1-SNAPSHOT pom - 2.7.3 + 2.7.5 2.33.0 + 2.33.0 17  (Sources) + + 17 + + 17 UTF-8 @@ -25,7 +30,7 @@ - repo + all true @@ -39,6 +44,7 @@ ../plugins/de.cau.cs.kieler.spviz.spvizmodel ../plugins/de.cau.cs.kieler.spviz.spvizmodel.ide ../plugins/de.cau.cs.kieler.spviz.spvizmodel.ui + ../cli/de.cau.cs.kieler.spviz.cli ../features/de.cau.cs.kieler.spviz.feature ../features/de.cau.cs.kieler.spviz.ui.feature @@ -70,7 +76,7 @@ - de.cau.cs.kieler.spviz + de.cau.cs.kieler de.cau.cs.kieler.spviz.targetplatform ${project.version} diff --git a/cli/de.cau.cs.kieler.spviz.cli/.classpath b/cli/de.cau.cs.kieler.spviz.cli/.classpath new file mode 100644 index 0000000..2713a9b --- /dev/null +++ b/cli/de.cau.cs.kieler.spviz.cli/.classpath @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/cli/de.cau.cs.kieler.spviz.cli/.project b/cli/de.cau.cs.kieler.spviz.cli/.project new file mode 100644 index 0000000..16e7320 --- /dev/null +++ b/cli/de.cau.cs.kieler.spviz.cli/.project @@ -0,0 +1,29 @@ + + + de.cau.cs.kieler.spviz.cli + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.xtext.ui.shared.xtextBuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + org.eclipse.jdt.core.javanature + org.eclipse.xtext.ui.shared.xtextNature + + diff --git a/cli/de.cau.cs.kieler.spviz.cli/build.properties b/cli/de.cau.cs.kieler.spviz.cli/build.properties new file mode 100644 index 0000000..7d7c57c --- /dev/null +++ b/cli/de.cau.cs.kieler.spviz.cli/build.properties @@ -0,0 +1,4 @@ +source.. = src/,\ + xtend-gen/ +bin.includes = . +bin.excludes = **/*.xtend diff --git a/cli/de.cau.cs.kieler.spviz.cli/pom.xml b/cli/de.cau.cs.kieler.spviz.cli/pom.xml new file mode 100644 index 0000000..b7bbbda --- /dev/null +++ b/cli/de.cau.cs.kieler.spviz.cli/pom.xml @@ -0,0 +1,141 @@ + + + 4.0.0 + + de.cau.cs.kieler + spviz-parent + 0.3.1-SNAPSHOT + ../../build/pom.xml + + + de.cau.cs.kieler.spviz.cli + + + + de.cau.cs.kieler + de.cau.cs.kieler.spviz.spviz + ${project.version} + + + de.cau.cs.kieler + de.cau.cs.kieler.spviz.spvizmodel + ${project.version} + + + + info.picocli + picocli + 4.7.6 + + + org.eclipse.emf + org.eclipse.emf.codegen + 2.23.0 + + + org.slf4j + slf4j-simple + 2.0.14 + + + org.eclipse.xtend + org.eclipse.xtend.lib + ${xtend-version} + + + org.eclipse.xtext + org.eclipse.xtext.ide + ${xtext-version} + + + org.eclipse.xtext + org.eclipse.xtext.xbase.lib + ${xtext-version} + + + + + src + + + + org.eclipse.xtend + xtend-maven-plugin + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + true + + + de.cau.cs.kieler.spviz.cli.SPVizCLI + + + plugin.properties + + + false + + + + + + + *:* + + **/*._trace + **/*.ecore + **/*.g + **/*.genmodel + **/*.mwe2 + **/*.xsd + **/*.xtext + *.profile + *.html + .api_description + .genmodel + .options + about.* + about_files/* + fragment.properties + META-INF/*.inf + META-INF/*.RSA + META-INF/*.SF + META-INF/INDEX.LIST + META-INF/MANIFEST.MF + modeling32.png + OSGI-INF/l10n/bundle.properties + plugin.xml + profile.list + schema/*.exsd + systembundle.properties + xtext32.png + + + + org.eclipse.platform:* + + **/*.png + + + + true + spviz-cli + false + + + + + shade + + + + + + + diff --git a/cli/de.cau.cs.kieler.spviz.cli/src/de/cau/cs/kieler/spviz/cli/SPVizCLI.xtend b/cli/de.cau.cs.kieler.spviz.cli/src/de/cau/cs/kieler/spviz/cli/SPVizCLI.xtend new file mode 100644 index 0000000..cca2803 --- /dev/null +++ b/cli/de.cau.cs.kieler.spviz.cli/src/de/cau/cs/kieler/spviz/cli/SPVizCLI.xtend @@ -0,0 +1,170 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright 2024 by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License 2.0 (EPL-2.0). + */ + +package de.cau.cs.kieler.spviz.cli + +import de.cau.cs.kieler.spviz.spviz.SPVizStandaloneSetup +import de.cau.cs.kieler.spviz.spviz.generator.SPVizGenerator +import de.cau.cs.kieler.spviz.spviz.sPViz.SPViz +import de.cau.cs.kieler.spviz.spvizmodel.SPVizModelStandaloneSetup +import de.cau.cs.kieler.spviz.spvizmodel.generator.SPVizModelGenerator +import java.io.BufferedReader +import java.io.File +import java.io.InputStreamReader +import java.nio.file.Path +import java.util.ArrayList +import java.util.List +import org.eclipse.emf.common.util.URI +import org.eclipse.emf.ecore.resource.Resource +import org.eclipse.xtext.resource.XtextResourceSet +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import picocli.CommandLine +import picocli.CommandLine.Command +import picocli.CommandLine.Option +import picocli.CommandLine.Parameters + +/** + * A command line tool to generate projects from SPViz DSL files. + * This can be configured via command line parameters. + * + * @author nre + */ +@Command(name = "spviz") +class SPVizCLI implements Runnable { + + static final Logger LOGGER = LoggerFactory.getLogger(SPVizCLI) + + /** + * All files for which this tool should generate the projects. Only accepts .spvizmodel and .spviz files. + */ + @Parameters(arity = "1..*", description = "Any number of .spvizmodel or .spviz input files. Other files types will be ignored.") + protected List files = new ArrayList + + /** + * The .spvizmodel files given to this tool. + */ + List spvizModelFiles = new ArrayList + + /** + * The .spviz files given to this tool. + */ + List spvizFiles = new ArrayList + + /** + * The paths to the folders of the projects, that should be documented. + */ + @Option(names = #["-o", "--output"], paramLabel = "OUTPUT-PATH", defaultValue = ".", + description = "The path to the output folder where the generated projects should be stored. Defaults to the current working directory.") + protected Path output + + @Option(names = #["-h", "--help"], usageHelp = true, description = "display a help message") + protected boolean help + + @Option(names = #["-b", "--build"], defaultValue = "false", description = "Automatically build the generated visualization projects with Maven.") + protected boolean build + + @Option(names = #["-g", "--build-generator"], defaultValue = "false", description = "Automatically build the generator projects with Maven.") + protected boolean buildGenerator + + /** + * Main entry point for this command line tool. + */ + def static void main(String[] args) { + val CommandLine cl = new CommandLine(new SPVizCLI()) + System.exit(cl.execute(args)) + } + + override void run() { + // Individually list all .spvizmodel and .spviz files from the parameters. + spvizModelFiles.addAll(files.filter[ + name.endsWith(".spvizmodel") + ]) + spvizFiles.addAll(files.filter[ + name.endsWith(".spviz") + ]) + + val XtextResourceSet rs = new XtextResourceSet + // Comment this line in if the lazy loading causes problems later when resolving the spvizmodel artifacts referred by the spviz file. + // This would load the referenced model immediately instead. Should not be necessary. +// rs.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE) + + try { + // Prepare loading .spvizmodel files. + SPVizModelStandaloneSetup.doSetup + for (spvizModelFile : spvizModelFiles) { + // Parse the model file. + LOGGER.info("Generating sources for {}", spvizModelFile.absolutePath) + val Resource resource = rs.getResource(URI.createURI("file://" + spvizModelFile.absolutePath), true) + SPVizModelGenerator.generate(resource, output) + } + + // Prepare loading .spviz files. + SPVizStandaloneSetup.doSetup + for (spvizFile : spvizFiles) { + // Parse the visualization file. A full absolute URI with file:// scheme is important, so that the resource + // can correctly resolve the imported .spvizmodel file. + LOGGER.info("Generating sources for {}", spvizFile.absolutePath) + val Resource resource = rs.createResource(URI.createURI("file://" + spvizFile.absolutePath)) + resource.load(rs.getLoadOptions()) + SPVizGenerator.generate(resource, output) + + // Build the project. + val buildProject = output.toAbsolutePath.toString + "/" + (resource.contents.head as SPViz).package + ".build" + if (build) { + LOGGER.info("Building the project {}.", buildProject) + #["mvn", "clean", "package"].invoke(new File(buildProject)) + } + // Build the generator. + if (buildGenerator) { + LOGGER.info("Building the project {}.", buildProject) + #["mvn", "clean", "package", "-P", "generator"].invoke(new File(buildProject)) + } + } + LOGGER.info("SPViz project generation finished. The newly generated projects can be found in {}", output.toAbsolutePath().toString()) + + + } catch (Throwable t) { + LOGGER.error("SPViz project generation failed. See trace for details.", t) + } + } + + /** + * Invokes a new process with the given {@code command}. + * @param command The command to invoke, parameters in individual Strings in the list. + * @param directory The root directory to execute the command. + */ + def invoke(List command, File directory) { + LOGGER.info("Invoking command: {}", command.join(" ")) + val pb = new ProcessBuilder(command) + pb.directory(directory) + pb.redirectErrorStream(true) + + try { + val p = pb.start + val pReader = new BufferedReader(new InputStreamReader(p.inputStream)) + var String line = null + while ((line = pReader.readLine()) !== null) { + LOGGER.info(line) + } + + p.waitFor + + LOGGER.info("Exit value: " + p.exitValue) + return p.exitValue + } catch (Exception e) { + LOGGER.error("ERROR: Exception while invoking command", e) + } + } + +} diff --git a/features/de.cau.cs.kieler.spviz.feature/pom.xml b/features/de.cau.cs.kieler.spviz.feature/pom.xml index c5eb135..44a06bd 100644 --- a/features/de.cau.cs.kieler.spviz.feature/pom.xml +++ b/features/de.cau.cs.kieler.spviz.feature/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 - de.cau.cs.kieler.spviz - parent + de.cau.cs.kieler + spviz-parent 0.3.1-SNAPSHOT ../../build/pom.xml diff --git a/features/de.cau.cs.kieler.spviz.ui.feature/pom.xml b/features/de.cau.cs.kieler.spviz.ui.feature/pom.xml index 801bd3b..5161f1d 100644 --- a/features/de.cau.cs.kieler.spviz.ui.feature/pom.xml +++ b/features/de.cau.cs.kieler.spviz.ui.feature/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 - de.cau.cs.kieler.spviz - parent + de.cau.cs.kieler + spviz-parent 0.3.1-SNAPSHOT ../../build/pom.xml diff --git a/plugins/de.cau.cs.kieler.spviz.spviz.ide/.classpath b/plugins/de.cau.cs.kieler.spviz.spviz.ide/.classpath index f5ec80f..f4bbb38 100644 --- a/plugins/de.cau.cs.kieler.spviz.spviz.ide/.classpath +++ b/plugins/de.cau.cs.kieler.spviz.spviz.ide/.classpath @@ -1,9 +1,33 @@ - - - + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/de.cau.cs.kieler.spviz.spviz.ide/.project b/plugins/de.cau.cs.kieler.spviz.spviz.ide/.project index bece512..67d21c1 100644 --- a/plugins/de.cau.cs.kieler.spviz.spviz.ide/.project +++ b/plugins/de.cau.cs.kieler.spviz.spviz.ide/.project @@ -25,8 +25,14 @@ + + org.eclipse.m2e.core.maven2Builder + + + + org.eclipse.m2e.core.maven2Nature org.eclipse.xtext.ui.shared.xtextNature org.eclipse.jdt.core.javanature org.eclipse.pde.PluginNature diff --git a/plugins/de.cau.cs.kieler.spviz.spviz.ide/.settings/org.eclipse.m2e.core.prefs b/plugins/de.cau.cs.kieler.spviz.spviz.ide/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/plugins/de.cau.cs.kieler.spviz.spviz.ide/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/plugins/de.cau.cs.kieler.spviz.spviz.ide/.settings/org.eclipse.xtend.core.Xtend.prefs b/plugins/de.cau.cs.kieler.spviz.spviz.ide/.settings/org.eclipse.xtend.core.Xtend.prefs new file mode 100644 index 0000000..56e3bbe --- /dev/null +++ b/plugins/de.cau.cs.kieler.spviz.spviz.ide/.settings/org.eclipse.xtend.core.Xtend.prefs @@ -0,0 +1,6 @@ +BuilderConfiguration.is_project_specific=true +eclipse.preferences.version=1 +outlet.DEFAULT_OUTPUT.hideLocalSyntheticVariables=true +outlet.DEFAULT_OUTPUT.installDslAsPrimarySource=false +outlet.DEFAULT_OUTPUT.sourceFolder.src.directory=xtend-gen +outlet.DEFAULT_OUTPUT.userOutputPerSourceFolder=true diff --git a/plugins/de.cau.cs.kieler.spviz.spviz.ide/pom.xml b/plugins/de.cau.cs.kieler.spviz.spviz.ide/pom.xml index 56f28d2..c069e26 100644 --- a/plugins/de.cau.cs.kieler.spviz.spviz.ide/pom.xml +++ b/plugins/de.cau.cs.kieler.spviz.spviz.ide/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 - de.cau.cs.kieler.spviz - parent + de.cau.cs.kieler + spviz-parent 0.3.1-SNAPSHOT ../../build/pom.xml diff --git a/plugins/de.cau.cs.kieler.spviz.spviz.tests/pom.xml b/plugins/de.cau.cs.kieler.spviz.spviz.tests/pom.xml index 97cc33c..ad01b24 100644 --- a/plugins/de.cau.cs.kieler.spviz.spviz.tests/pom.xml +++ b/plugins/de.cau.cs.kieler.spviz.spviz.tests/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 - de.cau.cs.kieler.spviz - parent + de.cau.cs.kieler + spviz-parent 0.2.1-SNAPSHOT ../../build/pom.xml diff --git a/plugins/de.cau.cs.kieler.spviz.spviz.ui/pom.xml b/plugins/de.cau.cs.kieler.spviz.spviz.ui/pom.xml index 98ac1be..a0df6c7 100644 --- a/plugins/de.cau.cs.kieler.spviz.spviz.ui/pom.xml +++ b/plugins/de.cau.cs.kieler.spviz.spviz.ui/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 - de.cau.cs.kieler.spviz - parent + de.cau.cs.kieler + spviz-parent 0.3.1-SNAPSHOT ../../build/pom.xml diff --git a/plugins/de.cau.cs.kieler.spviz.spviz/.classpath b/plugins/de.cau.cs.kieler.spviz.spviz/.classpath index b30ae3a..f4bbb38 100644 --- a/plugins/de.cau.cs.kieler.spviz.spviz/.classpath +++ b/plugins/de.cau.cs.kieler.spviz.spviz/.classpath @@ -1,9 +1,33 @@ - - - + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/de.cau.cs.kieler.spviz.spviz/.project b/plugins/de.cau.cs.kieler.spviz.spviz/.project index 7b4c084..5d5d97f 100644 --- a/plugins/de.cau.cs.kieler.spviz.spviz/.project +++ b/plugins/de.cau.cs.kieler.spviz.spviz/.project @@ -25,8 +25,14 @@ + + org.eclipse.m2e.core.maven2Builder + + + + org.eclipse.m2e.core.maven2Nature org.eclipse.xtext.ui.shared.xtextNature org.eclipse.jdt.core.javanature org.eclipse.pde.PluginNature diff --git a/plugins/de.cau.cs.kieler.spviz.spviz/.settings/org.eclipse.m2e.core.prefs b/plugins/de.cau.cs.kieler.spviz.spviz/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/plugins/de.cau.cs.kieler.spviz.spviz/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/plugins/de.cau.cs.kieler.spviz.spviz/.settings/org.eclipse.xtend.core.Xtend.prefs b/plugins/de.cau.cs.kieler.spviz.spviz/.settings/org.eclipse.xtend.core.Xtend.prefs new file mode 100644 index 0000000..56e3bbe --- /dev/null +++ b/plugins/de.cau.cs.kieler.spviz.spviz/.settings/org.eclipse.xtend.core.Xtend.prefs @@ -0,0 +1,6 @@ +BuilderConfiguration.is_project_specific=true +eclipse.preferences.version=1 +outlet.DEFAULT_OUTPUT.hideLocalSyntheticVariables=true +outlet.DEFAULT_OUTPUT.installDslAsPrimarySource=false +outlet.DEFAULT_OUTPUT.sourceFolder.src.directory=xtend-gen +outlet.DEFAULT_OUTPUT.userOutputPerSourceFolder=true diff --git a/plugins/de.cau.cs.kieler.spviz.spviz/META-INF/MANIFEST.MF b/plugins/de.cau.cs.kieler.spviz.spviz/META-INF/MANIFEST.MF index e649ac7..24e8fef 100644 --- a/plugins/de.cau.cs.kieler.spviz.spviz/META-INF/MANIFEST.MF +++ b/plugins/de.cau.cs.kieler.spviz.spviz/META-INF/MANIFEST.MF @@ -17,7 +17,8 @@ Require-Bundle: de.cau.cs.kieler.spviz.spvizmodel, org.eclipse.xtext.util, org.eclipse.xtext.xbase, org.eclipse.xtext.xbase.lib;bundle-version="2.14.0", - org.eclipse.xtend.lib;bundle-version="2.14.0" + org.eclipse.xtend.lib;bundle-version="2.14.0", + slf4j.api Bundle-RequiredExecutionEnvironment: JavaSE-17 Export-Package: de.cau.cs.kieler.spviz.spviz.services, de.cau.cs.kieler.spviz.spviz.parser.antlr, diff --git a/plugins/de.cau.cs.kieler.spviz.spviz/build.properties b/plugins/de.cau.cs.kieler.spviz.spviz/build.properties index 1e6f6b8..626b269 100644 --- a/plugins/de.cau.cs.kieler.spviz.spviz/build.properties +++ b/plugins/de.cau.cs.kieler.spviz.spviz/build.properties @@ -7,12 +7,7 @@ bin.includes = model/generated/,\ plugin.xml,\ icons/ bin.excludes = **/*.mwe2,\ - **/*.xtend,\ - icons/connect.svg,\ - icons/expand.svg,\ - icons/loupe.svg,\ - icons/minimize.svg,\ - icons/restore.svg + **/*.xtend additional.bundles = org.eclipse.xtext.xbase,\ org.eclipse.xtext.common.types,\ org.eclipse.xtext.xtext.generator,\ diff --git a/plugins/de.cau.cs.kieler.spviz.spviz/pom.xml b/plugins/de.cau.cs.kieler.spviz.spviz/pom.xml index 278602f..255b435 100644 --- a/plugins/de.cau.cs.kieler.spviz.spviz/pom.xml +++ b/plugins/de.cau.cs.kieler.spviz.spviz/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 - de.cau.cs.kieler.spviz - parent + de.cau.cs.kieler + spviz-parent 0.3.1-SNAPSHOT ../../build/pom.xml diff --git a/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateActions.xtend b/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateActions.xtend index 0e8fd79..7b55c8e 100644 --- a/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateActions.xtend +++ b/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateActions.xtend @@ -3,7 +3,7 @@ * * http://rtsys.informatik.uni-kiel.de/kieler * - * Copyright 2021-2023 by + * Copyright 2021-2024 by * + Kiel University * + Department of Computer Science * + Real-Time and Embedded Systems Group @@ -15,12 +15,11 @@ package de.cau.cs.kieler.spviz.spviz.generator import de.cau.cs.kieler.spviz.spvizmodel.generator.FileGenerator import de.cau.cs.kieler.spviz.spvizmodel.sPVizModel.Artifact import de.cau.cs.kieler.spviz.spvizmodel.sPVizModel.Connection +import java.io.File import java.util.ArrayList import java.util.HashMap import java.util.List import java.util.Map -import org.eclipse.core.resources.IFolder -import org.eclipse.core.runtime.IProgressMonitor import static extension de.cau.cs.kieler.spviz.spviz.util.SPVizExtension.* import static extension de.cau.cs.kieler.spviz.spvizmodel.util.SPVizModelExtension.* @@ -28,65 +27,61 @@ import static extension de.cau.cs.kieler.spviz.spvizmodel.util.SPVizModelExtensi /** * Generates action classes for the visualization. * - * @author leo, nre + * @author nre, leo */ class GenerateActions { - def static void generate(IFolder sourceFolder, DataAccess data, IProgressMonitor progressMonitor) { + def static void generate(File sourceFolder, DataAccess data) { val String bundleNamePrefix = data.getBundleNamePrefix - val String folder = bundleNamePrefix.replace('.','/') + "/viz/actions/" + val File folder = FileGenerator.createDirectory(sourceFolder, bundleNamePrefix.replace('.','/') + "/viz/actions") var String content = generateAbstractVisualizationContextChangingAction(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "AbstractVisualizationContextChangingAction.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "AbstractVisualizationContextChangingAction.xtend", content) content = generateContextCollapseExpandAction(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "ContextCollapseExpandAction.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "ContextCollapseExpandAction.xtend", content) content = generateOverviewContextCollapseExpandAction(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "OverviewContextCollapseExpandAction.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "OverviewContextCollapseExpandAction.xtend", content) content = generateUndoAction(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "UndoAction.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "UndoAction.xtend", content) content = generateRedoAction(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "RedoAction.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "RedoAction.xtend", content) content = generateResetViewAction(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "ResetViewAction.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "ResetViewAction.xtend", content) content = generateContextExpandAllAction(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "ContextExpandAllAction.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "ContextExpandAllAction.xtend", content) content = generateConnectAllAction(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "ConnectAllAction.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "ConnectAllAction.xtend", content) content = generateFocusAction(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "FocusAction.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "FocusAction.xtend", content) content = generateDefocusAction(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "DefocusAction.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "DefocusAction.xtend", content) content = generateSelectRelatedAction(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "SelectRelatedAction.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "SelectRelatedAction.xtend", content) content = generateShowHideCollapsedAction(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "ShowHideCollapsedAction.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "ShowHideCollapsedAction.xtend", content) content = generateStoreModelAction(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "StoreModelAction.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "StoreModelAction.xtend", content) content = generateRecursiveRevealAction(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "RecursiveRevealAction.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "RecursiveRevealAction.xtend", content) content = generateRevealAction(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "RevealAction.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "RevealAction.xtend", content) for (connection : data.connections) { val actionNameInfix = connection.connecting.name + "Connects" + connection.connected.name + "Named" + connection.name // reveal connected artifacts content = generateRevealAction(data, connection, true) - FileGenerator.generateOrUpdateFile(sourceFolder, - folder + "RevealConnected" + actionNameInfix + "Action.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "RevealConnected" + actionNameInfix + "Action.xtend", content) // remove connected artifacts content = generateRemoveAction(data, connection, true) - FileGenerator.generateOrUpdateFile(sourceFolder, - folder + "RemoveConnected" + actionNameInfix + "Action.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "RemoveConnected" + actionNameInfix + "Action.xtend", content) // reveal connecting artifacts content = generateRevealAction(data, connection, false) - FileGenerator.generateOrUpdateFile(sourceFolder, - folder + "RevealConnecting" + actionNameInfix + "Action.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "RevealConnecting" + actionNameInfix + "Action.xtend", content) // remove connecting artifacts content = generateRemoveAction(data, connection, false) - FileGenerator.generateOrUpdateFile(sourceFolder, - folder + "RemoveConnecting" + actionNameInfix + "Action.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, "RemoveConnecting" + actionNameInfix + "Action.xtend", content) } } diff --git a/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateLanguageServer.xtend b/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateLanguageServer.xtend index 9dc8871..7fa82a4 100644 --- a/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateLanguageServer.xtend +++ b/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateLanguageServer.xtend @@ -3,7 +3,7 @@ * * http://rtsys.informatik.uni-kiel.de/kieler * - * Copyright 2022-2023 by + * Copyright 2022-2024 by * + Kiel University * + Department of Computer Science * + Real-Time and Embedded Systems Group @@ -13,8 +13,7 @@ package de.cau.cs.kieler.spviz.spviz.generator import de.cau.cs.kieler.spviz.spvizmodel.generator.FileGenerator -import org.eclipse.core.resources.IFolder -import org.eclipse.core.runtime.IProgressMonitor +import java.io.File /** * Generates language server classes for the visualization. @@ -23,21 +22,21 @@ import org.eclipse.core.runtime.IProgressMonitor */ class GenerateLanguageServer { - def static void generate(IFolder sourceFolder, IFolder launchFolder, DataAccess data, IProgressMonitor progressMonitor) { + def static void generate(File sourceFolder, File launchFolder, DataAccess data) { val String bundleNamePrefix = data.getBundleNamePrefix - val String folder = bundleNamePrefix.replace('.','/') + "/language/server/" + val File folder = FileGenerator.createDirectory(sourceFolder, bundleNamePrefix.replace('.','/') + "/language/server") var String content = generateLanguageRegistration(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + data.visualizationName + "LanguageRegistration.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, data.visualizationName + "LanguageRegistration.xtend", content) content = generateLanguageServer(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + data.visualizationName + "LanguageServer.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, data.visualizationName + "LanguageServer.xtend", content) content = generateLsCreator(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + data.visualizationName + "LsCreator.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, data.visualizationName + "LsCreator.xtend", content) content = generateRegistrationLsExt(data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + data.visualizationName + "RegistrationLsExt.xtend", content, progressMonitor) + FileGenerator.updateFile(folder, data.visualizationName + "RegistrationLsExt.xtend", content) content = generateLaunchConfig(data) - FileGenerator.generateFile(launchFolder, data.visualizationName + " Launguage Server.launch", content, progressMonitor) + FileGenerator.generateFile(launchFolder, data.visualizationName + " Launguage Server.launch", content) } /** diff --git a/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateMavenBuild.xtend b/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateMavenBuild.xtend index 6401445..6425430 100644 --- a/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateMavenBuild.xtend +++ b/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateMavenBuild.xtend @@ -3,7 +3,7 @@ * * http://rtsys.informatik.uni-kiel.de/kieler * - * Copyright 2022-2023 by + * Copyright 2022-2024 by * + Kiel University * + Department of Computer Science * + Real-Time and Embedded Systems Group @@ -13,9 +13,7 @@ package de.cau.cs.kieler.spviz.spviz.generator import de.cau.cs.kieler.spviz.spvizmodel.generator.FileGenerator -import org.eclipse.core.resources.IProject -import org.eclipse.core.resources.ResourcesPlugin -import org.eclipse.core.runtime.IProgressMonitor +import java.io.File class GenerateMavenBuild { /* @@ -29,90 +27,77 @@ class GenerateMavenBuild { /** * Generates the entire Maven build for this visualization. * - * @param groupId The prefix group ID for this visualization project. - * @param modelId The ID prefix of the model bundle. + * @param rootPath the root path were all generated projects can be found. * @param artifactIdPrefix The individual bundle's prefix artifact ID + * @param vizName The name of the visualization. + * @param modelIdPrefix The ID prefix of the spvizmodel. + * @param version The version the generated project should be generated with. */ - static def generate(String artifactIdPrefix, String vizName, String modelIdPrefix, String version, IProgressMonitor progressMonitor) { + static def generate(String rootPath, String artifactIdPrefix, String vizName, String modelIdPrefix, String version) { + val root = new File (rootPath) // A pom for each sub-module for (bundleSuffix : bundleSuffixes) { - addProjectPom(artifactIdPrefix, bundleSuffix, version, progressMonitor) + addProjectPom(root, artifactIdPrefix, bundleSuffix, version) } // The main build folder with the main pom to build this viz, an Eclipse feature, LS CLI build, and Tycho update site config - addBuildFolder(artifactIdPrefix, vizName, modelIdPrefix, version, progressMonitor) + addBuildFolder(root, artifactIdPrefix, vizName, modelIdPrefix, version) } - private static def addProjectPom(String artifactIdPrefix, String bundleSuffix, String version, IProgressMonitor progressMonitor) { + private static def addProjectPom(File root, String artifactIdPrefix, String bundleSuffix, String version) { val projectId = artifactIdPrefix + "." + bundleSuffix - // Find the project - val workspace = ResourcesPlugin.getWorkspace() - val IProject project = workspace.getRoot().getProject(projectId) - if (!project.exists || !project.open) { - throw new IllegalStateException("The project does either not exist or is not open, but should be: " + projectId) + // Find the folder + val project = new File(root, projectId) + if (!project.exists || !project.isDirectory) { + throw new IllegalStateException("The project does either not exist or is not a directory, but should be: " + projectId) } - val content = pomXmlContent(artifactIdPrefix, bundleSuffix, version) - FileGenerator.generateFile(project, "pom.xml", content, progressMonitor) + val content = pomXmlContent(artifactIdPrefix, bundleSuffix, version, bundleSuffix.equals("model")) + FileGenerator.generateFile(project, "pom.xml", content) } - private static def addBuildFolder(String artifactIdPrefix, String vizName, String modelIdPrefix, String version, IProgressMonitor progressMonitor) { + private static def addBuildFolder(File root, String artifactIdPrefix, String vizName, String modelIdPrefix, String version) { val String modelId = modelIdPrefix + ".model" // The main build folder with an Eclipse feature, LS CLI build, and Tycho update site config // Create a project to hold the build artifacts. val buildProjectName = artifactIdPrefix + ".build" - val workspace = ResourcesPlugin.getWorkspace() - val IProject project = workspace.getRoot().getProject(buildProjectName) - if (!project.exists()) { - val projectDescription = ResourcesPlugin.getWorkspace().newProjectDescription(buildProjectName) - project.create(projectDescription, progressMonitor) - } - project.open(progressMonitor) + val project = FileGenerator.createDirectory(root, buildProjectName) // Put the pom.xml in the project. val content = spvizPomXmlContent(artifactIdPrefix, modelIdPrefix, version) - FileGenerator.generateFile(project, "pom.xml", content, progressMonitor) + FileGenerator.generateFile(project, "pom.xml", content) // Generate the Eclipse feature - addEclipseFeature(project, artifactIdPrefix, modelId, version, progressMonitor) + addEclipseFeature(project, artifactIdPrefix, modelId, version) // Generate the Tycho update site config - addTychoUpdateSiteConfig(project, artifactIdPrefix, modelId, version, progressMonitor) + addTychoUpdateSiteConfig(project, artifactIdPrefix, modelId, version) } - private static def addEclipseFeature(IProject project, String artifactIdPrefix, String modelId, String version, IProgressMonitor progressMonitor) { - val featureFolder = project.getFolder("feature") - if (!featureFolder.exists) { - featureFolder.create(false, true, progressMonitor) - } + private static def addEclipseFeature(File project, String artifactIdPrefix, String modelId, String version) { + val featureFolder = FileGenerator.createDirectory(project, "feature") var String content = featureXmlContent(artifactIdPrefix, modelId, version) - FileGenerator.generateFile(featureFolder, "feature.xml", content, progressMonitor) + FileGenerator.generateFile(featureFolder, "feature.xml", content) content = featurePomXmlContent(artifactIdPrefix, version) - FileGenerator.generateFile(featureFolder, "pom.xml", content, progressMonitor) + FileGenerator.generateFile(featureFolder, "pom.xml", content) content = featureBuildPropertiesContent - FileGenerator.generateFile(featureFolder, "build.properties", content, progressMonitor) + FileGenerator.generateFile(featureFolder, "build.properties", content) } - private static def addTychoUpdateSiteConfig(IProject project, String artifactIdPrefix, String modelId, String version, IProgressMonitor progressMonitor) { - val repositoryFolder = project.getFolder(artifactIdPrefix + ".repository") - if (!repositoryFolder.exists) { - repositoryFolder.create(false, true, progressMonitor) - } + private static def addTychoUpdateSiteConfig(File project, String artifactIdPrefix, String modelId, String version) { + val repositoryFolder = FileGenerator.createDirectory(project, artifactIdPrefix + ".repository") var String content = repositoryCategoryXmlContent(artifactIdPrefix, version) - FileGenerator.generateFile(repositoryFolder, "category.xml", content, progressMonitor) + FileGenerator.generateFile(repositoryFolder, "category.xml", content) content = repositoryPomXmlContent(artifactIdPrefix, version) - FileGenerator.generateFile(repositoryFolder, "pom.xml", content, progressMonitor) + FileGenerator.generateFile(repositoryFolder, "pom.xml", content) - val siteTemplateFolder = project.getFolder(artifactIdPrefix + ".repository/siteTemplate") - if (!siteTemplateFolder.exists) { - siteTemplateFolder.create(false, true, progressMonitor) - } + val siteTemplateFolder = FileGenerator.createDirectory(project, artifactIdPrefix + ".repository/siteTemplate") content = repositoryIndexHtmlContent(artifactIdPrefix) - FileGenerator.generateFile(siteTemplateFolder, "index.html", content, progressMonitor) + FileGenerator.generateFile(siteTemplateFolder, "index.html", content) content = repositoryP2IndexContent() - FileGenerator.generateFile(siteTemplateFolder, "p2.index", content, progressMonitor) + FileGenerator.generateFile(siteTemplateFolder, "p2.index", content) } private static def spvizPomXmlContent(String vizArtifactIdPrefix, String modelIdPrefix, String version) { @@ -168,7 +153,7 @@ class GenerateMavenBuild { ''' } - private static def pomXmlContent(String vizArtifactIdPrefix, String bundleSuffix, String version) { + private static def pomXmlContent(String vizArtifactIdPrefix, String bundleSuffix, String version, boolean modelXcoreBuild) { return ''' src-gen + «IF modelXcoreBuild» + + org.eclipse.xtext + xtext-maven-plugin + ${xtext-version} + + + generate-sources + + generate + + + + + + + org.eclipse.xtext.ecore.EcoreSupport + + + org.eclipse.emf.codegen.ecore.xtext.GenModelSupport + + + org.eclipse.emf.ecore.xcore.XcoreStandaloneSetup + + + ${project.basedir}/src-gen + + + + + + ${basedir}/model + + + + + org.eclipse.platform + org.eclipse.text + 3.14.100 + + + org.eclipse.platform + org.eclipse.core.resources + 3.20.200 + + + org.eclipse.xtext + org.eclipse.xtext.ecore + ${xtext-version} + + + org.eclipse.xtext + org.eclipse.xtext.xtext.generator + ${xtext-version} + + + org.eclipse.xtext + org.eclipse.xtext.builder.standalone + ${xtext-version} + + + org.eclipse.emf + org.eclipse.emf.codegen.ecore.xtext + 1.8.0 + + + org.eclipse.emf + org.eclipse.emf.common + 2.30.0 + + + org.eclipse.emf + org.eclipse.emf.ecore + 2.36.0 + + + org.eclipse.emf + org.eclipse.emf.ecore.xmi + 2.37.0 + + + org.eclipse.emf + org.eclipse.emf.codegen + 2.14.0 + + + org.eclipse.emf + org.eclipse.emf.codegen.ecore + 2.23.0 + + + org.eclipse.emf + org.eclipse.emf.ecore.xcore + 1.29.0 + + + org.eclipse.emf + org.eclipse.emf.ecore.xcore.lib + 1.7.0 + + + + «ENDIF» org.eclipse.xtend diff --git a/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateSubSyntheses.xtend b/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateSubSyntheses.xtend index a5c2cd9..0079b5b 100644 --- a/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateSubSyntheses.xtend +++ b/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateSubSyntheses.xtend @@ -3,7 +3,7 @@ * * http://rtsys.informatik.uni-kiel.de/kieler * - * Copyright 2021-2022 by + * Copyright 2021-2024 by * + Kiel University * + Department of Computer Science * + Real-Time and Embedded Systems Group @@ -16,11 +16,10 @@ import de.cau.cs.kieler.spviz.spviz.sPViz.ShownCategoryConnection import de.cau.cs.kieler.spviz.spviz.sPViz.View import de.cau.cs.kieler.spviz.spvizmodel.generator.FileGenerator import de.cau.cs.kieler.spviz.spvizmodel.sPVizModel.Artifact +import java.io.File import java.util.HashSet import java.util.List import java.util.Set -import org.eclipse.core.resources.IFolder -import org.eclipse.core.runtime.IProgressMonitor import static extension de.cau.cs.kieler.spviz.spviz.util.SPVizExtension.* import static extension de.cau.cs.kieler.spviz.spvizmodel.util.SPVizModelExtension.* @@ -28,26 +27,23 @@ import static extension de.cau.cs.kieler.spviz.spvizmodel.util.SPVizModelExtensi /** * Generates sub syntheses classes for overviews and their contained artifacts. * - * @author leo, nre + * @author nre, leo */ class GenerateSubSyntheses { - def static void generate(IFolder sourceFolder, DataAccess data, IProgressMonitor progressMonitor) { + def static void generate(File sourceFolder, DataAccess data) { val bundleNamePrefix = data.getBundleNamePrefix - val folder = bundleNamePrefix.replace('.', '/') + "/viz/subsyntheses/" + val folder = FileGenerator.createDirectory(sourceFolder, bundleNamePrefix.replace('.', '/') + "/viz/subsyntheses") for (artifact : data.artifacts) { var content = generateSimpleSynthesis(bundleNamePrefix, artifact.name) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "Simple" + artifact.name + "Synthesis.xtend", content, - progressMonitor) + FileGenerator.updateFile(folder, "Simple" + artifact.name + "Synthesis.xtend", content) content = generateSynthesis(artifact, data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + artifact.name + "Synthesis.xtend", content, - progressMonitor) + FileGenerator.updateFile(folder, artifact.name + "Synthesis.xtend", content) } for (view : data.views) { val content = generateOverviewSythesis(view, data) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + view.name + "OverviewSynthesis.xtend", content, - progressMonitor) + FileGenerator.updateFile(folder, view.name + "OverviewSynthesis.xtend", content) } } diff --git a/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateSyntheses.xtend b/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateSyntheses.xtend index 54a96a2..adf4b98 100644 --- a/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateSyntheses.xtend +++ b/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateSyntheses.xtend @@ -3,7 +3,7 @@ * * http://rtsys.informatik.uni-kiel.de/kieler * - * Copyright 2021-2023 by + * Copyright 2021-2024 by * + Kiel University * + Department of Computer Science * + Real-Time and Embedded Systems Group @@ -16,12 +16,11 @@ import de.cau.cs.kieler.spviz.spviz.sPViz.View import de.cau.cs.kieler.spviz.spvizmodel.generator.FileGenerator import de.cau.cs.kieler.spviz.spvizmodel.sPVizModel.Artifact import java.awt.Color +import java.io.File import java.util.HashMap import java.util.Locale import java.util.Map import java.util.Set -import org.eclipse.core.resources.IFolder -import org.eclipse.core.runtime.IProgressMonitor import static extension de.cau.cs.kieler.spviz.spviz.util.SPVizExtension.* import static extension de.cau.cs.kieler.spviz.spvizmodel.util.SPVizModelExtension.* @@ -29,28 +28,23 @@ import static extension de.cau.cs.kieler.spviz.spvizmodel.util.SPVizModelExtensi /** * Generates classes for the syntheses of the visualization. * - * @author leo, nre + * @author nre, leo */ class GenerateSyntheses { - def static void generate(IFolder sourceFolder, DataAccess data, IProgressMonitor progressMonitor) { - val folder = data.getBundleNamePrefix.replace('.','/') + "/viz/" + def static void generate(File sourceFolder, DataAccess data) { + val File folder = FileGenerator.createDirectory(sourceFolder, data.getBundleNamePrefix.replace('.','/') + "/viz") - FileGenerator.generateOrUpdateFile(sourceFolder, folder + data.projectName.toFirstUpper + "DiagramSynthesis.xtend", - generateDiagramSynthesis(data), progressMonitor) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + data.visualizationName.toFirstUpper + "DiagramSynthesis.xtend", - generateVizDiagramSynthesis(data), progressMonitor) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "KlighdSetup.xtend", generateKlighdSetup(data), - progressMonitor) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "Styles.xtend", generateStyles(data), - progressMonitor) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "SynthesisUtils.xtend", generateSynthesisUtils(data), - progressMonitor) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "SynthesisProperties.xtend", - generateSynthesisProperties(data), progressMonitor) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "Options.xtend", generateOptions(data), progressMonitor) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "FileHandler.xtend", generateFileHandler(data), progressMonitor) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "VisualizationReInitializer.xtend", - generateVisualizationReInitializer(data), progressMonitor) + FileGenerator.updateFile(folder, data.projectName.toFirstUpper + "DiagramSynthesis.xtend", + generateDiagramSynthesis(data)) + FileGenerator.updateFile(folder, data.visualizationName.toFirstUpper + "DiagramSynthesis.xtend", + generateVizDiagramSynthesis(data)) + FileGenerator.updateFile(folder, "KlighdSetup.xtend", generateKlighdSetup(data)) + FileGenerator.updateFile(folder, "Styles.xtend", generateStyles(data)) + FileGenerator.updateFile(folder, "SynthesisUtils.xtend", generateSynthesisUtils(data)) + FileGenerator.updateFile(folder, "SynthesisProperties.xtend", generateSynthesisProperties(data)) + FileGenerator.updateFile(folder, "Options.xtend", generateOptions(data)) + FileGenerator.updateFile(folder, "FileHandler.xtend", generateFileHandler(data)) + FileGenerator.updateFile(folder, "VisualizationReInitializer.xtend", generateVisualizationReInitializer(data)) } /** diff --git a/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateVizModelUtils.xtend b/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateVizModelUtils.xtend index fd95b28..0a12aaa 100644 --- a/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateVizModelUtils.xtend +++ b/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/GenerateVizModelUtils.xtend @@ -3,7 +3,7 @@ * * http://rtsys.informatik.uni-kiel.de/kieler * - * Copyright 2021-2023 by + * Copyright 2021-2024 by * + Kiel University * + Department of Computer Science * + Real-Time and Embedded Systems Group @@ -14,9 +14,8 @@ package de.cau.cs.kieler.spviz.spviz.generator import de.cau.cs.kieler.spviz.spviz.sPViz.ArtifactChain import de.cau.cs.kieler.spviz.spvizmodel.generator.FileGenerator +import java.io.File import java.util.List -import org.eclipse.core.resources.IFolder -import org.eclipse.core.runtime.IProgressMonitor import static extension de.cau.cs.kieler.spviz.spviz.util.SPVizExtension.* import static extension de.cau.cs.kieler.spviz.spvizmodel.util.SPVizModelExtension.* @@ -24,16 +23,14 @@ import static extension de.cau.cs.kieler.spviz.spvizmodel.util.SPVizModelExtensi /** * Generates utility classes for the visualization model. * - * @author leo, nre + * @author nre, leo */ class GenerateVizModelUtils { - def static void generate(IFolder sourceFolder, DataAccess spviz, IProgressMonitor progressMonitor) { - val folder = spviz.getBundleNamePrefix.replace('.', '/') + "/model/util/" - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "VizModelUtil.xtend", generateVizModelUtil(spviz), - progressMonitor) - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "ContextExtensions.xtend", - generateContextExtensions(spviz), progressMonitor) + def static void generate(File sourceFolder, DataAccess spviz) { + val utilFolder = FileGenerator.createDirectory(sourceFolder, spviz.getBundleNamePrefix.replace('.', '/') + "/model/util/") + FileGenerator.updateFile(new File(utilFolder, "VizModelUtil.xtend"), generateVizModelUtil(spviz)) + FileGenerator.updateFile(new File(utilFolder, "ContextExtensions.xtend"),generateContextExtensions(spviz)) } /** @@ -778,7 +775,7 @@ class GenerateVizModelUtils { } } - + /** * Removes a connected container edge in the parent overview context of the two given contexts. * @@ -810,7 +807,7 @@ class GenerateVizModelUtils { // connectingContext.allConnectedBundleConnectsBundleNamedDependencyShown = false // connectedContext.allConnectingBundleConnectsBundleNamedDependencyShown = false } - + «ENDFOR» // Method to let Xtend create the needed generic super type. diff --git a/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/SPVizGenerator.xtend b/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/SPVizGenerator.xtend index 36f8756..ff99e5a 100644 --- a/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/SPVizGenerator.xtend +++ b/plugins/de.cau.cs.kieler.spviz.spviz/src/de/cau/cs/kieler/spviz/spviz/generator/SPVizGenerator.xtend @@ -14,38 +14,42 @@ package de.cau.cs.kieler.spviz.spviz.generator import de.cau.cs.kieler.spviz.spvizmodel.generator.FileGenerator import de.cau.cs.kieler.spviz.spvizmodel.generator.JavaMavenProjectGenerator -import de.cau.cs.kieler.spviz.spvizmodel.generator.XCoreProjectGenerator +import de.cau.cs.kieler.spviz.spvizmodel.generator.ProjectGenerator import de.cau.cs.kieler.spviz.spvizmodel.generator.maven.Dependency -import java.util.Arrays -import java.util.Collections +import java.io.File +import java.nio.file.Path +import java.nio.file.Paths import java.util.List -import org.eclipse.core.resources.IProject -import org.eclipse.core.resources.IProjectDescription -import org.eclipse.core.runtime.IPath -import org.eclipse.core.runtime.NullProgressMonitor -import org.eclipse.core.runtime.Path -import org.eclipse.emf.codegen.ecore.Generator +import org.eclipse.core.resources.ResourcesPlugin import org.eclipse.emf.ecore.resource.Resource -import org.eclipse.jdt.core.JavaCore import org.eclipse.xtext.generator.AbstractGenerator import org.eclipse.xtext.generator.IFileSystemAccess2 import org.eclipse.xtext.generator.IGeneratorContext +import org.slf4j.Logger +import org.slf4j.LoggerFactory -import static extension de.cau.cs.kieler.spviz.spvizmodel.util.SPVizModelExtension.* import static extension de.cau.cs.kieler.spviz.spviz.util.SPVizExtension.* +import static extension de.cau.cs.kieler.spviz.spvizmodel.util.SPVizModelExtension.* /** * Generates code from your model files on save. * - * @author leo, nre + * @author nre, leo * @see https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation */ class SPVizGenerator extends AbstractGenerator { + static final Logger LOGGER = LoggerFactory.getLogger(SPVizGenerator) + + override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) { + val workspace = ResourcesPlugin.workspace + val output = Paths.get(workspace.root.location.toString) + SPVizGenerator.generate(resource, output) + } // TODO: add flags and a class for each 'via' connection (look at 'UsedPackagesOfBundleEdgeConnection' for reference) - val String[] CLASHING_NAMES = #[ + static val String[] CLASHING_NAMES = #[ "Appendable", "AutoCloseable", "CharSequence", "Cloneable", "Comparable", "Iterable", "ProcessHandle", "ProcessHandle.Info", "Readable", "Runnable", "StackWalker.StackFrame", "System.Logger", "Thread.UncaughtExceptionHandler", "Boolean", "Byte", "Character", "Character.Subset", "Character.UnicodeBlock", "Class", "ClassLoader", "ClassValue", "Compiler", "Double", "Enum", "Float", "InheritableThreadLocal", "Integer", "Long", "Math", "Module", "ModuleLayer", "ModuleLayer.Controller", "Number", "Object", "Package", "Process", "ProcessBuilder", "ProcessBuilder.Redirect", "Runtime", "Runtime.Version", "RuntimePermission", "SecurityManager", "Short", "StackTraceElement", "StrictMath", "String", "StringBuffer", "StringBuilder", "System", "System.LoggerFinder", "Thread", "ThreadGroup", "ThreadLocal", "Throwable", "Void", "Character.UnicodeScript", "ProcessBuilder.Redirect.Type", "StackWalker.Option", "System.Logger.Level", "Thread.State", @@ -53,126 +57,92 @@ class SPVizGenerator extends AbstractGenerator { "AbstractMethodError", "AssertionError", "BootstrapMethodError", "ClassCircularityError", "ClassFormatError", "Error", "ExceptionInInitializerError", "IllegalAccessError", "IncompatibleClassChangeError", "InstantiationError", "InternalError", "LinkageError", "NoClassDefFoundError", "NoSuchFieldError", "NoSuchMethodError", "OutOfMemoryError", "StackOverflowError", "ThreadDeath", "UnknownError", "UnsatisfiedLinkError", "UnsupportedClassVersionError", "VerifyError", "VirtualMachineError" ] - override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) { - println("Generate visualization for " + resource.contents.head?.class) + static def void generate(Resource resource, Path rootPath) { val DataAccess data = new DataAccess(resource) + val root = rootPath.toAbsolutePath.toString + "/" // Generate the -viz.model XCore project val String xcoreContent = xcoreContent(data) - val progressMonitor = new NullProgressMonitor - val project = new XCoreProjectGenerator(data.getBundleNamePrefix + ".model") - .configureXCoreFile(data.visualizationName + 'Model.xcore', xcoreContent) + val vizModelProjectName = data.getBundleNamePrefix + ".model" + val vizModelProjectPath = root + vizModelProjectName + if (new File(vizModelProjectPath).isDirectory) { + LOGGER.info("Updating sources of project {}", vizModelProjectPath) + } else { + LOGGER.info("Generating project {}", vizModelProjectPath) + } + val vizModelProjectDirectory = FileGenerator.createDirectory(vizModelProjectPath) + new ProjectGenerator(vizModelProjectName, vizModelProjectPath) + .configureXCoreFile(data.visualizationName, xcoreContent) .configureRequiredBundles(#[data.modelBundleNamePrefix + ".model"]) .configureExportedPackages(exportedVizModelPackages(data)) .configureMaven(true) - .generate(progressMonitor) + .additionalSourceFolder("xtend-gen") + .generate() - // Add the xtend-gen folder to the classpath - val xtendGenFolder = project.getFolder("xtend-gen") - if (!xtendGenFolder.exists()) { - xtendGenFolder.create(false, true, progressMonitor) - } - val javaProject = JavaCore.create(project); - val oldClasspathEntries = javaProject.getRawClasspath - if (!oldClasspathEntries.contains(JavaCore.newSourceEntry(xtendGenFolder.getFullPath()))) { - val classpathEntries = Arrays.copyOf(oldClasspathEntries, oldClasspathEntries.size + 1) - classpathEntries.set(oldClasspathEntries.size, JavaCore.newSourceEntry(xtendGenFolder.getFullPath())) - javaProject.setRawClasspath(classpathEntries, progressMonitor) - } - val sourceFolder = project.getFolder("src-gen") + val sourceVizModelFolder = FileGenerator.createDirectory(vizModelProjectDirectory, "src-gen") // Generate further source files for the project - GenerateVizModelUtils.generate(sourceFolder, data, progressMonitor) - - // Generate the build.properties file - FileGenerator.generateFile(project, "/build.properties", - FileGenerator.modelBuildPropertiesContent(), progressMonitor) + GenerateVizModelUtils.generate(sourceVizModelFolder, data) // Generate the -viz.viz model Plug-In Java project - val projectPath = new Path("/" + data.getBundleNamePrefix + ".viz/src-gen") - val vizProject = Generator.createEMFProject(projectPath, null as IPath, - Collections.emptyList(), progressMonitor, - Generator.EMF_MODEL_PROJECT_STYLE.bitwiseOr(Generator.EMF_PLUGIN_PROJECT_STYLE)) - XCoreProjectGenerator.addNatures(vizProject, true, progressMonitor) - + val vizProjectName = data.getBundleNamePrefix + ".viz" + val vizProjectPath = root + vizProjectName + if (new File(vizProjectPath).isDirectory) { + LOGGER.info("Updating sources of project {}", vizProjectPath) + } else { + LOGGER.info("Generating project {}", vizProjectPath) + } + val vizProjectDirectory = FileGenerator.createDirectory(vizProjectPath) + new ProjectGenerator(vizProjectName, vizProjectPath) + .configureMaven(true) + .configureKlighd(true) + .configureIcons(true) + .additionalSourceFolder("xtend-gen") + .configureRequiredBundles(requiredVizBundles(data)) + .configureExportedPackages(exportedVizPackages(data)) + .generate() - val sourceVizFolder = vizProject.getFolder("src-gen") - - // Generate the manifest - FileGenerator.generateFile(vizProject, "/META-INF/MANIFEST.MF", - FileGenerator.manifestContent(data.getBundleNamePrefix + '.viz', requiredVizBundles(data), exportedVizPackages(data)), progressMonitor) - - // Generate the services file - FileGenerator.generateFile(vizProject, - "/META-INF/services/de.cau.cs.kieler.klighd.IKlighdStartupHook", serviceFileContent(data), progressMonitor) - - // Generate the plugin.xml file - FileGenerator.generateFile(vizProject, "/plugin.xml", pluginXmlContent(data), progressMonitor) - - // Generate the build.properties file - FileGenerator.generateFile(vizProject, "/build.properties", - FileGenerator.buildPropertiesContent(true), progressMonitor - ) + val sourceVizFolder = new File(vizProjectPath, "src-gen") // Generate further source files for the project - GenerateSyntheses.generate(sourceVizFolder, data, progressMonitor) - GenerateSubSyntheses.generate(sourceVizFolder, data, progressMonitor) - GenerateActions.generate(sourceVizFolder, data, progressMonitor) + GenerateSyntheses.generate(sourceVizFolder, data) + GenerateSubSyntheses.generate(sourceVizFolder, data) + GenerateActions.generate(sourceVizFolder, data) // Copy icons over into the project - FileGenerator.copyFiles("de.cau.cs.kieler.spviz.spviz", - "/icons/", - vizProject.getFolder("icons"), - progressMonitor - ) - - // Add the Xtext and Plugin natures to the project - val IProjectDescription projectDescription = vizProject.getDescription(); - var String[] natureIds = projectDescription.getNatureIds() - if (natureIds === null) { - natureIds = #[ "org.eclipse.xtext.ui.shared.xtextNature", "org.eclipse.pde.PluginNature" ] - } else { - if (!project.hasNature("org.eclipse.xtext.ui.shared.xtextNature")) { - val oldNatureIds = natureIds - natureIds = newArrayOfSize(oldNatureIds.length + 1) - System.arraycopy(oldNatureIds, 0, natureIds, 0, oldNatureIds.length) - natureIds.set(oldNatureIds.length, "org.eclipse.xtext.ui.shared.xtextNature") - } - if (!project.hasNature("org.eclipse.pde.PluginNature")) { - val oldNatureIds = natureIds - natureIds = newArrayOfSize(oldNatureIds.length + 1 ) - System.arraycopy(oldNatureIds, 0, natureIds, 0, oldNatureIds.length) - natureIds.set(oldNatureIds.length, "org.eclipse.pde.PluginNature") - } - } - projectDescription.setNatureIds(natureIds); - vizProject.setDescription(projectDescription, progressMonitor); + FileGenerator.copyIcons(FileGenerator.createDirectory(vizProjectDirectory, "icons")) // Generate the .language.server Maven project - val lsProject = new JavaMavenProjectGenerator(data.getBundleNamePrefix, data.getBundleNamePrefix + ".language.server") + val lsProjectName = data.bundleNamePrefix + ".language.server" + val lsProjectPath = root + lsProjectName + if (new File(lsProjectPath).isDirectory) { + LOGGER.info("Updating sources of project {}", lsProjectPath) + } else { + LOGGER.info("Generating project {}", lsProjectPath) + } + val lsProjectDirectory = FileGenerator.createDirectory(lsProjectPath) + new JavaMavenProjectGenerator(data.bundleNamePrefix, lsProjectName, lsProjectPath) .configureDependencies(requiredLSDependencies(data)) .configureDependencyManagement(lsDependencyManagement) .configureXtendSources(true) .configureSourceFolderName("src-gen") .configureGenerateShadedJar(true) .configureMainClass(data.visualizationName + "LanguageServer") - .generate(progressMonitor) + .generate() // Generate further source files for the java project - val launchFolder = lsProject.getFolder("launch") - if (!launchFolder.exists) { - launchFolder.create(false, true, progressMonitor) - } - GenerateLanguageServer.generate(lsProject.getFolder("src-gen"), launchFolder, data, progressMonitor) + val launchFolder = FileGenerator.createDirectory(lsProjectDirectory, "launch") + val lsSourceFolder = FileGenerator.createDirectory(lsProjectDirectory, "src-gen") + GenerateLanguageServer.generate(lsSourceFolder, launchFolder, data) // Generate the Maven build framework for this visualization. - GenerateMavenBuild.generate(data.bundleNamePrefix, data.visualizationName.toFirstUpper, data.modelBundleNamePrefix, "0.1.0", progressMonitor) + GenerateMavenBuild.generate(root, data.bundleNamePrefix, data.visualizationName.toFirstUpper, data.modelBundleNamePrefix, "0.1.0") } - def lsDependencyManagement() { + static def lsDependencyManagement() { return ''' @@ -233,7 +203,7 @@ class SPVizGenerator extends AbstractGenerator { ''' } - protected def List exportedVizModelPackages(DataAccess data) { + protected static def List exportedVizModelPackages(DataAccess data) { return #[ data.bundleNamePrefix + ".model", data.bundleNamePrefix + ".model.impl", @@ -241,7 +211,7 @@ class SPVizGenerator extends AbstractGenerator { ] } - protected def List requiredLSDependencies(DataAccess data) { + protected static def List requiredLSDependencies(DataAccess data) { return #[ new Dependency("com.google.code.gson", "gson", "${gson-version}"), new Dependency("com.google.inject", "guice", "${guice-version}"), @@ -269,7 +239,7 @@ class SPVizGenerator extends AbstractGenerator { ] } - protected def List requiredVizBundles(DataAccess data) { + protected static def List requiredVizBundles(DataAccess data) { return #[ "de.cau.cs.kieler.klighd", "de.cau.cs.kieler.klighd.krendering.extensions", @@ -285,49 +255,12 @@ class SPVizGenerator extends AbstractGenerator { ] } - protected def List exportedVizPackages(DataAccess data) { + protected static def List exportedVizPackages(DataAccess data) { return #[ data.bundleNamePrefix + ".viz" ] } - /** - * Generates the content for the plugin.xml file - * - * @param data - * a DataAccess instance for the Spviz data - * @return - * the generated content for the plugin configuration as a String. - */ - private def String pluginXmlContent(DataAccess data) { - return ''' - - - - - - - - - ''' - } - - /** - * Generates the content for the IKLighdStartupHook service file - * - * @param data - * a DataAccess instance for the Spviz data - * @return - * the generated content for the service configuration as a String. - */ - private def String serviceFileContent(DataAccess data) { - return ''' - «data.getBundleNamePrefix».viz.KlighdSetup - ''' - } - /** * Generates the content for the Model.xcore file * @@ -336,7 +269,7 @@ class SPVizGenerator extends AbstractGenerator { * @return * the generated content for the visualization model XCore file as a String */ - private def String xcoreContent(DataAccess data) { + private static def String xcoreContent(DataAccess data) { return ''' @GenModel( fileExtensions="«data.visualizationName.toLowerCase»", @@ -522,7 +455,7 @@ class SPVizGenerator extends AbstractGenerator { /** * Corrects the artifact name if it clashes with the auto-imported public java.lang classes. */ - def correctArtifactName(String string, DataAccess data) { + static def correctArtifactName(String string, DataAccess data) { if (!CLASHING_NAMES.contains(string)) { return string } diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel.ide/.classpath b/plugins/de.cau.cs.kieler.spviz.spvizmodel.ide/.classpath index f5ec80f..f4bbb38 100644 --- a/plugins/de.cau.cs.kieler.spviz.spvizmodel.ide/.classpath +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel.ide/.classpath @@ -1,9 +1,33 @@ - - - + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel.ide/.project b/plugins/de.cau.cs.kieler.spviz.spvizmodel.ide/.project index 0a72c01..6772c65 100644 --- a/plugins/de.cau.cs.kieler.spviz.spvizmodel.ide/.project +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel.ide/.project @@ -25,8 +25,14 @@ + + org.eclipse.m2e.core.maven2Builder + + + + org.eclipse.m2e.core.maven2Nature org.eclipse.xtext.ui.shared.xtextNature org.eclipse.jdt.core.javanature org.eclipse.pde.PluginNature diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel.ide/.settings/org.eclipse.m2e.core.prefs b/plugins/de.cau.cs.kieler.spviz.spvizmodel.ide/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel.ide/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel.ide/.settings/org.eclipse.xtend.core.Xtend.prefs b/plugins/de.cau.cs.kieler.spviz.spvizmodel.ide/.settings/org.eclipse.xtend.core.Xtend.prefs new file mode 100644 index 0000000..56e3bbe --- /dev/null +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel.ide/.settings/org.eclipse.xtend.core.Xtend.prefs @@ -0,0 +1,6 @@ +BuilderConfiguration.is_project_specific=true +eclipse.preferences.version=1 +outlet.DEFAULT_OUTPUT.hideLocalSyntheticVariables=true +outlet.DEFAULT_OUTPUT.installDslAsPrimarySource=false +outlet.DEFAULT_OUTPUT.sourceFolder.src.directory=xtend-gen +outlet.DEFAULT_OUTPUT.userOutputPerSourceFolder=true diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel.ide/pom.xml b/plugins/de.cau.cs.kieler.spviz.spvizmodel.ide/pom.xml index 0e7e2af..a871f4a 100644 --- a/plugins/de.cau.cs.kieler.spviz.spvizmodel.ide/pom.xml +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel.ide/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 - de.cau.cs.kieler.spviz - parent + de.cau.cs.kieler + spviz-parent 0.3.1-SNAPSHOT ../../build/pom.xml diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel.tests/pom.xml b/plugins/de.cau.cs.kieler.spviz.spvizmodel.tests/pom.xml index 20476ea..59172bd 100644 --- a/plugins/de.cau.cs.kieler.spviz.spvizmodel.tests/pom.xml +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel.tests/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 - de.cau.cs.kieler.spviz - parent + de.cau.cs.kieler + spviz-parent 0.2.1-SNAPSHOT ../../build/pom.xml diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel.ui/pom.xml b/plugins/de.cau.cs.kieler.spviz.spvizmodel.ui/pom.xml index fdd12bb..1fe9657 100644 --- a/plugins/de.cau.cs.kieler.spviz.spvizmodel.ui/pom.xml +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel.ui/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 - de.cau.cs.kieler.spviz - parent + de.cau.cs.kieler + spviz-parent 0.3.1-SNAPSHOT ../../build/pom.xml diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel/.classpath b/plugins/de.cau.cs.kieler.spviz.spvizmodel/.classpath index f5ec80f..f4bbb38 100644 --- a/plugins/de.cau.cs.kieler.spviz.spvizmodel/.classpath +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel/.classpath @@ -1,9 +1,33 @@ - - - + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel/.project b/plugins/de.cau.cs.kieler.spviz.spvizmodel/.project index a426478..392155d 100644 --- a/plugins/de.cau.cs.kieler.spviz.spvizmodel/.project +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel/.project @@ -25,8 +25,14 @@ + + org.eclipse.m2e.core.maven2Builder + + + + org.eclipse.m2e.core.maven2Nature org.eclipse.xtext.ui.shared.xtextNature org.eclipse.jdt.core.javanature org.eclipse.pde.PluginNature diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel/.settings/org.eclipse.m2e.core.prefs b/plugins/de.cau.cs.kieler.spviz.spvizmodel/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel/.settings/org.eclipse.xtend.core.Xtend.prefs b/plugins/de.cau.cs.kieler.spviz.spvizmodel/.settings/org.eclipse.xtend.core.Xtend.prefs new file mode 100644 index 0000000..56e3bbe --- /dev/null +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel/.settings/org.eclipse.xtend.core.Xtend.prefs @@ -0,0 +1,6 @@ +BuilderConfiguration.is_project_specific=true +eclipse.preferences.version=1 +outlet.DEFAULT_OUTPUT.hideLocalSyntheticVariables=true +outlet.DEFAULT_OUTPUT.installDslAsPrimarySource=false +outlet.DEFAULT_OUTPUT.sourceFolder.src.directory=xtend-gen +outlet.DEFAULT_OUTPUT.userOutputPerSourceFolder=true diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel/META-INF/MANIFEST.MF b/plugins/de.cau.cs.kieler.spviz.spvizmodel/META-INF/MANIFEST.MF index 65af1ad..3229e1a 100644 --- a/plugins/de.cau.cs.kieler.spviz.spvizmodel/META-INF/MANIFEST.MF +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel/META-INF/MANIFEST.MF @@ -20,7 +20,8 @@ Require-Bundle: org.antlr.runtime;bundle-version="[3.2.0,3.2.1)", org.eclipse.xtext.util, org.eclipse.xtext.xbase, org.eclipse.xtext.xbase.lib;bundle-version="2.14.0", - org.eclipse.xtend.lib;bundle-version="2.14.0" + org.eclipse.xtend.lib;bundle-version="2.14.0", + slf4j.api Bundle-RequiredExecutionEnvironment: JavaSE-17 Export-Package: de.cau.cs.kieler.spviz.spvizmodel, de.cau.cs.kieler.spviz.spvizmodel.generator, diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel/pom.xml b/plugins/de.cau.cs.kieler.spviz.spvizmodel/pom.xml index b6c5880..46facaf 100644 --- a/plugins/de.cau.cs.kieler.spviz.spvizmodel/pom.xml +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 - de.cau.cs.kieler.spviz - parent + de.cau.cs.kieler + spviz-parent 0.3.1-SNAPSHOT ../../build/pom.xml diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/FileGenerator.xtend b/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/FileGenerator.xtend index a0ea0a9..41a78be 100644 --- a/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/FileGenerator.xtend +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/FileGenerator.xtend @@ -3,7 +3,7 @@ * * http://rtsys.informatik.uni-kiel.de/kieler * - * Copyright 2021-2022 by + * Copyright 2021-2024 by * + Kiel University * + Department of Computer Science * + Real-Time and Embedded Systems Group @@ -12,18 +12,10 @@ */ package de.cau.cs.kieler.spviz.spvizmodel.generator -import java.io.ByteArrayInputStream import java.io.File import java.io.InputStream import java.nio.file.Files -import org.eclipse.core.resources.IFile -import org.eclipse.core.resources.IFolder -import org.eclipse.core.resources.IProject -import org.eclipse.core.resources.IResource -import org.eclipse.core.runtime.FileLocator -import org.eclipse.core.runtime.IProgressMonitor -import org.eclipse.core.runtime.Platform -import org.eclipse.emf.codegen.util.CodeGenUtil +import java.nio.file.Paths /** * Utility for generating files in Eclipse projects. @@ -33,198 +25,122 @@ import org.eclipse.emf.codegen.util.CodeGenUtil class FileGenerator { /** - * Generates or updates the file with the given content. + * Updates the file with the given content. Generates it first if it does not exist yet. * - * @param sourceFolder The Java source folder where all sources need to be placed. - * @param filePath The relative file path to the file that should be generated or updated. - * @param fileContent The new file content. + * @param base The directory to write to. + * @param fileName the name of the file. + * @param fileContent The content to write to the file. */ - def static void generateOrUpdateFile(IFolder sourceFolder, String filePath, String fileContent, - IProgressMonitor progressMonitor) { - val file = sourceFolder.getFile(filePath); - generateOrUpdateFile(file, fileContent, progressMonitor, true) + def static void updateFile(File base, String fileName, String fileContent) { + generateOrUpdateFile(base, fileName, fileContent, true) } /** - * Generates the file with the given content, if it does not already exist. + * Updates the file with the given content. Generates it first if it does not exist yet. * - * @param sourceFolder The Java source folder where all sources need to be placed. - * @param filePath The relative file path to the file that should be generated. - * @param fileContent The file content. + * @param file The file to write to. + * @param fileContent The content to write to the file. */ - def static void generateFile(IFolder sourceProject, String filePath, String fileContent, - IProgressMonitor progressMonitor) { - val file = sourceProject.getFile(filePath); - generateOrUpdateFile(file, fileContent, progressMonitor, false) + def static void updateFile(File file, String fileContent) { + generateOrUpdateFile(file, fileContent, true) } /** - * Generates or updates the file with the given content. + * Generates the file with the given content. Does not update the file if it already exists. * - * @param sourceProject The project where the file needs to be placed. - * @param filePath The relative file path to the file that should be generated or updated. - * @param fileContent The new file content. + * @param base The directory to write to. + * @param fileName the name of the file. + * @param fileContent The content to write to the file. */ - def static void generateOrUpdateFile(IProject sourceProject, String filePath, String fileContent, - IProgressMonitor progressMonitor) { - val file = sourceProject.getFile(filePath); - generateOrUpdateFile(file, fileContent, progressMonitor, true) + def static void generateFile(File base, String fileName, String fileContent) { + generateOrUpdateFile(base, fileName, fileContent, false) } /** - * Generates the file with the given content, if it does not already exist. + * Generates the file with the given content. Does not update the file if it already exists. * - * @param sourceProject The project where the file needs to be placed. - * @param filePath The relative file path to the file that should be generated. - * @param fileContent The file content. + * @param file The file to write to. + * @param fileContent The content to write to the file. */ - def static void generateFile(IProject sourceProject, String filePath, String fileContent, - IProgressMonitor progressMonitor) { - val file = sourceProject.getFile(filePath); - generateOrUpdateFile(file, fileContent, progressMonitor, false) + def static void generateFile(File file, String fileContent) { + generateOrUpdateFile(file, fileContent, false) } - def private static void generateOrUpdateFile(IFile file, String fileContent, - IProgressMonitor progressMonitor, boolean overwriteExisting) { - val inputStream = new ByteArrayInputStream(fileContent.bytes) - if (!file.exists) { - create(file, progressMonitor) - } else if (!overwriteExisting) { - // If the file exists already and we should not overwrite it, don't do so. - return - } - file.setContents(inputStream, IResource.NONE, progressMonitor) + /** + * Generates or updates the file with the given content. + * + * @param base The directory to write to. + * @param fileName the name of the file. + * @param fileContent The content to write to the file. + * @param force If existing content should be overwritten. + */ + def static void generateOrUpdateFile(File base, String fileName, String fileContent, boolean force) { + generateOrUpdateFile(new File(base, fileName), fileContent, force) } /** - * Copies the files at the source location to the target folder. + * Generates or updates the file with the given content. * - * @param sourceBundle The bundle containing the folder to copy the files from. - * @param sourceFolder The sub-folder ini the bundle to copy from. - * @param targetFolder The folder to copy the files to. + * @param file The file to write to. + * @param fileContent The content to write to the file. + * @param force If existing content should be overwritten. */ - def static void copyFiles(String sourceBundle, String sourceFolder, IFolder targetFolder, - IProgressMonitor progressMonitor) { - if (!targetFolder.exists) { - targetFolder.create(progressMonitor) + def static void generateOrUpdateFile(File file, String fileContent, boolean force) { + // Only overwrite the file if `force` is true. + if (file.exists && !force) { + return } - if (Platform.isRunning()) { - // If the platform is running, the folder can be found in the bundle under the resource path. - val url = Platform.getBundle(sourceBundle) - ?.getEntry(sourceFolder) - val folder = new File(FileLocator.toFileURL(url).toURI.path) - for (file : folder.listFiles) { - val fileName = file.name - val newFile = new File(targetFolder.rawLocation.toString + "/" + fileName) - if (!newFile.exists) { - Files.copy(file.toPath, newFile.toPath) - } - } - - - } else { - // In the jar or plain Java application case, the bundle is ignored and the file path - // is searched on the classpath directly - val fileNames = #["icons/connect.svg", "icons/connect128.png", - "icons/expand.svg", "icons/expand128.png", - "icons/loupe.svg", "icons/loupe128.png", - "icons/minimize.svg", "icons/minimize128.png", - "icons/restore.svg", "icons/restore128.png"] - // TODO: this has to be tested from a standalone application. - for (fileName : fileNames) { - val InputStream source = FileGenerator.getResourceAsStream("/" + sourceFolder + "/" + fileName) - val newFile = new File(targetFolder.rawLocation.toString + "/" + fileName) - if (!newFile.exists) { - Files.copy(source, newFile.toPath) - } - } - } + Files.write(Paths.get(file.path), fileContent.bytes) } /** - * Creates the given resource recursively up, so this resource and any parent folders not yet created are created. + * Copies the files at the source location to the target folder. * - * @param resource The resource to create - * @param progressMonitor The progressMonitor + * @param sourceFolder The folder to copy the files from. + * @param targetFolder The folder to copy the files to. */ - def static void create(IResource resource, IProgressMonitor progressMonitor) { - if (resource === null || resource.exists()) { - return; - } - if (!resource.parent.exists()) { - create(resource.parent, progressMonitor); - } - switch (resource.type) { - case IResource.FILE: { - (resource as IFile).create(new ByteArrayInputStream(#[]), false, progressMonitor) - } - case IResource.FOLDER: { - (resource as IFolder).create(IResource.NONE, true, progressMonitor) + def static void copyIcons(File targetFolder) { + targetFolder.mkdirs + // The file path is searched on the classpath directly + // TODO: this has to be tested. + val fileNames = #["connect.svg", "connect128.png", + "expand.svg", "expand128.png", + "loupe.svg", "loupe128.png", + "loupe-crossed.svg", "loupe-crossed128.png", + "minimize.svg", "minimize128.png", + "restore.svg", "restore128.png"] + for (fileName : fileNames) { + val InputStream source = FileGenerator.classLoader.getResourceAsStream("icons/" + fileName) + val newFile = new File(targetFolder, fileName) + if (!newFile.exists) { + Files.copy(source, newFile.toPath) } } } - + /** - * Generates the content for the MANIFEST.MF file + * Creates a directory under the given filePath. * - * @param identifier - * the fully qualified identifier of the generated bundle. - * @param requiredBundles - * the Bundles this bundle requires and should be added to the manifest. - * @param exportedPackages - * the Packages this bundle exports and should be added to the manifest. - * @return - * the generated content for the manifest as a String. + * @param filePath the path to the directory + * @return The file object for that directory. */ - def static String manifestContent(String identifier, Iterable requiredBundles, Iterable exportedPackages) { - return ''' - Manifest-Version: 1.0 - Bundle-ManifestVersion: 2 - Automatic-Module-Name: «CodeGenUtil.validPluginID(identifier)» - Bundle-Name: «identifier» - Bundle-SymbolicName: «CodeGenUtil.validPluginID(identifier)»; singleton:=true - Bundle-Version: 0.1.0.qualifier - Bundle-RequiredExecutionEnvironment: JavaSE-17 - «FOR exportedPackage : exportedPackages BEFORE "Export-Package:" SEPARATOR ','» - «" " + exportedPackage» - «ENDFOR» - «FOR requiredBundle : requiredBundles BEFORE "Require-Bundle:" SEPARATOR ','» - «" " + requiredBundle» - «ENDFOR» - ''' - } - - def static String buildPropertiesContent(boolean isViz) { - return ''' - source.. = src/,\ - src-gen/,\ - xtend-gen/ - bin.includes = META-INF/,\ - «IF isViz» - .,\ - plugin.xml,\ - icons/ - «ELSE» - . - «ENDIF» - - ''' + def static File createDirectory(String filePath) { + val directory = new File(filePath) + directory.mkdirs + return directory } - def static modelBuildPropertiesContent() { - return ''' - bin.includes = .,\ - model/,\ - META-INF/,\ - plugin.xml,\ - plugin.properties - jars.compile.order = . - source.. = src/,\ - src-gen/,\ - xtend-gen/ - output.. = bin/ - - ''' + /** + * Creates a directory under the given filePath based on the given base. + * + * @param base the base path where to create this directory. + * @param filePath the path to the directory + * @return The file object for that directory. + */ + def static File createDirectory(File base, String path) { + val File directory = new File(base, path) + directory.mkdirs + return directory } } \ No newline at end of file diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/GenerateGeneratorScaffold.xtend b/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/GenerateGeneratorScaffold.xtend index 850cd1b..baab19f 100644 --- a/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/GenerateGeneratorScaffold.xtend +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/GenerateGeneratorScaffold.xtend @@ -3,7 +3,7 @@ * * http://rtsys.informatik.uni-kiel.de/kieler * - * Copyright 2022-2023 by + * Copyright 2022-2024 by * + Kiel University * + Department of Computer Science * + Real-Time and Embedded Systems Group @@ -16,43 +16,46 @@ import de.cau.cs.kieler.spviz.spvizmodel.generator.maven.Dependency import de.cau.cs.kieler.spviz.spvizmodel.sPVizModel.Connection import de.cau.cs.kieler.spviz.spvizmodel.sPVizModel.Containment import de.cau.cs.kieler.spviz.spvizmodel.sPVizModel.SPVizModel -import org.eclipse.core.resources.IProject -import org.eclipse.core.resources.IWorkspace -import org.eclipse.core.resources.ResourcesPlugin -import org.eclipse.core.runtime.IProgressMonitor +import java.io.File +import org.slf4j.Logger +import org.slf4j.LoggerFactory /** * Helper methods to generate Maven build artifacts for plugins. */ class GenerateGeneratorScaffold { - def static generate(SPVizModel model, String version, IProgressMonitor progressMonitor) { - val generatorBundleName = model.package + ".generate" - - // Check if the project does already exist. - val IWorkspace workspace = ResourcesPlugin.getWorkspace() - val IProject project = workspace.getRoot().getProject(generatorBundleName) + static final Logger LOGGER = LoggerFactory.getLogger(GenerateGeneratorScaffold) + + def static generate(File rootDirectory, SPVizModel model, String version) { + val projectName = model.package + ".generate" - // Do not overwrite an existing project. - if (project.exists()) { + val existingDirectory = new File(rootDirectory, projectName) + if (existingDirectory.isDirectory) { + LOGGER.info("Skipped generating generator scaffold project, folder already exists. {}", existingDirectory.absolutePath) return + } else { + LOGGER.info("Generating project {}", existingDirectory.absolutePath) } + val projectPath = rootDirectory.absolutePath + "/" + projectName + val File projectDirectory = FileGenerator.createDirectory(rootDirectory, projectName) + // Generate a new Java project - val generateProject = new JavaMavenProjectGenerator(model.package, generatorBundleName) + new JavaMavenProjectGenerator(model.package, projectName, projectPath) .configureDependencies(requiredBundles(model)) .configureSourceFolderName("src") .configureGenerateShadedJar(true) .configureMainClass("ConfigAndExecuteCli") - .generate(progressMonitor) + .generate() - val packageFolder = generateProject.getFolder(generatorBundleName.split('\\.').fold("src", [l, r | l + '/' + r])) + val packageFolder = FileGenerator.createDirectory(projectDirectory, "src/" + projectName.replace('.', '/')) // Generate the scaffold Java files - FileGenerator.generateFile(packageFolder, "ConfigAndExecuteCli.java", configAndExecute(model), progressMonitor) - FileGenerator.generateFile(packageFolder, model.name + "ModelDataGenerator.java", modelDataGenerator(model), progressMonitor) - FileGenerator.generateFile(packageFolder, model.name + "ModelSaveAndLoadUtility.java", modelSaveAndLoadUtility(model), progressMonitor) - FileGenerator.generateFile(packageFolder, "ReadProjectFiles.java", readProjectFilesScaffold(model), progressMonitor) + FileGenerator.generateFile(packageFolder, "ConfigAndExecuteCli.java", configAndExecute(model)) + FileGenerator.generateFile(packageFolder, model.name + "ModelDataGenerator.java", modelDataGenerator(model)) + FileGenerator.generateFile(packageFolder, model.name + "ModelSaveAndLoadUtility.java", modelSaveAndLoadUtility(model)) + FileGenerator.generateFile(packageFolder, "ReadProjectFiles.java", readProjectFilesScaffold(model)) } def static configAndExecute(SPVizModel model) { diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/GenerateModelMavenBuild.xtend b/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/GenerateModelMavenBuild.xtend index d47b0ba..bd47ae0 100644 --- a/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/GenerateModelMavenBuild.xtend +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/GenerateModelMavenBuild.xtend @@ -3,7 +3,7 @@ * * http://rtsys.informatik.uni-kiel.de/kieler * - * Copyright 2022-2023 by + * Copyright 2022-2024 by * + Kiel University * + Department of Computer Science * + Real-Time and Embedded Systems Group @@ -13,14 +13,19 @@ package de.cau.cs.kieler.spviz.spvizmodel.generator import de.cau.cs.kieler.spviz.spvizmodel.sPVizModel.SPVizModel -import org.eclipse.core.resources.IProject -import org.eclipse.core.resources.ResourcesPlugin -import org.eclipse.core.runtime.IProgressMonitor +import java.io.File +import org.slf4j.Logger +import org.slf4j.LoggerFactory /** * Helper methods to generate Maven build artifacts for plugins. + * + * @author nre */ class GenerateModelMavenBuild { + + static final Logger LOGGER = LoggerFactory.getLogger(GenerateModelMavenBuild) + /* * TODO: * - generate a full .gitignore for an easier build process (/bin, /target, dependencies.txt, ...) @@ -29,48 +34,42 @@ class GenerateModelMavenBuild { /** * Generates a pom.xml file for the given project and model. * - * @param project The generated Eclipse project for that the pom.xml file should be added. + * @param projectDirectory The generated project directory for that the pom.xml file should be added. * @param model The source model */ - static def addPluginPom(IProject project, SPVizModel model, String version, IProgressMonitor progressMonitor) { - val groupId = model.package - val content = pomXmlContent(groupId, "model", version) - FileGenerator.generateOrUpdateFile(project, "pom.xml", content, progressMonitor) + static def addPluginPom(File projectDirectory, SPVizModel model, String version) { + FileGenerator.generateFile(projectDirectory, "pom.xml", pomXmlContent(model.package, "model", version)) } /** * Generates the pom.xml in an own folder, working as the parent pom configuration for all * builds of projects using SPViz. Also adds a general target platform for all SPViz projects */ - static def addSpvizBuildProjectPom(String version, IProgressMonitor progressMonitor) { + static def addSpvizBuildProject(File rootDirectoy, String version) { val spvizPath = "spviz.build" // Create a project to hold the build pom. - val workspace = ResourcesPlugin.getWorkspace() - val IProject project = workspace.getRoot().getProject(spvizPath) - if (!project.exists()) { - val projectDescription = ResourcesPlugin.getWorkspace().newProjectDescription(spvizPath) - project.create(projectDescription, progressMonitor) + val existingDirectory = new File(rootDirectoy, spvizPath) + if (existingDirectory.isDirectory) { + LOGGER.info("Skipped generating build project, folder already exists. {}", existingDirectory.absolutePath) + return + } else { + LOGGER.info("Generating project {}", existingDirectory.absolutePath) } - project.open(progressMonitor) + val buildDirectory = FileGenerator.createDirectory(rootDirectoy, spvizPath) // Put the pom.xml in the project. val content = spvizPomXmlContent(version) - FileGenerator.generateOrUpdateFile(project, "pom.xml", content, progressMonitor) + FileGenerator.generateFile(buildDirectory, "pom.xml", content) // Generate the P2 update site config - addP2Config(project, version, progressMonitor) + addP2Config(buildDirectory, version) } - private static def addP2Config(IProject project, String version, IProgressMonitor progressMonitor) { - val targetPlatformFolder = project.getFolder("de.cau.cs.kieler.spviz.targetplatform") - if (!targetPlatformFolder.exists) { - targetPlatformFolder.create(false, true, progressMonitor) - } + private static def addP2Config(File buildDirectory, String version) { + val targetPlatformDirectory = FileGenerator.createDirectory(buildDirectory, "de.cau.cs.kieler.spviz.targetplatform") - var String content = targetContent - FileGenerator.generateOrUpdateFile(targetPlatformFolder, "de.cau.cs.kieler.spviz.targetplatform.target", content, progressMonitor) - content = targetPlatformPomXmlContent(version) - FileGenerator.generateOrUpdateFile(targetPlatformFolder, "pom.xml", content, progressMonitor) + FileGenerator.generateFile(targetPlatformDirectory, "de.cau.cs.kieler.spviz.targetplatform.target", targetContent) + FileGenerator.generateFile(targetPlatformDirectory, "pom.xml", targetPlatformPomXmlContent(version)) } private static def pomXmlContent(String groupId, String artifactId, String version) { @@ -93,6 +92,109 @@ class GenerateModelMavenBuild { src-gen + + + org.eclipse.xtext + xtext-maven-plugin + ${xtext-version} + + + generate-sources + + generate + + + + + + + org.eclipse.xtext.ecore.EcoreSupport + + + org.eclipse.emf.codegen.ecore.xtext.GenModelSupport + + + org.eclipse.emf.ecore.xcore.XcoreStandaloneSetup + + + ${project.basedir}/src-gen + + + + + + ${basedir}/model + + + + + org.eclipse.platform + org.eclipse.text + 3.14.100 + + + org.eclipse.platform + org.eclipse.core.resources + 3.20.200 + + + org.eclipse.xtext + org.eclipse.xtext.ecore + ${xtext-version} + + + org.eclipse.xtext + org.eclipse.xtext.xtext.generator + ${xtext-version} + + + org.eclipse.xtext + org.eclipse.xtext.builder.standalone + ${xtext-version} + + + org.eclipse.emf + org.eclipse.emf.codegen.ecore.xtext + 1.8.0 + + + org.eclipse.emf + org.eclipse.emf.common + 2.30.0 + + + org.eclipse.emf + org.eclipse.emf.ecore + 2.36.0 + + + org.eclipse.emf + org.eclipse.emf.ecore.xmi + 2.37.0 + + + org.eclipse.emf + org.eclipse.emf.codegen + 2.14.0 + + + org.eclipse.emf + org.eclipse.emf.codegen.ecore + 2.23.0 + + + org.eclipse.emf + org.eclipse.emf.ecore.xcore + 1.29.0 + + + org.eclipse.emf + org.eclipse.emf.ecore.xcore.lib + 1.7.0 + + + + @@ -121,9 +223,9 @@ class GenerateModelMavenBuild { 0.9.1 2.10.1 7.0.0 - 3.0.1.v20240410 + 3.0.2.v20240507 0.22.0 - 2.7.3 + 2.7.5 2.33.0 2.33.0 @@ -348,7 +450,7 @@ class GenerateModelMavenBuild { org.eclipse.tycho target-platform-configuration - [2.7.3,) + [2.7.5,) target-platform diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/GenerateModelUtils.xtend b/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/GenerateModelUtils.xtend index 3b49139..31827e5 100644 --- a/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/GenerateModelUtils.xtend +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/GenerateModelUtils.xtend @@ -3,7 +3,7 @@ * * http://rtsys.informatik.uni-kiel.de/kieler * - * Copyright 2021 by + * Copyright 2021-2024 by * + Kiel University * + Department of Computer Science * + Real-Time and Embedded Systems Group @@ -13,23 +13,21 @@ package de.cau.cs.kieler.spviz.spvizmodel.generator import de.cau.cs.kieler.spviz.spvizmodel.sPVizModel.SPVizModel -import org.eclipse.core.resources.IFolder -import org.eclipse.core.runtime.IProgressMonitor +import java.io.File /** * Generates utility classes for the model. * - * @author leo, nre + * @author nre, leo */ class GenerateModelUtils { - def static void generate(IFolder sourceFolder, SPVizModel spvizModel, IProgressMonitor progressMonitor) { - var folder = spvizModel.package.replace('.', '/') + "/model/util/" - FileGenerator.generateOrUpdateFile(sourceFolder, folder + "ModelUtil.java", - generateModelUtil(spvizModel.name + "Project", spvizModel.package), progressMonitor) + def static void generate(File sourceFolder, SPVizModel spvizModel) { + val folder = FileGenerator.createDirectory(sourceFolder, spvizModel.package.replace('.', '/') + "/model/util/") + FileGenerator.updateFile(folder, "ModelUtil.java", generateModelUtil(spvizModel.name + "Project", spvizModel.package)) } /** - * Generates the contend for the ModelUtil.java file contained inside the model package + * Generates the content for the ModelUtil.java file contained inside the model package * * @param projectName * the model project name diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/JavaMavenProjectGenerator.xtend b/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/JavaMavenProjectGenerator.xtend index 431a3d3..314065e 100644 --- a/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/JavaMavenProjectGenerator.xtend +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/JavaMavenProjectGenerator.xtend @@ -3,7 +3,7 @@ * * http://rtsys.informatik.uni-kiel.de/kieler * - * Copyright 2022-2023 by + * Copyright 2022-2024 by * + Kiel University * + Department of Computer Science * + Real-Time and Embedded Systems Group @@ -13,27 +13,20 @@ package de.cau.cs.kieler.spviz.spvizmodel.generator import de.cau.cs.kieler.spviz.spvizmodel.generator.maven.Dependency +import java.io.File import java.util.List -import org.eclipse.core.resources.IProject -import org.eclipse.core.resources.IProjectDescription -import org.eclipse.core.resources.IWorkspace -import org.eclipse.core.resources.ResourcesPlugin -import org.eclipse.core.runtime.IProgressMonitor -import org.eclipse.core.runtime.Path -import org.eclipse.emf.common.util.BasicMonitor -import org.eclipse.jdt.core.IClasspathEntry -import org.eclipse.jdt.core.IJavaProject -import org.eclipse.jdt.core.JavaCore -import org.eclipse.m2e.core.internal.IMavenConstants /** * Generator for Java projects using Maven dependencies. Configure it with chained configure[...] methods and start with - * {@link #generate(IProgressMonitor)}. + * {@link #generate()}. * * @author nre */ class JavaMavenProjectGenerator { + /** directory of the project to be generated */ + val File projectDirectory + /** Group ID of the project to be generated. */ val String groupId @@ -46,7 +39,7 @@ class JavaMavenProjectGenerator { /** Additional dependency management to be added to the project pom, as formatted String. */ var String dependencyManagement = "" - /** The subfolder name of the source folder */ + /** The sub-folder name of the source folder */ var String sourceFolderName = "src-gen" /** @@ -64,9 +57,10 @@ class JavaMavenProjectGenerator { /** * Create a new generator. */ - new(String groupId, String artifactId) { + new(String groupId, String projectName, String projectPath) { this.groupId = groupId - this.artifactId = artifactId + this.artifactId = projectName + this.projectDirectory = FileGenerator.createDirectory(projectPath) } /** @@ -142,76 +136,80 @@ class JavaMavenProjectGenerator { /** * Starts the generation of this generator and returns the fully generated Java project. - * - * @param progressMonitor The progressMonitor - * @returns The new Java project that was generated on the file system. */ - def IProject generate(IProgressMonitor progressMonitor) { - // Create the project. - val IWorkspace workspace = ResourcesPlugin.getWorkspace() - val IProject project = workspace.getRoot().getProject(artifactId) - var IProjectDescription projectDescription = null + def void generate() { + val File settingsDirectory = FileGenerator.createDirectory(projectDirectory, ".settings") - if (!project.exists()) { - projectDescription = ResourcesPlugin.getWorkspace().newProjectDescription(artifactId) - project.create(projectDescription, BasicMonitor.subProgress(progressMonitor, 1)) - } else { - projectDescription = project.description - } - project.open(BasicMonitor.subProgress(progressMonitor, 1)) - - // Add the Java nature to the project - var String[] natureIds = projectDescription.getNatureIds() - if (natureIds === null) { - natureIds = #[ JavaCore.NATURE_ID, IMavenConstants.NATURE_ID ] - } else { - if (!project.hasNature(JavaCore.NATURE_ID)) { - val oldNatureIds = natureIds - natureIds = newArrayOfSize(oldNatureIds.length + 1) - System.arraycopy(oldNatureIds, 0, natureIds, 0, oldNatureIds.length) - natureIds.set(oldNatureIds.length, JavaCore.NATURE_ID) - } - if (!project.hasNature(IMavenConstants.NATURE_ID)) { - val oldNatureIds = natureIds - natureIds = newArrayOfSize(oldNatureIds.length + 1) - System.arraycopy(oldNatureIds, 0, natureIds, 0, oldNatureIds.length) - natureIds.set(oldNatureIds.length, IMavenConstants.NATURE_ID) - } - } - projectDescription.setNatureIds(natureIds) - project.setDescription(projectDescription, BasicMonitor.subProgress(progressMonitor, 1)); + // Create the .classpath file + FileGenerator.generateFile(new File(projectDirectory, ".classpath"), classpathContent) - // Configure the Java project - val IJavaProject javaProject = JavaCore.create(project) + // Create the .project file + FileGenerator.generateFile(new File(projectDirectory, ".project"), projectContent) - // Configure classpath - val entries = newArrayList - entries.add(JavaCore.newContainerEntry(new Path("org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"))); - entries.add(JavaCore.newContainerEntry(new Path("org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"))) + // Create the settings/org.eclipse.core.resources.prefs file + FileGenerator.generateFile(new File(settingsDirectory, "org.eclipse.core.resources.prefs"), eclipseCoreResourcesPrefsContent) - // The source folders - val sourceFolder = project.getFolder(sourceFolderName) - if (!sourceFolder.exists) { - sourceFolder.create(false, true, BasicMonitor.subProgress(progressMonitor, 1)) - } - val sourceFolderRoot = javaProject.getPackageFragmentRoot(sourceFolder) - entries.add(JavaCore.newSourceEntry(sourceFolderRoot.path)) + // Generate the pom.xml file + FileGenerator.generateFile(new File(projectDirectory, "pom.xml"), pomXmlContent) + // The source folders + FileGenerator.createDirectory(projectDirectory, sourceFolderName) if (xtendSources) { - val xtendGenFolder = project.getFolder("xtend-gen") - if (!xtendGenFolder.exists) { - xtendGenFolder.create(false, true, BasicMonitor.subProgress(progressMonitor, 1)) - } - val xtendGenFolderRoot = javaProject.getPackageFragmentRoot(xtendGenFolder) - entries.add(JavaCore.newSourceEntry(xtendGenFolderRoot.path)) + FileGenerator.createDirectory(projectDirectory, "xtend-gen") } - - javaProject.setRawClasspath(entries.toArray(newArrayOfSize(entries.size)), null) - - // Generate the pom.xml file - FileGenerator.generateFile(project, "/pom.xml", pomXmlContent, progressMonitor) - - return project + } + + private def classpathContent() { + return ''' + + + + + + «IF xtendSources» + + «ENDIF» + + + + ''' + } + + private def projectContent() { + return ''' + + + «artifactId» + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + + + ''' + } + + private def eclipseCoreResourcesPrefsContent() { + return ''' + eclipse.preferences.version=1 + encoding/=UTF-8 + + ''' } private def getPomXmlContent() { @@ -242,14 +240,6 @@ class JavaMavenProjectGenerator { «sourceFolderName» - - - «sourceFolderName» - - **/*.java - - - maven-compiler-plugin diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/JavaProjectGenerator.xtend b/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/JavaProjectGenerator.xtend deleted file mode 100644 index a4b0766..0000000 --- a/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/JavaProjectGenerator.xtend +++ /dev/null @@ -1,182 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://rtsys.informatik.uni-kiel.de/kieler - * - * Copyright 2022 by - * + Kiel University - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License 2.0 (EPL-2.0). - */ -package de.cau.cs.kieler.spviz.spvizmodel.generator - -import java.util.List -import org.eclipse.core.resources.IProject -import org.eclipse.core.resources.IProjectDescription -import org.eclipse.core.resources.IWorkspace -import org.eclipse.core.resources.ResourcesPlugin -import org.eclipse.core.runtime.IProgressMonitor -import org.eclipse.core.runtime.Path -import org.eclipse.emf.common.util.BasicMonitor -import org.eclipse.jdt.core.IClasspathEntry -import org.eclipse.jdt.core.IJavaProject -import org.eclipse.jdt.core.JavaCore - -/** - * Generator for Java projects. Configure it with chained configure[...] methods and start with - * {@link #generate(IProgressMonitor)}. - * - * @author nre - */ -class JavaProjectGenerator { - - /** path of the project to be generated */ - val String projectPath - - /** The additional required bundles for this new project. */ - val List requiredBundles = newArrayList - - /** The exported packages for this new project. */ - val List exportedPackages = newArrayList - - /** The subfolder name of the source folder */ - var String sourceFolderName = "src-gen" - - /** - * Create a new generator. - */ - new(String projectName) { - this.projectPath = projectName - } - - /** - * Adds the given bundles as requirements to be written into the manifest as plug-in dependencies. - * - * @param requiredBundles The IDs of the bundles to be added as dependencies. - * @return This generator, for chaining configurations. - */ - def JavaProjectGenerator configureRequiredBundles(Iterable requiredBundles) { - for (requiredBundle : requiredBundles) { - if (!this.requiredBundles.contains(requiredBundle)) { - this.requiredBundles.add(requiredBundle) - } - } - - return this - } - - /** - * Adds the given exported packages to be written into the manifest. - * - * @param exportedPackages The IDs of the exported packages. - * @return This generator, for chaining configurations. - */ - def JavaProjectGenerator configureExportedPackages(Iterable exportedPackages) { - for (exportedPackage : exportedPackages) { - if (!this.exportedPackages.contains(exportedPackage)) { - this.exportedPackages.add(exportedPackage) - } - } - - return this - } - - /** - * Configure the source folder where the files should be generated into. Defaults to "src-gen". - * - * @param sourceFolderName the source folder to generate and configure. - * @return This generator, for chaining configurations. - */ - def JavaProjectGenerator configureSourceFolderName(String sourceFolderName) { - this.sourceFolderName = sourceFolderName - return this - } - - /** - * Starts the generation of this generator and returns the fully generated Java project. - * - * @param progressMonitor The progressMonitor - * @returns The new Java project that was generated on the file system. - */ - def IProject generate(IProgressMonitor progressMonitor) { - val genModelContainerPath = new Path("/" + projectPath + "/" + sourceFolderName) - - // Create the project. - val IWorkspace workspace = ResourcesPlugin.getWorkspace() - val IProject project = workspace.getRoot().getProject(projectPath) - var IProjectDescription projectDescription = null - - if (!project.exists()) { - projectDescription = ResourcesPlugin.getWorkspace().newProjectDescription(projectPath) - project.create(projectDescription, BasicMonitor.subProgress(progressMonitor, 1)) - } else { - projectDescription = project.description - } - project.open(BasicMonitor.subProgress(progressMonitor, 1)) - - // Add the Java and Xtext natures to the project - var String[] natureIds = projectDescription.getNatureIds() - if (natureIds === null) { - natureIds = #[ JavaCore.NATURE_ID, "org.eclipse.xtext.ui.shared.xtextNature" ] - } else { - if (!project.hasNature(JavaCore.NATURE_ID)) { - val oldNatureIds = natureIds - natureIds = newArrayOfSize(oldNatureIds.length + 1) - System.arraycopy(oldNatureIds, 0, natureIds, 0, oldNatureIds.length) - natureIds.set(oldNatureIds.length, JavaCore.NATURE_ID) - } - if (!project.hasNature("org.eclipse.xtext.ui.shared.xtextNature")) { - val oldNatureIds = natureIds - natureIds = newArrayOfSize(oldNatureIds.length + 1) - System.arraycopy(oldNatureIds, 0, natureIds, 0, oldNatureIds.length) - natureIds.set(oldNatureIds.length, "org.eclipse.xtext.ui.shared.xtextNature") - } - } - projectDescription.setNatureIds(natureIds) - project.setDescription(projectDescription, BasicMonitor.subProgress(progressMonitor, 1)); - - // Configure the Java project - val IJavaProject javaProject = JavaCore.create(project) - - val binFolder = project.getFolder("bin") - if (!binFolder.exists) { - binFolder.create(false, true, BasicMonitor.subProgress(progressMonitor, 1)) - } - javaProject.setOutputLocation(binFolder.fullPath, BasicMonitor.subProgress(progressMonitor, 1)) - - // Configure classpath - val entries = newArrayList - entries.add(JavaCore.newContainerEntry(new Path("org.eclipse.xtend.XTEND_CONTAINER"))) - entries.add(JavaCore.newContainerEntry(new Path("org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"))); - entries.add(JavaCore.newContainerEntry(new Path("org.eclipse.pde.core.requiredPlugins"))) - - // The source and xtend-gen folders - val sourceFolder = project.getFolder(sourceFolderName) - if (!sourceFolder.exists) { - sourceFolder.create(false, true, BasicMonitor.subProgress(progressMonitor, 1)) - } - val xtendGenFolder = project.getFolder("xtend-gen") - if (!xtendGenFolder.exists) { - xtendGenFolder.create(false, true, BasicMonitor.subProgress(progressMonitor, 1)) - } - - val sourceFolderRoot = javaProject.getPackageFragmentRoot(sourceFolder) - val xtendGenFolderRoot = javaProject.getPackageFragmentRoot(xtendGenFolder) - entries.add(JavaCore.newSourceEntry(sourceFolderRoot.path)) - entries.add(JavaCore.newSourceEntry(xtendGenFolderRoot.path)) - javaProject.setRawClasspath(entries.toArray(newArrayOfSize(entries.size)), null) - - // Generate the manifest - FileGenerator.generateFile(project, "/META-INF/MANIFEST.MF", - FileGenerator.manifestContent(genModelContainerPath.segment(0), requiredBundles, exportedPackages), progressMonitor) - - // Generate the build.properties file - FileGenerator.generateFile(project, "/build.properties", - FileGenerator.buildPropertiesContent(false), progressMonitor) - - return project - } - -} diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/ProjectGenerator.xtend b/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/ProjectGenerator.xtend new file mode 100644 index 0000000..9834220 --- /dev/null +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/ProjectGenerator.xtend @@ -0,0 +1,392 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright 2021-2024 by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License 2.0 (EPL-2.0). + */ +package de.cau.cs.kieler.spviz.spvizmodel.generator + +import java.io.File +import java.util.List +import org.eclipse.emf.codegen.util.CodeGenUtil + +/** + * Generator for various different Java projects. Configure it with chained configure[...] methods and start with + * {@link #generate()}. + * + * @author nre + */ +class ProjectGenerator { + + /** The name of the project */ + val String projectName + + /** directory of the project to be generated */ + val File projectDirectory + + /** The name of the Xcore model */ + var String xCoreModelName = null + + /** Name of the to-be-generated Xcore file */ + var String xCoreFileName = null + + /** Content of the to-be-generated Xcore file */ + var String xCoreFileContent = null + + /** If this project features a KLighD startup hook */ + var boolean klighdHook = false + + /** If this project as an additional icons folder for the binary build. */ + var boolean icons = false + + /** The additional required bundles for this new project. */ + val List requiredBundles = newArrayList + + /** The exported packages for this project. */ + val List exportedPackages = newArrayList + + /** If this project should have Maven nature. */ + var boolean mavenNature = false + + /** Additional source folders that should be included in this project's build process. */ + val List additionalSourceFolders = newArrayList + + /** + * Create a new generator. + */ + new(String projectName, String projectPath) { + this.projectName = projectName + this.projectDirectory = FileGenerator.createDirectory(projectPath) + configureRequiredBundles(#["org.eclipse.emf.ecore", "org.eclipse.xtext.xbase.lib", + "org.eclipse.emf.ecore.xcore.lib"]) + } + + /** + * Configure the model name and content of the Xcore file in the /model folder of the generated project. + * + * @param modelName The name of the Xcore model + * @param fileContent The content for that Xcore file. + * @return This generator, for chaining configurations. + */ + def ProjectGenerator configureXCoreFile(String modelName, String fileContent) { + this.xCoreModelName = modelName + this.xCoreFileName = modelName + 'Model.xcore' + this.xCoreFileContent = fileContent + + return this + } + + /** + * Configures if this generator should generate this project with a KLighD startup hook in mind. + * + * @param klighdHook {@code true} if this should have a startup hook. + * @return This generator, for chaining configurations. + */ + def configureKlighd(boolean klighdHook) { + this.klighdHook = klighdHook + return this + } + + /** + * Configures if this generator should generate this project with an icons folder in mind. + * + * @param icons {@code true} if this should keep it in mind.. + * @return This generator, for chaining configurations. + */ + def configureIcons(boolean icons) { + this.icons = icons + return this + } + + /** + * Adds the given bundles as requirements to be written into the manifest as plug-in dependencies. + * + * @param requiredBundles The IDs of the bundles to be added as dependencies. + * @return This generator, for chaining configurations. + */ + def ProjectGenerator configureRequiredBundles(Iterable requiredBundles) { + for (requiredBundle : requiredBundles) { + if (!this.requiredBundles.contains(requiredBundle)) { + this.requiredBundles.add(requiredBundle) + } + } + + return this + } + + /** + * Adds the given packages to be written into the manifest as package exports. + * + * @param exportedPackages The IDs of the packages to be exported. + * @return This generator, for chaining configurations. + */ + def ProjectGenerator configureExportedPackages(Iterable exportedPackages) { + for (exportedPackage : exportedPackages) { + if (!this.exportedPackages.contains(exportedPackage)) { + this.exportedPackages.add(exportedPackage) + } + } + + return this + } + + /** + * Configures if this generator should generate this project with Maven nature. + * + * @param mavenNature {@code true} if this should have the Maven nature. + * @return This generator, for chaining configurations. + */ + def configureMaven(boolean mavenNature) { + this.mavenNature = mavenNature + return this + } + + /** + * Adds the given relative path as further source folders of this project. + * + * @param sourceFolder the folder to add as a source folder, e.g. xtend-gen or src-gen. + * @return This generator, for chaining configurations. + */ + def additionalSourceFolder(String sourceFolder) { + this.additionalSourceFolders.add(sourceFolder) + return this + } + + /** + * Starts the generation of this generator. + */ + def void generate() { + // Create all necessary directories + FileGenerator.createDirectory(projectDirectory, "src-gen") + for (sourceFolder : additionalSourceFolders) { + FileGenerator.createDirectory(projectDirectory, sourceFolder) + } + val File settingsDirectory = FileGenerator.createDirectory(projectDirectory, ".settings") + + // Create the .classpath file + FileGenerator.generateFile(projectDirectory, ".classpath", classpathContent) + + // Create the .project file + FileGenerator.generateFile(projectDirectory, ".project", projectContent) + + // Create the settings/org.eclipse.core.resources.prefs file + FileGenerator.generateFile(settingsDirectory, "org.eclipse.core.resources.prefs", eclipseCoreResourcesPrefsContent) + + // Generate the manifest + val File manifestDirectory = FileGenerator.createDirectory(projectDirectory, "META-INF") + FileGenerator.generateFile(manifestDirectory, "MANIFEST.MF", + manifestContent(projectName, requiredBundles, exportedPackages)) + + if (this.xCoreModelName !== null) { + // Create the /model directory + val File modelDirectory = FileGenerator.createDirectory(projectDirectory, "model") + + // Create/Update the Xcore file in the project. + FileGenerator.generateFile(modelDirectory, xCoreFileName, xCoreFileContent) + + } + + if (this.xCoreModelName !== null || this.klighdHook) { + // Generate the plugin.xml + FileGenerator.generateFile(projectDirectory, "plugin.xml", pluginXmlContent) + } + + if (this.klighdHook) { + // Generate the services file + FileGenerator.createDirectory(projectDirectory, "META-INF/services") + FileGenerator.generateFile(projectDirectory, + "/META-INF/services/de.cau.cs.kieler.klighd.IKlighdStartupHook", serviceFileContent) + } + + // Generate plugin.properties + FileGenerator.generateFile(projectDirectory, "plugin.properties", pluginPropertiesContent) + + // Generate build.properties + FileGenerator.generateFile(projectDirectory, "build.properties", buildPropertiesContent) + } + + private def classpathContent() { + return ''' + + + + «FOR additionalSourceFolder : additionalSourceFolders» + + «ENDFOR» + + + + + + ''' + } + + private def projectContent() { + return ''' + + + «projectName» + + + + + + org.eclipse.xtext.ui.shared.xtextBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + «IF mavenNature» + + org.eclipse.m2e.core.maven2Builder + + + + «ENDIF» + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + org.eclipse.xtext.ui.shared.xtextNature + «IF mavenNature» + org.eclipse.m2e.core.maven2Nature + «ENDIF» + + + + ''' + } + + private def eclipseCoreResourcesPrefsContent() { + return ''' + eclipse.preferences.version=1 + encoding/=UTF-8 + + ''' + } + + /** + * Generates the content for the MANIFEST.MF file + * + * @param identifier + * the fully qualified identifier of the generated bundle. + * @param requiredBundles + * the Bundles this bundle requires and should be added to the manifest. + * @param exportedPackages + * the Packages this bundle exports and should be added to the manifest. + * @return + * the generated content for the manifest as a String. + */ + private def manifestContent(String identifier, Iterable requiredBundles, Iterable exportedPackages) { + return ''' + Manifest-Version: 1.0 + Bundle-ManifestVersion: 2 + Automatic-Module-Name: «CodeGenUtil.validPluginID(identifier)» + Bundle-Name: «identifier» + Bundle-SymbolicName: «CodeGenUtil.validPluginID(identifier)»; singleton:=true + Bundle-Version: 0.1.0.qualifier + Bundle-RequiredExecutionEnvironment: JavaSE-17 + «FOR exportedPackage : exportedPackages BEFORE "Export-Package:" SEPARATOR ','» + «" " + exportedPackage» + «ENDFOR» + «FOR requiredBundle : requiredBundles BEFORE "Require-Bundle:" SEPARATOR ','» + «" " + requiredBundle» + «ENDFOR» + ''' + } + + private def pluginXmlContent() { + return ''' + + + + + + + + «IF xCoreModelName !== null» + + + + + «ENDIF» + «IF klighdHook» + + + + + «ENDIF» + + + + ''' + } + + private def String serviceFileContent() { + return ''' + «projectName».KlighdSetup + ''' + } + + private def pluginPropertiesContent() { + return ''' + # + + pluginName = «projectName» + providerName = https://github.com/kieler/SoftwareProjectViz/ + + ''' + } + + private def buildPropertiesContent() { + return ''' + # + + bin.includes = .,\ + «IF xCoreFileName !== null» + model/,\ + plugin.properties,\ + «ENDIF» + «IF icons» + icons/,\ + «ENDIF» + META-INF/,\ + plugin.xml + bin.excludes = **/*.xtend,\ + **/*.java._trace + source.. = src-gen/«IF !additionalSourceFolders.empty»,\«ENDIF» + «FOR sourceFolder : additionalSourceFolders SEPARATOR ',\\'» + «sourceFolder»/ + «ENDFOR» + output.. = bin/ + + ''' + } + +} diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/SPVizModelGenerator.xtend b/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/SPVizModelGenerator.xtend index 6a20f7b..5e38a8f 100644 --- a/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/SPVizModelGenerator.xtend +++ b/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/SPVizModelGenerator.xtend @@ -3,7 +3,7 @@ * * http://rtsys.informatik.uni-kiel.de/kieler * - * Copyright 2020-2022 by + * Copyright 2020-2024 by * + Kiel University * + Department of Computer Science * + Real-Time and Embedded Systems Group @@ -15,45 +15,71 @@ package de.cau.cs.kieler.spviz.spvizmodel.generator import de.cau.cs.kieler.spviz.spvizmodel.sPVizModel.Connection import de.cau.cs.kieler.spviz.spvizmodel.sPVizModel.Containment import de.cau.cs.kieler.spviz.spvizmodel.sPVizModel.SPVizModel +import java.io.File +import java.nio.file.Path +import java.nio.file.Paths import java.util.ArrayList import java.util.LinkedHashMap +import org.eclipse.core.resources.ResourcesPlugin import org.eclipse.emf.ecore.resource.Resource import org.eclipse.xtext.generator.AbstractGenerator import org.eclipse.xtext.generator.IFileSystemAccess2 import org.eclipse.xtext.generator.IGeneratorContext -import org.eclipse.core.runtime.NullProgressMonitor +import org.slf4j.Logger +import org.slf4j.LoggerFactory /** * Generates code from your model files on save. * - * @author leo, nre + * @author nre, leo * @see https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation */ class SPVizModelGenerator extends AbstractGenerator { + static final Logger LOGGER = LoggerFactory.getLogger(SPVizModelGenerator) + override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) { + val workspace = ResourcesPlugin.workspace + val output = Paths.get(workspace.root.location.toString) + SPVizModelGenerator.generate(resource, output) + } + + static def void generate(Resource resource, Path rootPath) { + val rootDirectory = new File(rootPath.toAbsolutePath.toString) val SPVizModel model = resource.contents.head as SPVizModel - + val String fileContent = xcoreContent(model) - val progressMonitor = new NullProgressMonitor - val project = new XCoreProjectGenerator(model.package + ".model") - .configureXCoreFile(model.name + "Model.xcore", fileContent) + val projectName = model.package + ".model" + val projectPath = rootPath.toAbsolutePath.toString + "/" + projectName + if (new File(projectPath).isDirectory) { + LOGGER.info("Updating sources of project {}", projectPath) + } else { + LOGGER.info("Generating project {}", projectPath) + } + new ProjectGenerator(projectName, projectPath) + .configureXCoreFile(model.name, fileContent) + .configureExportedPackages(#[ + projectName, + projectName + ".impl", + projectName + ".util" + ]) .configureMaven(true) - .generate(progressMonitor) + .generate() - val sourceFolder = project.getFolder("src-gen"); + val sourceFolder = new File(projectPath, "src-gen") // Generate further source files for the project - GenerateModelUtils.generate(sourceFolder, model, progressMonitor) + GenerateModelUtils.generate(sourceFolder, model) // Generate the build artifacts for the project + val projectDirectory = FileGenerator.createDirectory(projectPath) val version = "0.1.0" - GenerateModelMavenBuild.addPluginPom(project, model, version, progressMonitor) + GenerateModelMavenBuild.addPluginPom(projectDirectory, model, version) - GenerateModelMavenBuild.addSpvizBuildProjectPom(version, progressMonitor) + GenerateModelMavenBuild.addSpvizBuildProject(rootDirectory, version) // Generate a .generate scaffold for the model if not already existent. - GenerateGeneratorScaffold.generate(model, version, progressMonitor) + GenerateGeneratorScaffold.generate(rootDirectory, model, version) } /** @@ -64,7 +90,7 @@ class SPVizModelGenerator extends AbstractGenerator { * @return * the generated content for the model XCore file as a string */ - private def String xcoreContent(SPVizModel model) { + private static def String xcoreContent(SPVizModel model) { // maps all artifacts to all artifacts they relate to, regardless of direction val LinkedHashMap> crossRef = newLinkedHashMap() diff --git a/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/XCoreProjectGenerator.xtend b/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/XCoreProjectGenerator.xtend deleted file mode 100644 index 7aadcd5..0000000 --- a/plugins/de.cau.cs.kieler.spviz.spvizmodel/src/de/cau/cs/kieler/spviz/spvizmodel/generator/XCoreProjectGenerator.xtend +++ /dev/null @@ -1,199 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://rtsys.informatik.uni-kiel.de/kieler - * - * Copyright 2021-2022 by - * + Kiel University - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License 2.0 (EPL-2.0). - */ -package de.cau.cs.kieler.spviz.spvizmodel.generator - -import java.io.ByteArrayInputStream -import java.util.Collections -import java.util.List -import org.eclipse.core.resources.IFolder -import org.eclipse.core.resources.IProject -import org.eclipse.core.resources.IProjectDescription -import org.eclipse.core.resources.IResource -import org.eclipse.core.runtime.IPath -import org.eclipse.core.runtime.IProgressMonitor -import org.eclipse.core.runtime.Path -import org.eclipse.emf.codegen.ecore.Generator -import org.eclipse.emf.codegen.util.CodeGenUtil - -/** - * Generator for Xcore projects. Configure it with chained configure[...] methods and start with - * {@link #generate(IProgressMonitor)}. - * - * @author nre - */ -class XCoreProjectGenerator { - - /** path of the project to be generated */ - val String projectPath - - /** Name of the to-be-generated Xcore file */ - var String xCoreFileName = null - - /** Content of the to-be-generated Xcore file */ - var String xCoreFileContent = null - - /** The additional required bundles for this new project. */ - val List requiredBundles = newArrayList - - /** The exported packages for this project. */ - val List exportedPackages = newArrayList - - /** If this project should have Maven nature. */ - var boolean mavenNature = false - - /** - * Create a new generator. - */ - new(String projectName) { - this.projectPath = projectName - configureRequiredBundles(#["org.eclipse.emf.ecore", "org.eclipse.xtext.xbase.lib", - "org.eclipse.emf.ecore.xcore.lib"]) - } - - /** - * Configure the file name and content of the Xcore file in the /model folder of the generated project. - * - * @param fileName The name of the Xcore file - * @param fileContent The content for that Xcore file. - * @return This generator, for chaining configurations. - */ - def XCoreProjectGenerator configureXCoreFile(String fileName, String fileContent) { - this.xCoreFileName = fileName - this.xCoreFileContent = fileContent - - return this - } - - /** - * Adds the given bundles as requirements to be written into the manifest as plug-in dependencies. - * - * @param requiredBundles The IDs of the bundles to be added as dependencies. - * @return This generator, for chaining configurations. - */ - def XCoreProjectGenerator configureRequiredBundles(Iterable requiredBundles) { - for (requiredBundle : requiredBundles) { - if (!this.requiredBundles.contains(requiredBundle)) { - this.requiredBundles.add(requiredBundle) - } - } - - return this - } - - /** - * Adds the given packages to be written into the manifest as package exports. - * - * @param exportedPackages The IDs of the packages to be exported. - * @return This generator, for chaining configurations. - */ - def XCoreProjectGenerator configureExportedPackages(Iterable exportedPackages) { - for (exportedPackage : exportedPackages) { - if (!this.exportedPackages.contains(exportedPackage)) { - this.exportedPackages.add(exportedPackage) - } - } - - return this - } - - /** - * Configures if this generator should generate this project with Maven nature. - * - * @param mavenNature {@code true} if this should have the Maven nature. - * @return This generator, for chaining configurations. - */ - def configureMaven(boolean mavenNature) { - this.mavenNature = mavenNature - return this - } - - /** - * Starts the generation of this generator and returns the fully generated XCore project. - * - * @param progressMonitor The progressMonitor - * @returns The new XCore project that was generated on the file system. - */ - def IProject generate(IProgressMonitor progressMonitor) { - val genModelContainerPath = new Path("/" + projectPath + "/src-gen") - val IPath genModelProjectLocation = null - - // Code taken and adapted from the org.eclipse.emf.ecore.xcore.ui.EmptyXcoreProjectWizard and - // org.eclipse.emf.codegen.ecore.ui.EmptyProjectWizard. - // Create the project as an EMF project. - val project = Generator.createEMFProject(new Path(genModelContainerPath.toString()), genModelProjectLocation, - Collections.emptyList(), progressMonitor, - Generator.EMF_MODEL_PROJECT_STYLE.bitwiseOr(Generator.EMF_PLUGIN_PROJECT_STYLE)) - - // Create the /model folder - val IFolder modelContainer = CodeGenUtil.EclipseUtil.findOrCreateContainer( - new Path("/" + genModelContainerPath.segment(0) + "/model"), true, genModelProjectLocation, - progressMonitor) as IFolder; - - // Create/Update the Xcore file in the project. - val xcoreFile = modelContainer.getFile(xCoreFileName) - val inputStream = new ByteArrayInputStream(xCoreFileContent.bytes) - if (xcoreFile.exists) { - xcoreFile.setContents(inputStream, IResource.NONE, progressMonitor) - } else { - xcoreFile.create(inputStream, IResource.NONE, progressMonitor) - } - - // Generate the manifest - FileGenerator.generateOrUpdateFile(project, "/META-INF/MANIFEST.MF", - FileGenerator.manifestContent(genModelContainerPath.segment(0), requiredBundles, exportedPackages), progressMonitor) - - XCoreProjectGenerator.addNatures(project, mavenNature, progressMonitor) - - return project - } - - /** - * Adds the Xtext nature to the given project. If {@code mavenNature} is set, also add the Maven nature. - * - * @param project The project to modify. - * @param mavenNature {@code true} if the Maven nature should be set as well. - * @param progressMonitor The progress monitor for Eclipse. - */ - static def void addNatures(IProject project, boolean mavenNature, IProgressMonitor progressMonitor) { - val IProjectDescription projectDescription = project.getDescription(); - var String[] natureIds = projectDescription.getNatureIds(); - if (natureIds === null) { - natureIds = #[ "org.eclipse.xtext.ui.shared.xtextNature" ] - - if (mavenNature) { - val oldNatureIds = natureIds - natureIds = newArrayOfSize(oldNatureIds.length + 1) - System.arraycopy(oldNatureIds, 0, natureIds, 0, oldNatureIds.length) - natureIds.set(oldNatureIds.length, "org.eclipse.m2e.core.maven2Nature") - } - } else { - // Add the Xtext nature to the project - if (!project.hasNature("org.eclipse.xtext.ui.shared.xtextNature")) { - val oldNatureIds = natureIds - natureIds = newArrayOfSize(oldNatureIds.length + 1) - System.arraycopy(oldNatureIds, 0, natureIds, 0, oldNatureIds.length) - natureIds.set(oldNatureIds.length, "org.eclipse.xtext.ui.shared.xtextNature") - } - // Add the Maven nature to the project - if (mavenNature && !project.hasNature("org.eclipse.m2e.core.maven2Nature")) { - val oldNatureIds = natureIds - natureIds = newArrayOfSize(oldNatureIds.length + 1) - System.arraycopy(oldNatureIds, 0, natureIds, 0, oldNatureIds.length) - natureIds.set(oldNatureIds.length, "org.eclipse.m2e.core.maven2Nature") - } - } - projectDescription.setNatureIds(natureIds); - project.setDescription(projectDescription, progressMonitor); - } - -}