From 0fed845468d3245a6c2bc058d12f4a9f1b92c587 Mon Sep 17 00:00:00 2001 From: Alain Picard Date: Wed, 8 Feb 2017 17:46:37 -0500 Subject: [PATCH 1/6] Adjusted java version --- plugins/ecoredocgen.incquery/.classpath | 16 ++++++++-------- .../hu.bme.mit.documentation.ecore.ui/.classpath | 2 +- .../hu.bme.mit.documentation.ecore/.classpath | 2 +- plugins/hu.qgears.documentation/.classpath | 14 +++++++------- plugins/hu.qgears.gendoc.app/.classpath | 15 ++++++++------- 5 files changed, 25 insertions(+), 24 deletions(-) diff --git a/plugins/ecoredocgen.incquery/.classpath b/plugins/ecoredocgen.incquery/.classpath index d25c08a..76509f9 100644 --- a/plugins/ecoredocgen.incquery/.classpath +++ b/plugins/ecoredocgen.incquery/.classpath @@ -1,8 +1,8 @@ - - - - - - - - + + + + + + + + diff --git a/plugins/hu.bme.mit.documentation.ecore.ui/.classpath b/plugins/hu.bme.mit.documentation.ecore.ui/.classpath index 8a8f166..b862a29 100644 --- a/plugins/hu.bme.mit.documentation.ecore.ui/.classpath +++ b/plugins/hu.bme.mit.documentation.ecore.ui/.classpath @@ -1,6 +1,6 @@ - + diff --git a/plugins/hu.bme.mit.documentation.ecore/.classpath b/plugins/hu.bme.mit.documentation.ecore/.classpath index b98a0d8..04c71c7 100644 --- a/plugins/hu.bme.mit.documentation.ecore/.classpath +++ b/plugins/hu.bme.mit.documentation.ecore/.classpath @@ -1,6 +1,6 @@ - + diff --git a/plugins/hu.qgears.documentation/.classpath b/plugins/hu.qgears.documentation/.classpath index 098194c..b862a29 100644 --- a/plugins/hu.qgears.documentation/.classpath +++ b/plugins/hu.qgears.documentation/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/plugins/hu.qgears.gendoc.app/.classpath b/plugins/hu.qgears.gendoc.app/.classpath index ad32c83..dc1a557 100644 --- a/plugins/hu.qgears.gendoc.app/.classpath +++ b/plugins/hu.qgears.gendoc.app/.classpath @@ -1,7 +1,8 @@ - - - - - - - + + + + + + + + From 6192db40fb402a8a2c95fcfbcccb0c49cd937dcc Mon Sep 17 00:00:00 2001 From: Alain Picard Date: Wed, 8 Feb 2017 17:49:07 -0500 Subject: [PATCH 2/6] Removed dependency on UI to allow command line application not to be forced to import UI plugins. --- .../.settings/org.eclipse.jdt.core.prefs | 6 +++--- plugins/hu.qgears.documentation/META-INF/MANIFEST.MF | 7 ++----- .../src/hu/qgears/documentation/Activator.java | 5 ++--- .../hu/qgears/documentation/DocumentationFieldUtils.java | 1 - 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/plugins/hu.qgears.documentation/.settings/org.eclipse.jdt.core.prefs b/plugins/hu.qgears.documentation/.settings/org.eclipse.jdt.core.prefs index f42de36..0c68a61 100644 --- a/plugins/hu.qgears.documentation/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/hu.qgears.documentation/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,7 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/plugins/hu.qgears.documentation/META-INF/MANIFEST.MF b/plugins/hu.qgears.documentation/META-INF/MANIFEST.MF index 4375978..9f59ec9 100644 --- a/plugins/hu.qgears.documentation/META-INF/MANIFEST.MF +++ b/plugins/hu.qgears.documentation/META-INF/MANIFEST.MF @@ -4,12 +4,9 @@ Bundle-Name: Documentation Bundle-SymbolicName: hu.qgears.documentation Bundle-Version: 1.0.0.qualifier Bundle-Activator: hu.qgears.documentation.Activator -Require-Bundle: org.eclipse.ui, - org.eclipse.core.runtime, - org.eclipse.emf.ecore, - org.eclipse.core.resources, +Require-Bundle: org.eclipse.core.runtime, org.eclipse.emf.ecore.xcore, org.eclipse.emf.codegen.ecore -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Export-Package: hu.qgears.documentation diff --git a/plugins/hu.qgears.documentation/src/hu/qgears/documentation/Activator.java b/plugins/hu.qgears.documentation/src/hu/qgears/documentation/Activator.java index 957e5a2..31e78a5 100644 --- a/plugins/hu.qgears.documentation/src/hu/qgears/documentation/Activator.java +++ b/plugins/hu.qgears.documentation/src/hu/qgears/documentation/Activator.java @@ -1,16 +1,15 @@ package hu.qgears.documentation; +import org.eclipse.core.runtime.Plugin; import org.eclipse.emf.ecore.EValidator; import org.eclipse.emf.ecore.EValidator.Registry; import org.eclipse.emf.ecore.EcorePackage; -import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; /** * The activator class controls the plug-in life cycle */ -public class Activator extends AbstractUIPlugin { - +public class Activator extends Plugin { private EValidator oldRegister; // The shared instance diff --git a/plugins/hu.qgears.documentation/src/hu/qgears/documentation/DocumentationFieldUtils.java b/plugins/hu.qgears.documentation/src/hu/qgears/documentation/DocumentationFieldUtils.java index b336dcb..a437c66 100644 --- a/plugins/hu.qgears.documentation/src/hu/qgears/documentation/DocumentationFieldUtils.java +++ b/plugins/hu.qgears.documentation/src/hu/qgears/documentation/DocumentationFieldUtils.java @@ -26,7 +26,6 @@ * */ public class DocumentationFieldUtils { - public static final String GEN_MODEL_PACKAGE_NS_URI = "http://www.eclipse.org/emf/2002/GenModel"; /** From f3368f0ff819c1565bcbf9a437f9db80fcb0ff30 Mon Sep 17 00:00:00 2001 From: Alain Picard Date: Wed, 8 Feb 2017 17:50:57 -0500 Subject: [PATCH 3/6] Added support to select genmodel and not only ecore from the UI to launch document generation --- .../.settings/org.eclipse.jdt.core.prefs | 6 ++--- .../META-INF/MANIFEST.MF | 2 +- .../plugin.xml | 14 ++++++++---- .../ui/handlers/AbstractGenerateEcoreDoc.java | 22 +++++++++---------- .../ui/handlers/GenerateEcoreDocHTML.java | 2 -- .../ui/handlers/GenerateEcoreDocLatex.java | 1 - 6 files changed, 24 insertions(+), 23 deletions(-) diff --git a/plugins/hu.bme.mit.documentation.ecore.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/hu.bme.mit.documentation.ecore.ui/.settings/org.eclipse.jdt.core.prefs index f287d53..295926d 100644 --- a/plugins/hu.bme.mit.documentation.ecore.ui/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/hu.bme.mit.documentation.ecore.ui/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,7 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/plugins/hu.bme.mit.documentation.ecore.ui/META-INF/MANIFEST.MF b/plugins/hu.bme.mit.documentation.ecore.ui/META-INF/MANIFEST.MF index 7f24fab..9edc1ed 100644 --- a/plugins/hu.bme.mit.documentation.ecore.ui/META-INF/MANIFEST.MF +++ b/plugins/hu.bme.mit.documentation.ecore.ui/META-INF/MANIFEST.MF @@ -12,6 +12,6 @@ Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime;bundle-version="3.7.0", org.eclipse.core.resources;bundle-version="3.7.101" Bundle-ActivationPolicy: lazy -Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-Vendor: Budapest University of Technology and Economics, Fault Tolerant Systems Research Group Export-Package: hu.bme.mit.documentation.ecore.ui.handlers diff --git a/plugins/hu.bme.mit.documentation.ecore.ui/plugin.xml b/plugins/hu.bme.mit.documentation.ecore.ui/plugin.xml index f479700..3bb1066 100644 --- a/plugins/hu.bme.mit.documentation.ecore.ui/plugin.xml +++ b/plugins/hu.bme.mit.documentation.ecore.ui/plugin.xml @@ -51,10 +51,16 @@ ifEmpty="false"> - - + + + + + + diff --git a/plugins/hu.bme.mit.documentation.ecore.ui/src/hu/bme/mit/documentation/ecore/ui/handlers/AbstractGenerateEcoreDoc.java b/plugins/hu.bme.mit.documentation.ecore.ui/src/hu/bme/mit/documentation/ecore/ui/handlers/AbstractGenerateEcoreDoc.java index 94d57ca..279eebd 100644 --- a/plugins/hu.bme.mit.documentation.ecore.ui/src/hu/bme/mit/documentation/ecore/ui/handlers/AbstractGenerateEcoreDoc.java +++ b/plugins/hu.bme.mit.documentation.ecore.ui/src/hu/bme/mit/documentation/ecore/ui/handlers/AbstractGenerateEcoreDoc.java @@ -14,6 +14,7 @@ import hu.bme.mit.documentation.generator.ecore.UtilDocGenerator; import java.io.File; +import java.io.IOException; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; @@ -32,22 +33,15 @@ * */ public abstract class AbstractGenerateEcoreDoc extends AbstractHandler { - - /* - * (non-Javadoc) - * - * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands. ExecutionEvent) - */ @Override public Object execute(ExecutionEvent event) throws ExecutionException { ISelection selection = HandlerUtil.getCurrentSelection(event); if (selection instanceof IStructuredSelection) { - for (Object element : ((IStructuredSelection) selection).toList()) { if (element instanceof IFile) { IFile file = (IFile) element; - if(file.getFileExtension().equals("ecore")){ + if(file.getFileExtension().equals("ecore") || file.getFileExtension().equals("genmodel")){ URI ecoreURI = URI.createPlatformResourceURI(file.getFullPath().toString(), true); String ecoreFileName = file.getName().substring(0,file.getName().indexOf(".")); @@ -67,10 +61,14 @@ public Object execute(ExecutionEvent event) throws ExecutionException { filterFile = folder.getFile(filterFileName); } IDocGenerator docGen = getCodeGenerator(); - UtilDocGenerator.generateDocForEPackage(ecoreURI, - new File(outFile.getLocationURI()), - new File(filterFile.getLocationURI()), - docGen); + try { + UtilDocGenerator.generateDocForModel(ecoreURI, + new File(outFile.getLocationURI()), + new File(filterFile.getLocationURI()), + docGen); + } catch (IOException e) { + throw new ExecutionException("Generation Exception", e); + } } } } diff --git a/plugins/hu.bme.mit.documentation.ecore.ui/src/hu/bme/mit/documentation/ecore/ui/handlers/GenerateEcoreDocHTML.java b/plugins/hu.bme.mit.documentation.ecore.ui/src/hu/bme/mit/documentation/ecore/ui/handlers/GenerateEcoreDocHTML.java index 59c8b4d..924bbe6 100644 --- a/plugins/hu.bme.mit.documentation.ecore.ui/src/hu/bme/mit/documentation/ecore/ui/handlers/GenerateEcoreDocHTML.java +++ b/plugins/hu.bme.mit.documentation.ecore.ui/src/hu/bme/mit/documentation/ecore/ui/handlers/GenerateEcoreDocHTML.java @@ -11,7 +11,6 @@ * */ public class GenerateEcoreDocHTML extends AbstractGenerateEcoreDoc { - @Override protected IDocGenerator getCodeGenerator() { return new EPackageDocGenHtml(); @@ -21,5 +20,4 @@ protected IDocGenerator getCodeGenerator() { protected String getFileExtension() { return "html"; } - } diff --git a/plugins/hu.bme.mit.documentation.ecore.ui/src/hu/bme/mit/documentation/ecore/ui/handlers/GenerateEcoreDocLatex.java b/plugins/hu.bme.mit.documentation.ecore.ui/src/hu/bme/mit/documentation/ecore/ui/handlers/GenerateEcoreDocLatex.java index ea2554e..02494b2 100644 --- a/plugins/hu.bme.mit.documentation.ecore.ui/src/hu/bme/mit/documentation/ecore/ui/handlers/GenerateEcoreDocLatex.java +++ b/plugins/hu.bme.mit.documentation.ecore.ui/src/hu/bme/mit/documentation/ecore/ui/handlers/GenerateEcoreDocLatex.java @@ -10,7 +10,6 @@ * */ public class GenerateEcoreDocLatex extends AbstractGenerateEcoreDoc { - @Override protected IDocGenerator getCodeGenerator() { return new EPackageDocGen(); From 11144e486cf5ed5c42ba6276d52a1c9dc7879c0c Mon Sep 17 00:00:00 2001 From: Alain Picard Date: Wed, 8 Feb 2017 17:51:50 -0500 Subject: [PATCH 4/6] Added support for new options in running documentation application and documented all options that can be passed in new option file. --- .../.settings/org.eclipse.jdt.core.prefs | 6 +-- .../hu.qgears.gendoc.app/META-INF/MANIFEST.MF | 4 +- .../gendoc/app/GenerateDocApplication.java | 53 +++++++++++++------ 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/plugins/hu.qgears.gendoc.app/.settings/org.eclipse.jdt.core.prefs b/plugins/hu.qgears.gendoc.app/.settings/org.eclipse.jdt.core.prefs index c537b63..0c68a61 100644 --- a/plugins/hu.qgears.gendoc.app/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/hu.qgears.gendoc.app/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,7 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/plugins/hu.qgears.gendoc.app/META-INF/MANIFEST.MF b/plugins/hu.qgears.gendoc.app/META-INF/MANIFEST.MF index 1e2059b..0697fb3 100644 --- a/plugins/hu.qgears.gendoc.app/META-INF/MANIFEST.MF +++ b/plugins/hu.qgears.gendoc.app/META-INF/MANIFEST.MF @@ -8,5 +8,7 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.emf.ecore.xmi;bundle-version="2.7.0", hu.bme.mit.documentation.ecore Bundle-ActivationPolicy: lazy -Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Export-Package: hu.qgears.gendoc.app +Bundle-ClassPath: lib/org.apache.commons.io_2.2.0.v201405211200.jar, + . diff --git a/plugins/hu.qgears.gendoc.app/src/hu/qgears/gendoc/app/GenerateDocApplication.java b/plugins/hu.qgears.gendoc.app/src/hu/qgears/gendoc/app/GenerateDocApplication.java index f902141..90b815d 100644 --- a/plugins/hu.qgears.gendoc.app/src/hu/qgears/gendoc/app/GenerateDocApplication.java +++ b/plugins/hu.qgears.gendoc.app/src/hu/qgears/gendoc/app/GenerateDocApplication.java @@ -24,11 +24,11 @@ * */ public class GenerateDocApplication implements IApplication { - private static final String ARG_FORMAT = "format"; - private static final String ARG_FILTER_FILE = "filterFile"; + private static final String ARG_OPTION_FILE = "optionFile"; private static final String ARG_OUTPUT_FILE = "outputFile"; private static final String ARG_METAMODEL_FILE = "metamodelFile"; + private static final String ARG_NO_CONFIG = "noConfig"; private static IDocGenerator getDocGenerator(String format) throws UnsupportedTypeException{ if("html".contentEquals(format)){ @@ -45,33 +45,55 @@ public Object start(IApplicationContext context) throws Exception { String[] arguments = (String[])context.getArguments().get(IApplicationContext.APPLICATION_ARGS); Options opts = new Options(); - opts.addOption(ARG_METAMODEL_FILE, true, "Path to the .ecore file that is the source of documentation."); + String options = "\nOptions (All defaults to false or unspecified):\n" + + "\tincludeGenericTypes= boolean whether to inclue generic information for types\n" + + "\tincludeSubtypes= boolean whether to inclue a section for subtypes\n" + + "\tincludeRecursiveSupertypes = boolean whether to recursively look for supertypes\n" + + "\tincludeUsedPackages= boolean whether to process used packages (when processing genmodel only)\n" + + "\tfullLatexDocument = boolean whether to create a full Latex document with packages and document tags\n" + + "\tauthorName = name of the author to insert in Latex document (when producing full Latex document)\n" + + "\tfilters = list of | separated packages to filter - no anchors are generated for elements in these packages. Supports regex\n" + + "\tfitleredTypes= list of | separated types (classes) to filter out. Supports regex\n" + + "\tfitleredSubtypes= list of | separated types (classes) to filter out from subtype section. Supports regex\n" + + "\tfitleredUsedPackages= list of | separated packages to filter out from used package processin. Supports regex\n" + + "\tskipOperations = boolean whether to skip the EOperation section\n" + + "\tshowMissingDoc = boolean whether to show tag when encountering missing documentation\n"; + + opts.addOption(ARG_METAMODEL_FILE, true, "Path to the .ecore or .genmodel file that is the source of documentation."); opts.addOption(ARG_OUTPUT_FILE,true,"File where the documentation should be generated."); opts.addOption(ARG_FORMAT,true,"Documentation format. Currently, html and latex are supported."); - opts.addOption(ARG_FILTER_FILE,true,"Optional .properties file where filtered packages are described - no anchors are generated for elements in these packages."); + opts.addOption(ARG_OPTION_FILE,true,"Alternate .properties file where various processing options are described. Default is gendoc.config in same folder as metamodel file" + options); + opts.addOption(ARG_NO_CONFIG,false,"Specify if default config file should be ignored."); CommandLineParser parser = new BasicParser(); CommandLine cli = parser.parse(opts, arguments); HelpFormatter hf = new HelpFormatter(); - if(cli.hasOption(ARG_METAMODEL_FILE) && cli.hasOption(ARG_OUTPUT_FILE) && cli.hasOption(ARG_FORMAT)){ - String metamodelFile = cli.getOptionValue(ARG_METAMODEL_FILE); + File metamodelFile = new File(cli.getOptionValue(ARG_METAMODEL_FILE)); + String metamodelFileName = metamodelFile.getAbsolutePath(); String outputFile = cli.getOptionValue(ARG_OUTPUT_FILE); String format = cli.getOptionValue(ARG_FORMAT); - String filterFile = null; - if(cli.hasOption(ARG_FILTER_FILE)){ - filterFile = cli.getOptionValue(ARG_FILTER_FILE); + File optionFile = null; + + if(cli.hasOption(ARG_OPTION_FILE)){ + String optionFileName = cli.getOptionValue(ARG_OPTION_FILE); + if(optionFileName!=null){ + optionFile = new File(optionFileName); + } } - URI metamodelUri = URI.createFileURI(metamodelFile); + else if (!cli.hasOption(ARG_NO_CONFIG)) { + File opfile = new File(metamodelFile.getParentFile().getAbsolutePath() + File.separatorChar + "ba.docgen"); + if (opfile.exists()) { + optionFile = opfile; + } + } + + URI metamodelUri = URI.createFileURI(metamodelFileName); File output = new File(outputFile); IDocGenerator docGen = getDocGenerator(format); - File filter = null; - if(filterFile!=null){ - filter = new File(filterFile); - } System.out.println("Generating documentation from "+metamodelUri.toString() + " to "+output.toString()+" in format "+format); - UtilDocGenerator.generateDocForEPackage(metamodelUri, output, filter, docGen); + UtilDocGenerator.generateDocForModel(metamodelUri, output, optionFile, docGen); System.out.println("Documentation generation finished without errors."); } else{ @@ -86,5 +108,4 @@ public Object start(IApplicationContext context) throws Exception { public void stop() { } - } From 463ba79dd6b65677e0686d94109624e1e93226de Mon Sep 17 00:00:00 2001 From: Alain Picard Date: Wed, 8 Feb 2017 17:53:08 -0500 Subject: [PATCH 5/6] Full refactoring of gen doc to support many options and the ability to document from the GenModel and not only from the Ecore. Includes options to produce subtypes, use generics, full latex document, etc. --- .../.settings/org.eclipse.jdt.core.prefs | 6 +- .../META-INF/MANIFEST.MF | 6 +- .../generator/ecore/CoreDocGen.xtend | 567 ++++++++++++ .../generator/ecore/DocGenUtil.java | 65 ++ .../ecore/DocGenerationInstance.java | 32 - .../generator/ecore/EPackageDocGen.xtend | 683 +++++++-------- .../generator/ecore/EPackageDocGenHtml.xtend | 817 ++++++++---------- .../generator/ecore/IDocGenerator.java | 14 +- .../generator/ecore/UtilDocGenerator.java | 102 ++- 9 files changed, 1352 insertions(+), 940 deletions(-) create mode 100644 plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/CoreDocGen.xtend create mode 100644 plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/DocGenUtil.java delete mode 100644 plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/DocGenerationInstance.java diff --git a/plugins/hu.bme.mit.documentation.ecore/.settings/org.eclipse.jdt.core.prefs b/plugins/hu.bme.mit.documentation.ecore/.settings/org.eclipse.jdt.core.prefs index f287d53..295926d 100644 --- a/plugins/hu.bme.mit.documentation.ecore/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/hu.bme.mit.documentation.ecore/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,7 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/plugins/hu.bme.mit.documentation.ecore/META-INF/MANIFEST.MF b/plugins/hu.bme.mit.documentation.ecore/META-INF/MANIFEST.MF index dfae0f7..729ec8b 100644 --- a/plugins/hu.bme.mit.documentation.ecore/META-INF/MANIFEST.MF +++ b/plugins/hu.bme.mit.documentation.ecore/META-INF/MANIFEST.MF @@ -7,8 +7,10 @@ Export-Package: hu.bme.mit.documentation.generator.ecore Require-Bundle: org.eclipse.xtext.xbase.lib, org.apache.log4j;bundle-version="1.2.0", org.eclipse.emf.ecore.xmi;bundle-version="2.7.0", - hu.qgears.documentation;bundle-version="1.0.0" -Bundle-RequiredExecutionEnvironment: JavaSE-1.6 + hu.qgears.documentation;bundle-version="1.0.0", + org.eclipse.emf.codegen.ecore, + org.eclipse.emf.ecore +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-Vendor: Budapest University of Technology and Economics, Fault Tolerant Systems Research Group Bundle-ClassPath: lib/markdownpapers-core-1.2.7.jar, . diff --git a/plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/CoreDocGen.xtend b/plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/CoreDocGen.xtend new file mode 100644 index 0000000..a7b8254 --- /dev/null +++ b/plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/CoreDocGen.xtend @@ -0,0 +1,567 @@ +/* Copyright (c) 2010-2012, Abel Hegedus, Istvan Rath and Daniel Varro + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Abel Hegedus - initial API and implementation + * Adam Horvath - Markdown support, escaping fixes + * + *******************************************************************************/ + package hu.bme.mit.documentation.generator.ecore + +import com.google.common.collect.Lists +import java.util.List +import java.util.PropertyResourceBundle +import org.eclipse.emf.codegen.ecore.genmodel.GenModel +import org.eclipse.emf.codegen.ecore.genmodel.GenPackage +import org.eclipse.emf.common.util.URI +import org.eclipse.emf.ecore.EClass +import org.eclipse.emf.ecore.EModelElement +import org.eclipse.emf.ecore.EPackage +import org.eclipse.emf.ecore.EObject +import org.eclipse.emf.codegen.ecore.genmodel.GenEnum +import org.eclipse.emf.codegen.ecore.genmodel.GenDataType +import org.eclipse.emf.ecore.EEnum +import org.eclipse.emf.ecore.EDataType +import org.eclipse.emf.codegen.ecore.genmodel.GenClass +import org.eclipse.emf.ecore.EAttribute +import org.eclipse.emf.ecore.EReference +import org.eclipse.emf.ecore.EOperation +import org.eclipse.emf.ecore.EGenericType +import java.util.ArrayList +import org.eclipse.emf.codegen.ecore.genmodel.GenBase +import org.eclipse.emf.codegen.ecore.genmodel.GenFeature +import hu.qgears.documentation.DocumentationFieldUtils +import org.eclipse.emf.ecore.EClassifier +import java.util.stream.Collectors +import org.eclipse.emf.ecore.ETypeParameter + +/** + * @author Abel Hegedus + * @author Adam Horvath + */ +abstract class CoreDocGen extends DocGenUtil implements IDocGenerator{ + public static final String SKIP_OP = "skipOperations" + public static final String RECURSE_SUPER = "includeRecursiveSupertypes" + public static final String INC_SUBTYPES = "includeSubtypes" + public static final String INC_USED_PKG = "includeUsedPackages" + public static final String FULL_LATEX_DOC = "fullLatexDocument" + public static final String FILTERED_TYPES = "filteredTypes" + public static final String FILTERED_SUBTYPES = "filteredSubtypes" + public static final String FILTERED_USED_PKG = "filteredUsedPackages" + public static final String AUTHOR_NAME = "authorName" + public static final String INC_GENTYPE = "includeGenericTypes" + public static final String SHOW_MISSING_DOC = "showMissingDoc" + + private static String LT + private static String GT + + protected EPackage pckg + protected GenPackage genPkg + protected StringBuilder builder + protected List filter + protected PropertyResourceBundle options + + override generateDocument(StringBuilder sb, EObject root, List filters, PropertyResourceBundle options) { + this.builder = sb + this.filter = Lists::newArrayList(filters) + this.options = options + init + + if (root instanceof GenModel) { + documentGenmodel(root as GenModel) + } + else { + documentAllEPackages(root as EPackage) + } + + generateTail() + } + + def private init(){ + LT = defineLT + GT = defineGT + } + + def private documentGenmodel(GenModel genmodel) { + var genPkg = genmodel.getGenPackages().get(0) + + genPkg.eResource.URI.processHeader + genPkg.documentGenPackages + + if(optionActive(INC_USED_PKG)){ + genmodel.usedGenPackages.forEach[ + if(!isFiltered(optionValue(FILTERED_USED_PKG))){ + documentGenPackages + } + ] + } + } + + def private void documentGenPackages(GenPackage genPkg) { + if(!genPkg.getGenClasses().isEmpty()){ + genPkg.documentGenPackage + } + + genPkg.nestedGenPackages.forEach[ + documentGenPackage + ] + } + + def private documentAllEPackages(EPackage pckg){ + pckg.eResource.URI.processHeader + pckg.documentEPackages + } + + def private void documentEPackages(EPackage pckg){ + if(!pckg.getEClassifiers().isEmpty()){ + pckg.documentEPackage + } + pckg.getESubpackages.forEach[ + documentEPackage + ] + } + + def private documentEPackage(EPackage pckg){ + this.pckg = pckg + + pckg.documentEPackageHeader.appendToBuilder + + pckg.EClassifiers.sortBy[name].forEach[ + if(it instanceof EClass){ + val cls = it as EClass + cls.documentEClassHeader + cls.emitSuperTypes + cls.emitSubTypes + cls.documentEClass("" + escapeLabel(cls.EPackage.nsPrefix+"."+cls.name)) + } + else if(it instanceof EDataType && it instanceof EEnum){ + val eenum = it as EEnum + eenum.documentEEnumHeader.appendToBuilder + } + ] + } + + def private documentGenPackage(GenPackage genPkg) { + this.genPkg = genPkg + + pckg = genPkg.getEcorePackage + pckg.documentEPackageHeader.appendToBuilder + + genPkg.genClassifiers.sortBy[name].forEach[ + if(it instanceof GenClass){ + val gcls = it as GenClass + val cls = gcls.ecoreClass as EClass + + if (!isFiltered(cls, optionValue(FILTERED_TYPES))) { + gcls.documentGenClassHeader + cls.emitSuperTypes + cls.emitSubTypes + gcls.documentGenClass("" + escapeLabel(cls.EPackage.nsPrefix+"."+cls.name)) + } + } + else if(it instanceof GenDataType && it instanceof GenEnum){ + val gen = it as GenEnum + val eenum = gen.ecoreEnum as EEnum + eenum.documentEEnumHeader.appendToBuilder + } + ] + } + + def private documentEClassHeader(EClass cls){ + '''«cls.documentEClassifierHeader»'''.appendToBuilder + cls.documentEClassProperties + } + + def private documentGenClassHeader(GenClass gcls){ + val cls = gcls.ecoreClass as EClass + '''«gcls.documentGenClassifierHeader»'''.appendToBuilder + cls.documentEClassProperties + } + + def private documentEClass(EClass cls, String id) { + if(!cls.EAttributes.empty){ + emitTblHeader("Attributes") + cls.EAttributes.sortBy[name].forEach[ + emitAttrTblRow(id, findGenModelDocumentation(derived)) + ] + emitTblTrailer(cls, "Attributes", "attr") + } + + if(!cls.EReferences.empty){ + //"paragraph".documentHeader("References", cls.EPackage.nsPrefix+"."+cls.name+".ref", null).appendToBuilder + emitTblHeader("References") + cls.EReferences.sortBy[name].forEach[ + emitRefTblRow(id, findGenModelDocumentation(derived)) + ] + emitTblTrailer(cls, "References", "ref") + } + + if(!cls.EOperations.empty){ + emitTblHeader("Operations") + cls.EOperations.sortBy[name].forEach[ + emitOpTblRow(id, findGenModelDocumentation(false)) + ] + emitTblTrailer(cls, "Operations", "op") + } + } + + def private documentGenClass(GenClass gcls, String id) { + val cls = gcls.ecoreClass as EClass + + if(!cls.EAttributes.empty){ + emitTblHeader("Attributes") + + gcls.genFeatures.filter[ecoreFeature instanceof EAttribute].sortBy[name].forEach[ + emitAttrTblRow(ecoreFeature as EAttribute, id, findGenModelDocumentation(derived)) + ] + emitTblTrailer(cls, "Attributes", "attr") + } + + if(!cls.EReferences.empty){ + emitTblHeader("References") + gcls.genFeatures.filter[ecoreFeature instanceof EReference].sortBy[name].forEach[ + emitRefTblRow(ecoreFeature as EReference, id, findGenModelDocumentation(derived)) + ] + emitTblTrailer(cls, "References", "ref") + } + + if(optionActive(SKIP_OP) && !cls.EOperations.empty){ + emitTblHeader("Operations") + gcls.genOperations.sortBy[name].forEach[ + val eop = ecoreOperation as EOperation + emitOpTblRow(eop, id, eop.findGenModelDocumentation(false)) + ] + emitTblTrailer(cls, "Operations", "op") + } + } + + def private emitSuperTypes(EClass cls) { + if (!cls.EGenericSuperTypes.empty){ + var List list = new ArrayList + cls.getAllSuperClasses(list) + + if (!list.empty){ + val plural = if (list.size > 1) '''s''' else '''''' + cls.emitSuperTypeHeader(plural) + emitSuperTypeElements(list).appendToBuilder + emitSuperTypeTrailer + } + } + } + + def protected emitSuperTypeElements(List genTypes) { + genTypes.emitGenTypeListRef + } + + def private emitSubTypes(EClass cls) { + if(optionActive(INC_SUBTYPES) && !isFiltered(cls, optionValue(FILTERED_SUBTYPES))){ + val subTypes = getSubTypes(pckg, cls, true) + if (!subTypes.empty){ + val plural = if (subTypes.size > 1) '''s''' else '''''' + cls.emitSubTypeHeader(plural) + emitSubTypeElements(subTypes).appendToBuilder + emitSubTypeTrailer + } + } + } + + def protected emitSubTypeElements(List subTypes) { + subTypes.emitClassListRef + } + + def protected documentHeader(String sectionClass, String sectionTitle, String shortTitle, String label, EModelElement element) + ''' + «documentHeader(sectionClass, sectionTitle, shortTitle, label)» + + «IF element != null» + «element.findGenModelDocumentation» + «ENDIF» + ''' + + def protected documentHeader(String sectionClass, String sectionTitle, String shortTitle, String label, GenBase element) + ''' + «documentHeader(sectionClass, sectionTitle, shortTitle, label)» + + «IF element != null» + «element.findGenModelDocumentation» + «ENDIF» + ''' + + def protected preparePossibleReference(EGenericType genType){ + val cls = genType.EClassifier + if(cls==null) { + return genType.emitGenTypeInfo + } + val typePckg = cls.EPackage + val typeName = cls.name + if(typePckg != null && filter.findFirst[typePckg.nsURI.contains(it)] == null){ + cls.emitBaseClassRef + } + else { + '''«typeName»''' + } + } + + def private emitClassListRef(List classes) { + val str = new ArrayList + classes.sortBy[name].forEach[ + str.add(emitClassRef) + ] + + str.stream().collect(Collectors.joining(", ")) + } + + def private String emitGenTypeListRef(List genTypes) { + val str = new ArrayList + genTypes.sortBy[EClassifier.name].forEach[ + str.add(emitGenTypeRef) + ] + + str.stream().collect(Collectors.joining(", ")) + } + + def protected String emitClassRef(EClassifier cls) { + var typeInfo = emitBaseClassRef(cls) + + if (optionActive(INC_GENTYPE) && !cls.ETypeParameters.empty){ + typeInfo += emitTypeParamInfo(cls) + } + return typeInfo + } + + def private String emitGenTypeInfo(EGenericType genType) { + val str = new ArrayList + + if (!genType.ETypeArguments.empty) { + genType.ETypeArguments.forEach[ + if (EClassifier != null && EClassifier instanceof EClass) { + str.add(EClassifier.emitClassRef) + } + else if (EClassifier != null && EClassifier instanceof EDataType) { + val dataType = EClassifier as EDataType + str.add('''«dataType.name»''') + } + else if (ETypeParameter != null) { + str.add(ETypeParameter.emitTypeParamRef) + } + ] + } + else if (genType.ETypeParameter != null) { + str.add(genType.ETypeParameter.emitTypeParamRef) + } + else { + val sb = new StringBuilder + sb.append('?') + + if (genType.ELowerBound != null) { + sb.append(" super ") + sb.append(genType.ELowerBound.emitGenTypeRef) + } + else if (genType.EUpperBound != null) { + sb.append(" extends ") + sb.append(genType.EUpperBound.emitGenTypeRef) + } + + str.add('''«sb.toString»''') + } + str.stream().collect(Collectors.joining(", ", LT, GT)) + } + + def private emitTypeParamInfo(EClassifier cls) { + val str = new ArrayList + + cls.ETypeParameters.forEach[ + str.add(emitTypeParamRef) + ] + str.stream().collect(Collectors.joining(", ", LT, GT)) + } + + def private emitGenTypeRef(EGenericType genType){ + var typeInfo = genType.EClassifier.emitBaseClassRef + + if (optionActive(INC_GENTYPE) && !genType.ETypeArguments.empty){ + typeInfo += genType.emitGenTypeInfo + } + return typeInfo + } + + def private emitTypeParamRef(ETypeParameter typeParam) { + val str = new ArrayList + + if (typeParam instanceof EClassifier) { + str.add(emitClassRef(typeParam as EClassifier)) + } + else { + str.add('''«typeParam.name»''') + } + + if (!typeParam.EBounds.empty){ + str.add("extends " + typeParam.EBounds.emitGenTypeListRef) + } + + str.stream().collect(Collectors.joining(" ")) + } + + def protected optionActive(String option){ + var optVal = "" + if (options != null && options.containsKey(option)) { + optVal = options.getString(option) + } + optVal.trim.equals("true") + } + + def protected optionValue(String option){ + var optVal = "" + if (options != null) { + optVal = options.getString(option) + } + return optVal + } + + def protected isFiltered(EClass cls, String key){ + val cname = cls.name + getOptionValues(key).stream.anyMatch[cname.matches(key)] + } + + def protected isFiltered(GenPackage pkg, String key){ + val pname = pkg.getEcorePackage.name + getOptionValues(key).stream.anyMatch[pname.matches(key)] + } + + def protected findAnnotation(EModelElement elem, String source, String key){ + val annotations = elem.EAnnotations + if(annotations != null){ + val ann = annotations.findFirst[it.source == source] + if(ann != null){ + val det = ann.details + if(det != null){ + return det.get(key) + } + } + } + } + + def protected findAnnotation(GenBase elem, String source, String key){ + val annotations = elem.genAnnotations + if(annotations != null && annotations.size > 0){ + val ann = annotations.findFirst[source == source && details.containsKey(key)] + if(ann != null){ + val det = ann.details + if(det != null){ + return det.get(key) + } + } + } + } + + def protected findGenModelDocumentation(EModelElement element){ + element.findGenModelDocumentation(true) + } + + def protected findGenModelDocumentation(EModelElement element, boolean required){ + var doc = findAnnotation(element, DocumentationFieldUtils.GEN_MODEL_PACKAGE_NS_URI, "documentation") + emitDocumentation(doc, required) + } + + def protected findGenModelDocumentation(GenFeature element){ + element.findGenModelDocumentation(true) + } + + def protected findGenModelDocumentation(GenFeature element, boolean required){ + var doc = element.propertyDescription + if (doc == null || doc.empty) { + doc = findAnnotation(element, DocumentationFieldUtils.GEN_MODEL_PACKAGE_NS_URI, "documentation") + } + + emitDocumentation(doc, required) + } + + def protected findGenModelDocumentation(GenBase element){ + element.findGenModelDocumentation(true) + } + + def protected findGenModelDocumentation(GenBase element, boolean required){ + findGenModelDocumentation(element, "documentation", required) + } + + def protected findGenModelInternalDoc(GenBase element, boolean required){ + findGenModelDocumentation(element, "internaldoc", required) + } + + def protected findGenModelDocumentation(GenBase element, String key, boolean required){ + val doc = findAnnotation(element, DocumentationFieldUtils.GEN_MODEL_PACKAGE_NS_URI, key) + emitDocumentation(doc, required) + } + + def protected String ePackageFqName(EPackage pckg){ + var current = pckg + var List list = new ArrayList + var ret = new StringBuilder + while(current!=null){ + list.add(0,current.name) + current = current.eContainer as EPackage + } + var i = 0 + val len = list.size + for(String pElement:list){ + ret.append(pElement) + if(i < len - 1 ){ + ret.append(".") + } + i = i + 1 + } + ret.toString() + } + + def protected void getAllSuperClasses(EClass cls, List list) { + for (EGenericType superCls : cls.EGenericSuperTypes) { + if (!superCls.eIsProxy && !contains(list, superCls)) { + list.add(superCls) + if (optionActive(RECURSE_SUPER)) { + getAllSuperClasses(superCls.EClassifier as EClass, list) + } + } + } + } + + //needed since generic type instances are all different + def private contains(List list, EGenericType type) { + list.stream().anyMatch[EClassifier.equals(type.EClassifier)] + } + + def protected appendToBuilder(CharSequence s){ + builder.append(s) + } + + def String defineLT() + def String defineGT() + + def CharSequence documentEPackageHeader(EPackage pckg) + def CharSequence documentEClassProperties(EClass cls) + def CharSequence documentEClassifierHeader(EClassifier cls) + def CharSequence documentGenClassifierHeader(GenClass gcls) + def CharSequence documentEEnumHeader(EEnum eenum) + + def String emitBaseClassRef(EClassifier cls) + def void emitTblHeader(String title) + def void emitAttrTblRow(EAttribute attr, String id, String doc) + def void emitRefTblRow(EReference ref, String id, String doc) + def void emitOpTblRow(EOperation op, String id, String doc) + def void emitTblTrailer(EClass cls, String title, String type) + def void emitSuperTypeHeader(EClass cls, String plural) + def void emitSuperTypeTrailer() + def void emitSubTypeHeader(EClass cls, String plural) + def void emitSubTypeTrailer() + def CharSequence documentHeader(String sectionClass, String sectionTitle, String shortTitle, String label) + + def CharSequence escapeText(String text) + def CharSequence escapeLabel(String text) + def String emitDocumentation(String doc, boolean required) + + def void generateTail() + + def void processHeader(URI pkgURI) +} diff --git a/plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/DocGenUtil.java b/plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/DocGenUtil.java new file mode 100644 index 0000000..3ca2317 --- /dev/null +++ b/plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/DocGenUtil.java @@ -0,0 +1,65 @@ +package hu.bme.mit.documentation.generator.ecore; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; + +public class DocGenUtil { + public static List getSubTypes(final EPackage pkg, final EClass supertype, + boolean concreteTypesOnly) { + EPackage rootPkg = getRootPackage(pkg); + List eClasses = new ArrayList<>(getAllEclasses(rootPkg)); + final List result = eClasses.stream() + .filter(eClass -> supertype.isSuperTypeOf(eClass) && + eClass != supertype && + (!concreteTypesOnly || (!eClass.isAbstract() && !eClass.isInterface()))) + .collect(Collectors.toList()); + return result; + } + + public static List getAllEclasses(final EPackage rootPkg) { + List eClasses = new ArrayList<>(); + for (final EPackage pkg : rootPkg.getESubpackages()) { + eClasses.addAll(getEclasses(pkg)); + eClasses.addAll(getAllEclasses(pkg)); + } + + return eClasses; + } + + public static List getEclasses(final EPackage pkg) { + return pkg.getEClassifiers().stream() + .filter(c -> c instanceof EClass) + .map(c -> (EClass)c) + .collect(Collectors.toList()); + } + + public static EPackage getRootPackage(final EPackage pkg) { + EPackage superPkg = pkg; + + while (superPkg.getESuperPackage() != null) { + superPkg = superPkg.getESuperPackage(); + } + + return superPkg; + } + + public static List getOptionValues(String key) { + List values = new ArrayList<>(); + + if(key!=null){ + String [] array = key.split("\\|"); + for (int i = 0; i < array.length; i++) { + String value = array[i]; + if(value != null && !value.isEmpty()){ + values.add(value); + } + } + } + + return values; + } +} diff --git a/plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/DocGenerationInstance.java b/plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/DocGenerationInstance.java deleted file mode 100644 index ea648ec..0000000 --- a/plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/DocGenerationInstance.java +++ /dev/null @@ -1,32 +0,0 @@ -package hu.bme.mit.documentation.generator.ecore; - -import java.util.ArrayList; - -import org.eclipse.emf.ecore.EPackage; - -/** - * Class that represents the process of a single documentation generation. - * - * @author adam - * - */ -public class DocGenerationInstance{ - - private boolean genHeader = true; - - public void doGenerateAllSubpackages(IDocGenerator docGen, StringBuilder sb, EPackage pckg, ArrayList filter) { - generateAll(docGen, sb, pckg, filter); - docGen.generateTail(); - } - private void generateAll(IDocGenerator docGen, StringBuilder sb, EPackage pckg, ArrayList filter){ - if(!pckg.getEClassifiers().isEmpty()){ - docGen.documentEPackage(sb, pckg, filter,genHeader); - //the first, non-empty package is found, no need to generate headers for the others - genHeader = false; - } - for (EPackage subpck : pckg.getESubpackages()) { - generateAll(docGen, sb, subpck, filter); - } - } - -} \ No newline at end of file diff --git a/plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/EPackageDocGen.xtend b/plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/EPackageDocGen.xtend index aed8bb6..856dd12 100644 --- a/plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/EPackageDocGen.xtend +++ b/plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/EPackageDocGen.xtend @@ -11,18 +11,15 @@ *******************************************************************************/ package hu.bme.mit.documentation.generator.ecore -import com.google.common.collect.Lists import java.io.Reader import java.io.StringReader -import java.util.ArrayList import java.util.GregorianCalendar -import java.util.List +import org.eclipse.emf.common.util.URI import org.eclipse.emf.ecore.EAttribute import org.eclipse.emf.ecore.EClass import org.eclipse.emf.ecore.EClassifier import org.eclipse.emf.ecore.EDataType import org.eclipse.emf.ecore.EEnum -import org.eclipse.emf.ecore.EModelElement import org.eclipse.emf.ecore.ENamedElement import org.eclipse.emf.ecore.EOperation import org.eclipse.emf.ecore.EPackage @@ -31,153 +28,108 @@ import org.eclipse.emf.ecore.EStructuralFeature import org.eclipse.emf.ecore.ETypedElement import org.tautua.markdownpapers.ast.Document import org.tautua.markdownpapers.parser.Parser +import org.eclipse.emf.codegen.ecore.genmodel.GenClass +import java.util.List +import org.eclipse.emf.ecore.EGenericType /** * @author Abel Hegedus * @author Adam Horvath */ -class EPackageDocGen implements IDocGenerator{ - private EPackage pckg - private StringBuilder builder - private List filter - private boolean floatTables +class EPackageDocGen extends CoreDocGen implements IDocGenerator { + private boolean floatTables = false //is never changed, left there anyway. - override documentEPackage(StringBuilder sb, EPackage pckg, List nameRefFilter, boolean genHeader){ - this.floatTables = false; - this.builder = sb - this.pckg = pckg - this.filter = Lists::newArrayList(nameRefFilter) - - val gc = new GregorianCalendar() - val now = gc.getTime().toString() - if(genHeader){ - "% This file was created using the TeX documentation generator.\n".appendToBuilder - - val create = "% Creation date: " + now + "\n" - create.appendToBuilder - } - - pckg.documentEPackageHeader.appendToBuilder - - //pckg.EClassifiers.sortBy[if(it instanceof EClass){(it as EClass).ESuperTypes.size} else {0}].forEach[ - pckg.EClassifiers.sortBy[name].forEach[ - + override defineLT() { + '''<''' + } + + override defineGT() { + '''>''' + } - if(it instanceof EClass){ - - val cls = it as EClass + override emitSuperTypeHeader(EClass cls, String plural) { + ''' + «IF cls.interface || cls.^abstract» + \\ + «ENDIF» + \textbf{Supertype«plural»: }'''.appendToBuilder + } + + override emitSuperTypeElements(List genTypes) { + ''' + \texttt{«super.emitSuperTypeElements(genTypes)»} + ''' + } + + override emitSuperTypeTrailer() { + ''''''.appendToBuilder + } + + override emitSubTypeHeader(EClass cls, String plural) { + ''' + «IF !cls.EGenericSuperTypes.empty» + \\ + «ENDIF» + \textbf{Subtype«plural»: }'''.appendToBuilder + } + + override emitSubTypeElements(List subTypes) { + ''' + \texttt{«super.emitSubTypeElements(subTypes)»} + ''' + } + + override emitSubTypeTrailer() { + ''''''.appendToBuilder + } + + override emitTblHeader(String title) { + ''' + \begin{table}[«getTableFloat»] + \footnotesize + \begin{tabularx}{\textwidth}{|c| p{4 cm} | X |} + \hline + \multicolumn{3}{|c|}{\textbf{«title»}} \\ + \hline + Name & Properties & Documentation \\ \hline \hline + '''.appendToBuilder + } + + override emitTblTrailer(EClass cls, String title, String type) { + ''' + \caption{«title» of the «escapeText(cls.name)» EClass} + \end{tabularx} + \label{«escapeLabel(cls.EPackage.nsPrefix+"."+cls.name+"." + type)»} + \end{table} + '''.appendToBuilder + } - cls.documentEClassHeader.appendToBuilder - if(!cls.EAttributes.empty){ - //"textbf".documentHeader("Attributes", cls.EPackage.nsPrefix+"."+cls.name+".attr", null).appendToBuilder - ''' - \begin{table}[«getTableFloat»] - \footnotesize - \begin{tabularx}{\textwidth}{|c| p{4 cm} | X |} - \hline - \multicolumn{3}{|c|}{\textbf{Attributes}} \\ - \hline - Name & Properties & Documentation \\ \hline \hline - '''.appendToBuilder - cls.EAttributes.sortBy[name].forEach[ - documentEAttributeHeader.appendToBuilder - ''' & '''.appendToBuilder - findGenModelDocumentation(derived).appendToBuilder - '''\\ \hline - '''.appendToBuilder - ] - ''' - \end{tabularx} - \caption{Attributes of the «escapeText(cls.name)» EClass} - \label{«escapeLabel(cls.EPackage.nsPrefix+"."+cls.name+".attr")»} - \end{table} - '''.appendToBuilder - - } - - - if(!cls.EReferences.empty){ - //"paragraph".documentHeader("References", cls.EPackage.nsPrefix+"."+cls.name+".ref", null).appendToBuilder - ''' - \begin{table}[«getTableFloat»] - \footnotesize - \begin{tabularx}{\textwidth}{|c| p{4 cm} | X |} - \hline - \multicolumn{3}{|c|}{\textbf{References}} \\ - \hline - Name & Properties & Documentation \\ \hline \hline - '''.appendToBuilder - cls.EReferences.sortBy[name].forEach[ - documentEReferenceHeader.appendToBuilder - ''' & '''.appendToBuilder - findGenModelDocumentation(derived).appendToBuilder - '''\\ \hline - '''.appendToBuilder - ] - ''' - \end{tabularx} - \caption{References of the «escapeText(cls.name)» EClass} - \label{«escapeLabel(cls.EPackage.nsPrefix+"."+cls.name+".ref")»} - \end{table} - '''.appendToBuilder - - } - - if(!cls.EOperations.empty){ - //"paragraph".documentHeader("Operations", cls.EPackage.nsPrefix+"."+cls.name+".op", null).appendToBuilder - ''' - \begin{table}[«getTableFloat»] - \small - \begin{tabularx}{\textwidth}{|c| p{4 cm} | X |} - \hline - \multicolumn{3}{|c|}{\textbf{Operations}} \\ - \hline - Name & Properties & Documentation \\ \hline \hline - '''.appendToBuilder - cls.EOperations.sortBy[name].forEach[ - documentEOperationHeader.appendToBuilder - ''' & '''.appendToBuilder - findGenModelDocumentation(false).appendToBuilder - '''\\ \hline - '''.appendToBuilder - ] - ''' - \end{tabularx} - \caption{Operations of the «escapeText(cls.name)» EClass} - \label{«escapeLabel(cls.EPackage.nsPrefix+"."+cls.name+".op")»} - \end{table} - '''.appendToBuilder - - } - - //if(cls.EOperations.size + cls.EStructuralFeatures.size > 2){ - // '''\clearpage'''.appendToBuilder - //} - - } else if(it instanceof EDataType){ - if(it instanceof EEnum){ - val eenum = it as EEnum - eenum.documentEEnumHeader.appendToBuilder - } - } - - ] - - } - def getTableFloat() { - if(floatTables){ - '''!ht''' - }else{ - '''H''' - } + override emitAttrTblRow(EAttribute attr, String id, String doc) { + attr.documentEAttributeHeader(id).appendToBuilder + ''' & '''.appendToBuilder + doc.appendToBuilder + '''\\ \hline + '''.appendToBuilder + } + + override emitRefTblRow(EReference ref, String id, String doc) { + ref.documentEReferenceHeader(id).appendToBuilder + ''' & '''.appendToBuilder + doc.appendToBuilder + '''\\ \hline + '''.appendToBuilder + } + + override emitOpTblRow(EOperation op, String id, String doc) { + op.documentEOperationHeader(id).appendToBuilder + ''' & '''.appendToBuilder + doc.appendToBuilder + '''\\ \hline + '''.appendToBuilder } - - def private appendToBuilder(CharSequence s){ - builder.append(s) - } - - def private documentEPackageHeader(EPackage pckg) + //empty line in here is important!! + override documentEPackageHeader(EPackage pckg) ''' «val packageName = ePackageFqName(pckg)» «val title = "The \\textsc{" + pckg.name + "} metamodel"» @@ -186,256 +138,209 @@ class EPackageDocGen implements IDocGenerator{ «documentProperty("Namespace Prefix", '''«escapeText(pckg.nsPrefix)»''')» «documentProperty("Namespace URI", '''«pckg.nsURI»''')» - ''' - def private String ePackageFqName(EPackage pckg) - { - var current = pckg; - var List list = new ArrayList; - var ret = new StringBuilder; - while(current!=null){ - list.add(0,current.name); - current = current.eContainer as EPackage; - } - var i = 0; - val len = list.size; - for(String pElement:list){ - ret.append(pElement); - if(i < len - 1 ){ - ret.append("."); - } - i = i + 1; - } - ret.toString(); - } - def private documentEClassifierHeader(EClassifier cls) - ''' - «documentHeader("subsection", cls.name, cls.name, cls.EPackage.nsPrefix+"."+cls.name, cls)» - ''' + override documentEClassifierHeader(EClassifier cls) + ''' + «documentHeader("subsection", emitClassRef(cls), cls.name, cls.EPackage.nsPrefix+"."+cls.name, cls)» + ''' + override documentGenClassifierHeader(GenClass gcls) { + ''' + «documentHeader("subsection", emitClassRef(gcls.ecoreClass), gcls.name, gcls.ecoreClass.EPackage.nsPrefix+"."+gcls.name, gcls)» + ''' + } + def private documentEDataTypeHeader(EDataType dt) - ''' - «dt.documentEClassifierHeader» - ''' + ''' + «dt.documentEClassifierHeader» + ''' - def private documentEEnumHeader(EEnum eenum) - ''' - «eenum.documentEDataTypeHeader» - \begin{table}[«getTableFloat»] - \footnotesize - \begin{tabularx}{\textwidth}{| c | c | X |} - \hline - \multicolumn{3}{|c|}{\textbf{Literals}} \\ - \hline - Name & Value & Documentation \\ \hline \hline - «FOR literal : eenum.ELiterals» - \texttt{«escapeText(literal.literal)»} & «literal.value» & - «literal.findGenModelDocumentation(false)» \\ \hline - «ENDFOR» - \end{tabularx} - \caption{Literals of the «escapeText(eenum.name)» EEnum} - \label{«escapeLabel(eenum.EPackage.nsPrefix+"."+eenum.name+".lit")»} - \end{table} - ''' + override documentEEnumHeader(EEnum eenum) + ''' + «eenum.documentEDataTypeHeader» + \begin{table}[«getTableFloat»] + \footnotesize + \begin{tabularx}{\textwidth}{| c | c | X |} + \hline + \multicolumn{3}{|c|}{\textbf{Literals}} \\ + \hline + Name & Value & Documentation \\ \hline \hline + «FOR literal : eenum.ELiterals» + \texttt{«escapeText(literal.literal)»} & «literal.value» & + «literal.findGenModelDocumentation(false)» \\ \hline + «ENDFOR» + \caption{Literals of the «escapeText(eenum.name)» EEnum} + \end{tabularx} + \label{«escapeLabel(eenum.EPackage.nsPrefix+"."+eenum.name+".lit")»} + \end{table} + ''' - def private documentEClassHeader(EClass cls) - ''' - «cls.documentEClassifierHeader» - - «IF cls.interface» - \paragraph{EClass properties:} \hspace{0pt} \\ \indent - \textbf{Interface} - «ENDIF» - «IF cls.^abstract» - «IF cls.interface» - , - «ELSE» - \paragraph{EClass properties:} \hspace{0pt} \\ \indent - «ENDIF» - \textbf{Abstract} - «ENDIF» - «IF !cls.ESuperTypes.empty» - «IF cls.interface || cls.^abstract» - \\ \indent - «ELSE» - \paragraph{EClass properties:} \hspace{0pt} \\ \indent - «ENDIF» - \textbf{Supertypes: } - «FOR st : cls.ESuperTypes SEPARATOR ", "» - \texttt{«st.preparePossibleReference»} - «ENDFOR» - «ENDIF» - ''' - - def private documentENamedElement(ENamedElement elem, String color) - ''' - \texttt{«IF color != null»\color{«color»}{«ENDIF»«escapeText(elem.name)»«IF color != null»}«ENDIF»} - ''' + override documentEClassProperties(EClass cls) { + ''' + «IF cls.interface» + \paragraph{EClass properties:} \hspace{0pt} \\ \indent + \textbf{Interface} + «ENDIF» + «IF cls.^abstract» + «IF cls.interface» + , + «ELSE» + \paragraph{EClass properties:} \hspace{0pt} \\ \indent + «ENDIF» + \textbf{Abstract} + «ENDIF» + '''.appendToBuilder + } + + def private documentENamedElement(ENamedElement elem, String parentId, String color) + ''' + \texttt{«IF color != null»\color{«color»}{«ENDIF»«escapeText(elem.name)»«IF color != null»}«ENDIF»} + ''' //(«typePckg.nsURI») // <«typePckg.name»> - def private documentETypedElement(ETypedElement elem, String color) - ''' - «elem.documentENamedElement(color)» & - «documentProperty("T", elem.preparePossibleReference)» - \newline - \textbf{Cardinality:} [«elem.lowerBound»..«IF elem.upperBound == -1»*«ELSE»«elem.upperBound»«ENDIF»] - «IF !elem.ordered» - \newline - \textbf{Unordered} - «ENDIF» - «IF !elem.unique» - \newline - \textbf{Not unique} - «ENDIF»''' + def private documentETypedElement(ETypedElement elem, String parentId, String color) + ''' + «elem.documentENamedElement(parentId, color)» & + «documentProperty("T", elem.preparePossibleReference)» + \newline + \textbf{Cardinality:} [«elem.lowerBound»..«IF elem.upperBound == -1»*«ELSE»«elem.upperBound»«ENDIF»] + «IF !elem.ordered» + \newline + \textbf{Unordered} + «ENDIF» + «IF !elem.unique» + \newline + \textbf{Not unique} + «ENDIF»''' def private preparePossibleReference(ETypedElement elem){ if(elem.EGenericType != null){ - elem.EGenericType.EClassifier.preparePossibleReference + elem.EGenericType.preparePossibleReference } else { '''\textsc{\color{red}{MISSING TYPE!}}''' } } - def private preparePossibleReference(EClassifier cls){ - val typePckg = cls.EPackage - val typeName = cls.name - - if(typePckg != null && filter.findFirst[typePckg.nsURI.contains(it)] != null){ - '''\nameref{«escapeLabel(typePckg.nsPrefix+ "." + typeName)»}''' - } else { - '''«typeName»''' - } - } - - def private documentEStructuralFeatureHeader(EStructuralFeature feat) - ''' - «IF feat.derived» - «feat.documentETypedElement("blue")» - «ELSE» - «feat.documentETypedElement(null)» - «ENDIF» - «IF !feat.changeable» - \newline - \textbf{Non-changeable} - «ENDIF» - «IF feat.volatile» - \newline - \textbf{Volatile} - «ENDIF» - «IF feat.transient» - \newline - \textbf{Transient} - «ENDIF» - «IF feat.unsettable» - \newline - \textbf{Unsettable} - «ENDIF» - «IF feat.defaultValueLiteral != null» - \newline - «documentProperty("Default", escapeText(feat.defaultValueLiteral))» - «ENDIF» - «IF feat.derived» - «val fqn = findAnnotation(feat, "org.eclipse.viatra2.emf.incquery.derived.feature", "patternFQN")» - \newline - \textbf{Derived} - «IF fqn != null» - %\newline - %(Query: «fqn.replace("hu.bme.mit.transima.models.","").replace(".",".\\allowbreak ")») - «ELSE» - \newline - \textsc{\color{red}{MISSING DEFINITION!}} - «ENDIF» - «ENDIF» - ''' - - def private documentEAttributeHeader(EAttribute attr) - ''' - «attr.documentEStructuralFeatureHeader» - «IF attr.ID» - \newline - \textbf{Identifier} - «ENDIF» - ''' + def private documentEStructuralFeatureHeader(EStructuralFeature feat, String parentId) + ''' + «IF feat.derived» + «feat.documentETypedElement(parentId, "blue")» + «ELSE» + «feat.documentETypedElement(parentId, null)» + «ENDIF» + «IF !feat.changeable» + \newline + \textbf{Non-changeable} + «ENDIF» + «IF feat.volatile» + \newline + \textbf{Volatile} + «ENDIF» + «IF feat.transient» + \newline + \textbf{Transient} + «ENDIF» + «IF feat.unsettable» + \newline + \textbf{Unsettable} + «ENDIF» + «IF feat.defaultValueLiteral != null» + \newline + «documentProperty("Default", escapeText(feat.defaultValueLiteral))» + «ENDIF» + «IF feat.derived» + «val fqn = findAnnotation(feat, "org.eclipse.viatra2.emf.incquery.derived.feature", "patternFQN")» + \newline + \textbf{Derived} + «IF fqn != null» + %\newline + %(Query: «fqn.replace("hu.bme.mit.transima.models.","").replace(".",".\\allowbreak ")») + «ELSE» + \newline + \textsc{\color{red}{MISSING DEFINITION!}} + «ENDIF» + «ENDIF» + ''' - def private documentEReferenceHeader(EReference ref) - ''' - «ref.documentEStructuralFeatureHeader» - «IF ref.containment» - \newline - \textbf{Containment} - «ENDIF» - «IF ref.container» - \newline - \textbf{Container} - «ENDIF» - «IF ref.EOpposite != null» - \newline - «documentProperty("Op", ref.EOpposite.name)» - «ENDIF» - ''' - //ref.EOpposite.EContainingClass.preparePossibleReference+".\\allowbreak "+ + def private documentEAttributeHeader(EAttribute attr, String parentId) + ''' + «attr.documentEStructuralFeatureHeader(parentId)» + «IF attr.ID» + \newline + \textbf{Identifier} + «ENDIF» + ''' - def private documentEOperationHeader(EOperation op) - ''' - «op.documentETypedElement(null)» - «IF op.EType != null» - %\newline - %\textbf{Returns:} - %«op.preparePossibleReference»[«op.lowerBound»..«IF op.upperBound == ETypedElement::UNBOUNDED_MULTIPLICITY»*«ELSE»«op.upperBound»«ENDIF»] - «ENDIF» - «IF !op.EParameters.empty» - \newline - \textbf{Parameters:} - \begin{itemize} - «FOR param : op.EParameters» - \item «param.preparePossibleReference»[«param.lowerBound»..«IF param.upperBound == ETypedElement::UNBOUNDED_MULTIPLICITY»*«ELSE»«param.upperBound»«ENDIF»] \texttt{«escapeText(param.name)»} - «ENDFOR» - \end{itemize} - «ENDIF» - ''' + def private documentEReferenceHeader(EReference ref, String parentId) + ''' + «ref.documentEStructuralFeatureHeader(parentId)» + «IF ref.containment» + \newline + \textbf{Containment} + «ENDIF» + «IF ref.container» + \newline + \textbf{Container} + «ENDIF» + «IF ref.EOpposite != null» + \newline + «documentProperty("Op", ref.EOpposite.name)» + «ENDIF» + ''' + //ref.EOpposite.EContainingClass.preparePossibleReference+".\\allowbreak "+ + def private documentEOperationHeader(EOperation op, String parentId) + ''' + «op.documentETypedElement(parentId, null)» + «IF op.EType != null» + %\newline + %\textbf{Returns:} + %«op.preparePossibleReference»[«op.lowerBound»..«IF op.upperBound == ETypedElement::UNBOUNDED_MULTIPLICITY»*«ELSE»«op.upperBound»«ENDIF»] + «ENDIF» + «IF !op.EParameters.empty» + \newline + \textbf{Parameters:} + \begin{itemize} + «FOR param : op.EParameters» + \item «param.preparePossibleReference»[«param.lowerBound»..«IF param.upperBound == ETypedElement::UNBOUNDED_MULTIPLICITY»*«ELSE»«param.upperBound»«ENDIF»] \texttt{«escapeText(param.name)»} + «ENDFOR» + \end{itemize} + «ENDIF» + ''' + def private documentProperty(CharSequence key, CharSequence value) - ''' - \textbf{«key»:} \texttt{«value»} - ''' + ''' + \textbf{«key»:} \texttt{«value»} + ''' - def private documentHeader(String sectionClass, String sectionTitle, String shortTitle, String label, EModelElement element) - ''' - \«sectionClass»[«escapeText(shortTitle)»]{«escapeText(sectionTitle)»} - \label{«escapeLabel(label)»} + override documentHeader(String sectionClass, String sectionTitle, String shortTitle, String label) + ''' + \«sectionClass»[«escapeText(shortTitle)»]{«escapeText(sectionTitle)»} + \label{«escapeLabel(label)»} + ''' - «IF element != null» - «element.findGenModelDocumentation» - «ENDIF» - ''' - - def private escapeText(String text){ + override escapeText(String text){ '''«text.replaceAll("_","\\\\_").replaceAll("%","\\\\%")»''' } - def private escapeLabel(String text){ + override escapeLabel(String text){ '''«text.replaceAll("_","").replaceAll("\\.","")»''' } - - def private findGenModelDocumentation(EModelElement element){ - element.findGenModelDocumentation(true) - } - - def private findGenModelDocumentation(EModelElement element, boolean required){ - val doc = findAnnotation(element, "http://www.eclipse.org/emf/2002/GenModel", "documentation") + + override emitDocumentation(String doc, boolean required){ if(doc!=null){ - val Reader docReader = new StringReader(doc); - val Parser parser = new Parser(docReader); + val Reader docReader = new StringReader(doc) + val Parser parser = new Parser(docReader) - val Document markdownDoc = parser.parse(); - val latexVisitor = new MarkdownToLatexVisitor(); - markdownDoc.accept(latexVisitor); - return latexVisitor.latexString; + val Document markdownDoc = parser.parse() + val latexVisitor = new MarkdownToLatexVisitor() + markdownDoc.accept(latexVisitor) + return latexVisitor.latexString } else { - if(required){ + if(optionActive(SHOW_MISSING_DOC) && required){ return '''\textsc{\color{red}{Missing Documentation!}}''' } else { return '''''' @@ -443,21 +348,53 @@ class EPackageDocGen implements IDocGenerator{ } } - def private findAnnotation(EModelElement elem, String source, String key){ - val annotations = elem.EAnnotations - if(annotations != null){ - val ann = annotations.findFirst[it.source == source] - if(ann != null){ - val det = ann.details - if(det != null){ - return det.get(key) - } - } - } - } - + override emitBaseClassRef(EClassifier cls) { + '''«escapeLabel(cls.name)»''' +// '''\nameref{«escapeLabel(cls.EPackage.nsPrefix+ "." + cls.name)»}''' + } + + override processHeader(URI pkgURI) { + val gc = new GregorianCalendar() + val now = gc.getTime().toString() + + "% This file was created using the TeX documentation generator.\n".appendToBuilder + val create = "% Creation date: " + now + "\n" + create.appendToBuilder + + ''' + «IF optionActive(FULL_LATEX_DOC)» +\documentclass{article} +\usepackage[hypertex]{hyperref} +\usepackage{url} +\usepackage{times} +\usepackage{ltablex} +\usepackage{float} +\usepackage{courier} +\usepackage{color} +\usepackage{lmodern} + +\title{Metamodel Documentation («pkgURI»)} +\date{«now»} +\author{«optionValue(AUTHOR_NAME)»} + +\begin{document} + «ENDIF» + '''.appendToBuilder + } + override generateTail() { - //not required for latex documents + ''' + «IF optionActive(FULL_LATEX_DOC)» + \end{document} + «ENDIF» + '''.appendToBuilder } + def getTableFloat() { + if(floatTables){ + '''!ht''' + }else{ + '''H''' + } + } } diff --git a/plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/EPackageDocGenHtml.xtend b/plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/EPackageDocGenHtml.xtend index ccaef64..4caee13 100644 --- a/plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/EPackageDocGenHtml.xtend +++ b/plugins/hu.bme.mit.documentation.ecore/src/hu/bme/mit/documentation/generator/ecore/EPackageDocGenHtml.xtend @@ -11,12 +11,10 @@ *******************************************************************************/ package hu.bme.mit.documentation.generator.ecore -import com.google.common.collect.Lists import java.io.Reader import java.io.StringReader import java.util.ArrayList import java.util.GregorianCalendar -import java.util.List import org.eclipse.emf.ecore.EAttribute import org.eclipse.emf.ecore.EClass import org.eclipse.emf.ecore.EClassifier @@ -32,35 +30,357 @@ import org.eclipse.emf.ecore.ETypedElement import org.tautua.markdownpapers.ast.Document import org.tautua.markdownpapers.parser.Parser import hu.qgears.documentation.DocumentationFieldUtils +import org.eclipse.emf.common.util.URI +import org.eclipse.emf.codegen.ecore.genmodel.GenClass +import java.util.stream.Collectors /** * @author Abel Hegedus * @author Adam Horvath * */ -class EPackageDocGenHtml implements IDocGenerator{ - private EPackage pckg - private StringBuilder builder - private List filter +class EPackageDocGenHtml extends CoreDocGen implements IDocGenerator{ +// if (!cls.ESuperTypes.empty){ +// var List list = new ArrayList; +// getAllSuperClassesRecursively(cls, list); +// list.sortBy[name].forEach[ +// val superCls = it as EClass +// val id = escapeLabel(cls.EPackage.nsPrefix+"."+cls.name) + "." + escapeLabel(superCls.EPackage.nsPrefix+"."+superCls.name); +// '''
'''.appendToBuilder +// '''Supertype: «superCls.name»'''.appendToBuilder +// ''' [show]'''.appendToBuilder +// ''''''.appendToBuilder +// '''
'''.appendToBuilder +// ] +// } + + override defineLT() { + '''<''' + } + + override defineGT() { + '''>''' + } + + override emitSuperTypeHeader(EClass cls, String plural) { + '''

Supertype«plural»:'''.appendToBuilder + } + + override emitSuperTypeTrailer() { + '''

'''.appendToBuilder + } + + override emitSubTypeHeader(EClass cls, String plural) { + '''

Subtype«plural»:'''.appendToBuilder + } + + override emitSubTypeTrailer() { + '''

'''.appendToBuilder + } + + override emitTblHeader(String title) { + ''' + + + + + + + + + + '''.appendToBuilder + } + + override emitTblTrailer(EClass cls, String title, String type) { + ''' +
«title»
Name
Properties
Documentation
+ «anchorDef(cls.EPackage.nsPrefix+"."+cls.name+"." + type,"")» + '''.appendToBuilder + } + + override emitAttrTblRow(EAttribute attr, String id, String doc) { + ''''''.appendToBuilder + attr.documentEAttributeHeader(id).appendToBuilder + ''' '''.appendToBuilder + ''''''.appendToBuilder + doc.appendToBuilder + ''' + '''.appendToBuilder + } + + override emitRefTblRow(EReference ref, String id, String doc) { + ''''''.appendToBuilder + ref.documentEReferenceHeader(id).appendToBuilder + ''' + + '''.appendToBuilder + doc.appendToBuilder + ''' + '''.appendToBuilder + } + + override emitOpTblRow(EOperation op, String id, String doc) { + ''''''.appendToBuilder + op.documentEOperationHeader(id).appendToBuilder + ''' '''.appendToBuilder + doc.appendToBuilder + ''' + '''.appendToBuilder + } + + override documentEPackageHeader(EPackage pckg) + ''' + «val packageName = ePackageFqName(pckg)» + «val title = "" + packageName + " package"» + «documentHeader("h1", title, packageName, pckg.nsPrefix, pckg)» +
EPackage properties:
+ «documentProperty("Namespace Prefix", '''«escapeText(pckg.nsPrefix)»''')» + «documentProperty("Namespace URI", '''«pckg.nsURI»''')» + ''' + + override documentEClassifierHeader(EClassifier cls) + ''' + «documentHeader("h2", emitClassRef(cls), cls.name, cls.EPackage.nsPrefix+"."+cls.name, cls)» + ''' + + override documentGenClassifierHeader(GenClass gcls) + ''' + «documentHeader("h2", emitClassRef(gcls.ecoreClass), gcls.name, gcls.ecoreClass.EPackage.nsPrefix+"."+gcls.name, gcls)» + ''' - override documentEPackage(StringBuilder sb, EPackage pckg, List nameRefFilter, boolean genHeader){ - this.builder = sb - this.pckg = pckg - this.filter = Lists::newArrayList(nameRefFilter) - + def private documentEDataTypeHeader(EDataType dt) + ''' + «dt.documentEClassifierHeader» + ''' + + override documentEEnumHeader(EEnum eenum) + ''' + «eenum.documentEDataTypeHeader» + + + + + + + + + + «FOR literal : eenum.ELiterals» + + + + + + «ENDFOR» +
Literals
Name
Value
Documentation
+ «escapeText(literal.literal)» + + «literal.value» + + «literal.findGenModelDocumentation(false)» +
+ «anchorDef(eenum.EPackage.nsPrefix+"."+eenum.name+".lit","")» + ''' + + override documentEClassProperties(EClass cls){ + val str = new ArrayList + + if(cls.isInterface()){ + str.add('''Interface''') + } + + if(cls.isAbstract()){ + str.add('''Abstract''') + } + + if (!str.empty) { + str.stream().collect(Collectors.joining(", ", + '''
EClass properties:
''', + '''
''')).appendToBuilder + } + } + + def private documentENamedElement(ENamedElement elem, String parentId, String color) + ''' +
«IF color != null»
«ENDIF»«escapeText(elem.name)»«IF color != null»
«ENDIF»
+ ''' + + //(«typePckg.nsURI») + // <«typePckg.name»> + def private documentETypedElement(ETypedElement elem, String parentId, String color) + ''' + «elem.documentENamedElement(parentId, color)» + «documentProperty("T", elem.preparePossibleReference)» +
Cardinality: [«elem.lowerBound»..«IF elem.upperBound == -1»*«ELSE»«elem.upperBound»«ENDIF»]
+ «IF !elem.ordered» +
Unordered
+ «ENDIF» + «IF !elem.unique» +
Not unique
+ «ENDIF»''' + + def private preparePossibleReference(ETypedElement elem){ + if(elem.EGenericType != null){ + elem.EGenericType.preparePossibleReference + } else { + '''
MISSING TYPE elem!
''' + } + } + + def private documentEStructuralFeatureHeader(EStructuralFeature feat, String parentId) + ''' + «IF feat.derived» + «feat.documentETypedElement(parentId, "blue")» + «ELSE» + «feat.documentETypedElement(parentId, null)» + «ENDIF» + «IF !feat.changeable» +
Non-changeable
+ «ENDIF» + «IF feat.volatile» +
Volatile
+ «ENDIF» + «IF feat.transient» +
Transient
+ «ENDIF» + «IF feat.unsettable» +
Unsettable
+ «ENDIF» + «IF feat.defaultValueLiteral != null» + «documentProperty("Default", feat.defaultValueLiteral.escapeText)» + «ENDIF» + «IF feat.derived» +
Derived
+ «ENDIF» + ''' + + def private documentEAttributeHeader(EAttribute attr, String parentId) + ''' + «attr.documentEStructuralFeatureHeader(parentId)» + «IF attr.ID» +
Identifier
+ «ENDIF» + ''' + + def private documentEReferenceHeader(EReference ref, String parentId) + ''' + «ref.documentEStructuralFeatureHeader(parentId)» + «IF ref.containment» +
Containment
+ «ENDIF» + «IF ref.container» +
Container
+ «ENDIF» + «IF ref.EOpposite != null» + «documentProperty("Op", ref.EOpposite.name)» + «ENDIF» + ''' + //ref.EOpposite.EContainingClass.preparePossibleReference+".\\allowbreak "+ + + def private documentEOperationHeader(EOperation op, String parentId) + ''' + «op.documentETypedElement(parentId, null)» + «IF op.EType != null» +
Returns:
+ «op.preparePossibleReference»[«op.lowerBound»..«IF op.upperBound == ETypedElement::UNBOUNDED_MULTIPLICITY»*«ELSE»«op.upperBound»«ENDIF»] + «ENDIF» + «IF !op.EParameters.empty» +
Parameters: +
    + «FOR param : op.EParameters» +
  • «param.preparePossibleReference»[«param.lowerBound»..«IF param.upperBound == ETypedElement::UNBOUNDED_MULTIPLICITY»*«ELSE»«param.upperBound»«ENDIF»]
  • + «ENDFOR» +
+ «ENDIF» + ''' + + def private documentProperty(CharSequence key, CharSequence value) + ''' +
«key»: «value»
+ ''' + + override documentHeader(String sectionClass, String sectionTitle, String shortTitle, String label) { + documentHeader(sectionClass, anchorDef(escapeLabel(label), sectionTitle).toString, label) + } + + private def documentHeader(String sectionClass, String sectionAnchor, String label) + ''' + <«sectionClass» id="«escapeLabel(label)»">«sectionAnchor» + ''' + + override escapeText(String text){ + '''«text.replaceAll("&","&").replaceAll("<","<")»''' + } + + override escapeLabel(String text){ + '''«text.replaceAll("_","").replaceAll("\\.","")»''' + } + + override findGenModelDocumentation(EModelElement element, boolean required){ + var doc = super.findGenModelDocumentation(element, required) + val builder = new StringBuilder(); + val documentationFields = DocumentationFieldUtils.getDocumentationFields(element); + + builder.append(doc) + documentationFields.forEach[ + val value = getValue; + if (value != null) { + builder.append(getKey + ": " + value); + builder.append("
"); + } + ] + return builder.toString; + } + + override emitDocumentation(String doc, boolean required){ + if(doc!=null){ + val Reader docReader = new StringReader(doc); + val Parser parser = new Parser(docReader); + + val Document markdownDoc = parser.parse(); + val builder = new StringBuilder(); + val latexVisitor = new FixedHtmlEmitter(builder); + markdownDoc.accept(latexVisitor); + return builder.toString; + } + else { + if(optionActive(SHOW_MISSING_DOC) && required){ + return '''
Missing Documentation!
''' + } else { + return '''''' + } + } + } + + override String emitBaseClassRef(EClassifier cls) { + '''«cls.name»''' + } + + override processHeader(URI pkgURI) { val gc = new GregorianCalendar() val now = gc.getTime().toString() - if(genHeader){ - "\n".appendToBuilder - - val create = "\n" - create.appendToBuilder - ''' - - - - Metamodel Documentation («pckg.eResource.URI») -