diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..cd1399e
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+# Prevent global windows configuration to change lf into crlf
+* text=auto eol=lf
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2c4d9c9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,90 @@
+### General ###
+.~lock*#
+yalc.lock
+.yalc
+
+
+### macOS ###
+.DS_Store
+._*
+
+
+### Windows ###
+Thumbs.db
+ehthumbs.db
+ehthumbs_vista.db
+
+### Eclipse ###
+# m2e
+.factorypath
+
+### Java ###
+# Compiled class file
+*.class
+bin
+bin/
+target
+target/
+pom.xml.versionsBackup
+
+# Log file
+*.log
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+
+### Node ###
+# Logs
+logs
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Dependency directories
+node_modules/
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variables file
+.env
+.env.test
+
+# parcel-bundler cache (https://parceljs.org/)
+.cache
+.attach_pid*
+
+# Turborepo
+.turbo
+dist/
+coverage/
+
+# IntelliJ IDEA
+.idea
+*.iws
+*.iml
+*.ipr
diff --git a/README.md b/README.md
index a9389df..42fbe03 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,8 @@
Welcome to the temporary repository of the Eclipse SysON project.
-🚧 **Note:** This repository is temporary and is awaiting the official creation of the repository by the Eclipse Foundation. The proposal for the project is available here: [Eclipse SysOn Proposal](https://projects.eclipse.org/proposals/eclipse-syson).
+🚧 **Note:** This repository is temporary and is awaiting the official creation of the repository by the Eclipse Foundation. The proposal for the project is available here: [Eclipse SysON Proposal](https://projects.eclipse.org/proposals/eclipse-syson).
+
## Overview
diff --git a/backend/application/syson-application/.checkstyle b/backend/application/syson-application/.checkstyle
new file mode 100644
index 0000000..84ad855
--- /dev/null
+++ b/backend/application/syson-application/.checkstyle
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/backend/application/syson-application/.classpath b/backend/application/syson-application/.classpath
new file mode 100644
index 0000000..bf19e04
--- /dev/null
+++ b/backend/application/syson-application/.classpath
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/backend/application/syson-application/.project b/backend/application/syson-application/.project
new file mode 100644
index 0000000..f2a87fd
--- /dev/null
+++ b/backend/application/syson-application/.project
@@ -0,0 +1,34 @@
+
+
+ syson-application
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.springframework.ide.eclipse.boot.validation.springbootbuilder
+
+
+
+
+ net.sf.eclipsecs.core.CheckstyleBuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+ net.sf.eclipsecs.core.CheckstyleNature
+
+
diff --git a/backend/application/syson-application/.settings/org.eclipse.core.resources.prefs b/backend/application/syson-application/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..abdea9a
--- /dev/null
+++ b/backend/application/syson-application/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/main/resources=UTF-8
+encoding/=UTF-8
diff --git a/backend/application/syson-application/.settings/org.eclipse.core.runtime.prefs b/backend/application/syson-application/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000..a287fef
--- /dev/null
+++ b/backend/application/syson-application/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,3 @@
+#Mon Sep 24 15:04:19 CEST 2007
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/backend/application/syson-application/.settings/org.eclipse.jdt.apt.core.prefs b/backend/application/syson-application/.settings/org.eclipse.jdt.apt.core.prefs
new file mode 100644
index 0000000..d4313d4
--- /dev/null
+++ b/backend/application/syson-application/.settings/org.eclipse.jdt.apt.core.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.apt.aptEnabled=false
diff --git a/backend/application/syson-application/.settings/org.eclipse.jdt.core.prefs b/backend/application/syson-application/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..2ab93cd
--- /dev/null
+++ b/backend/application/syson-application/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,505 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.annotationPath.allLocations=disabled
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=17
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.APILeak=warning
+org.eclipse.jdt.core.compiler.problem.annotatedTypeArgumentToUnannotated=info
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.suppressWarningsNotFullyAnalysed=info
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
+org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.processAnnotations=disabled
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=17
+org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
+org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns=false
+org.eclipse.jdt.core.formatter.align_with_spaces=false
+org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant=0
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field=49
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable=49
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method=49
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package=49
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter=0
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type=49
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assertion_message=0
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_loops=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain=0
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0
+org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_module_statements=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_record_components=16
+org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_shift_operator=0
+org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_type_annotations=0
+org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0
+org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch=0
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_record_constructor=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_record_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped=false
+org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.indent_tag_description=false
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags=do not insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=120
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_not_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case=insert
+org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line=one_line_if_empty
+org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line=one_line_if_empty
+org.eclipse.jdt.core.formatter.keep_code_block_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line=one_line_if_empty
+org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line=one_line_if_empty
+org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_method_body_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.lineSplit=200
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=false
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.text_block_indentation=0
+org.eclipse.jdt.core.formatter.use_on_off_tags=true
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
+org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_before_relational_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_shift_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
+org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
diff --git a/backend/application/syson-application/.settings/org.eclipse.jdt.ui.prefs b/backend/application/syson-application/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..d4b0716
--- /dev/null
+++ b/backend/application/syson-application/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,152 @@
+cleanup.add_all=false
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_missing_override_annotations_interface_methods=true
+cleanup.add_serial_version_id=false
+cleanup.also_simplify_lambda=true
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=true
+cleanup.always_use_this_for_non_static_method_access=true
+cleanup.array_with_curly=false
+cleanup.arrays_fill=false
+cleanup.bitwise_conditional_expression=false
+cleanup.boolean_literal=false
+cleanup.boolean_value_rather_than_comparison=true
+cleanup.break_loop=false
+cleanup.collection_cloning=false
+cleanup.comparing_on_criteria=false
+cleanup.comparison_statement=false
+cleanup.controlflow_merge=false
+cleanup.convert_functional_interfaces=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.convert_to_enhanced_for_loop_if_loop_var_used=true
+cleanup.convert_to_switch_expressions=false
+cleanup.correct_indentation=true
+cleanup.do_while_rather_than_while=true
+cleanup.double_negation=false
+cleanup.else_if=false
+cleanup.embedded_if=false
+cleanup.evaluate_nullable=false
+cleanup.extract_increment=false
+cleanup.format_source_code=true
+cleanup.format_source_code_changes_only=false
+cleanup.hash=false
+cleanup.if_condition=false
+cleanup.insert_inferred_type_arguments=false
+cleanup.instanceof=false
+cleanup.instanceof_keyword=false
+cleanup.invert_equals=false
+cleanup.join=false
+cleanup.lazy_logical_operator=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=false
+cleanup.map_cloning=false
+cleanup.merge_conditional_blocks=false
+cleanup.multi_catch=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.no_string_creation=false
+cleanup.no_super=false
+cleanup.number_suffix=false
+cleanup.objects_equals=false
+cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=true
+cleanup.operand_factorization=false
+cleanup.organize_imports=true
+cleanup.overridden_assignment=false
+cleanup.overridden_assignment_move_decl=true
+cleanup.plain_replacement=false
+cleanup.precompile_regex=false
+cleanup.primitive_comparison=false
+cleanup.primitive_parsing=false
+cleanup.primitive_rather_than_wrapper=true
+cleanup.primitive_serialization=false
+cleanup.pull_out_if_from_if_else=false
+cleanup.pull_up_assignment=false
+cleanup.push_down_negation=false
+cleanup.qualify_static_field_accesses_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=false
+cleanup.qualify_static_method_accesses_with_declaring_class=true
+cleanup.reduce_indentation=false
+cleanup.redundant_comparator=false
+cleanup.redundant_falling_through_block_end=false
+cleanup.remove_private_constructors=true
+cleanup.remove_redundant_modifiers=false
+cleanup.remove_redundant_semicolons=false
+cleanup.remove_redundant_type_arguments=true
+cleanup.remove_trailing_whitespaces=true
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_array_creation=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_method_parameters=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.return_expression=false
+cleanup.simplify_lambda_expression_and_method_ref=false
+cleanup.single_used_field=false
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.standard_comparison=false
+cleanup.static_inner_class=false
+cleanup.strictly_equal_or_different=false
+cleanup.stringbuffer_to_stringbuilder=false
+cleanup.stringbuilder=false
+cleanup.stringbuilder_for_local_vars=true
+cleanup.stringconcat_stringbuffer_stringbuilder=false
+cleanup.stringconcat_to_textblock=false
+cleanup.substring=false
+cleanup.switch=false
+cleanup.system_property=false
+cleanup.system_property_boolean=false
+cleanup.system_property_file_encoding=false
+cleanup.system_property_file_separator=false
+cleanup.system_property_line_separator=false
+cleanup.system_property_path_separator=false
+cleanup.ternary_operator=false
+cleanup.try_with_resource=false
+cleanup.unlooped_while=false
+cleanup.unreachable_block=false
+cleanup.use_anonymous_class_creation=false
+cleanup.use_autoboxing=false
+cleanup.use_blocks=false
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_directly_map_method=false
+cleanup.use_lambda=true
+cleanup.use_parentheses_in_expressions=false
+cleanup.use_string_is_blank=false
+cleanup.use_this_for_non_static_field_access=true
+cleanup.use_this_for_non_static_field_access_only_if_necessary=false
+cleanup.use_this_for_non_static_method_access=true
+cleanup.use_this_for_non_static_method_access_only_if_necessary=false
+cleanup.use_unboxing=false
+cleanup.use_var=false
+cleanup.useless_continue=false
+cleanup.useless_return=false
+cleanup.valueof_rather_than_instantiation=false
+cleanup_profile=_SysON
+cleanup_settings_version=2
+eclipse.preferences.version=1
+formatter_profile=_SysON
+formatter_settings_version=22
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=com;fr;java;javax;org;
+org.eclipse.jdt.ui.javadoc=true
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=/*******************************************************************************\n * Copyright (c) ${year} Obeo.\n * This program and the accompanying materials\n * are made available under the terms of the Eclipse Public License v2.0\n * which accompanies this distribution, and is available at\n * https\://www.eclipse.org/legal/epl-2.0/\n *\n * SPDX-License-Identifier\: EPL-2.0\n *\n * Contributors\:\n * Obeo - initial API and implementation\n *******************************************************************************//**\n * @author ${user}\n *//**\n * \n *//**\n * ${tags}\n *//**\n * ${tags}\n * ${see_to_target}\n */${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}\n\n\n\n${exception_var}.printStackTrace();${body_statement}${body_statement}return ${field};${field} \= ${param};/**\n * @author ${user}\n *\n * ${tags}\n */
diff --git a/backend/application/syson-application/.settings/org.eclipse.m2e.core.prefs b/backend/application/syson-application/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..96b30f9
--- /dev/null
+++ b/backend/application/syson-application/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=pom.xml
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/backend/application/syson-application/.settings/org.springframework.ide.eclipse.boot.prefs b/backend/application/syson-application/.settings/org.springframework.ide.eclipse.boot.prefs
new file mode 100644
index 0000000..b5811b1
--- /dev/null
+++ b/backend/application/syson-application/.settings/org.springframework.ide.eclipse.boot.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+spring.boot.launch.profile.history=dev;
diff --git a/backend/application/syson-application/.settings/org.springframework.ide.eclipse.prefs b/backend/application/syson-application/.settings/org.springframework.ide.eclipse.prefs
new file mode 100644
index 0000000..a12794d
--- /dev/null
+++ b/backend/application/syson-application/.settings/org.springframework.ide.eclipse.prefs
@@ -0,0 +1,2 @@
+boot.validation.initialized=true
+eclipse.preferences.version=1
diff --git a/backend/application/syson-application/pom.xml b/backend/application/syson-application/pom.xml
new file mode 100644
index 0000000..bcab1b0
--- /dev/null
+++ b/backend/application/syson-application/pom.xml
@@ -0,0 +1,269 @@
+
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.1.2
+
+
+ org.eclipse.syson
+ syson-application
+ 2023.10.6
+ syson-application
+ SysON Application
+
+
+ 17
+ 2.1.5-SNAPSHOT
+ 2023.10.6
+
+
+
+
+ Central
+ https://repo.maven.apache.org/maven2
+
+
+ github-sirius-emfjson
+ https://maven.pkg.github.com/eclipse-sirius/sirius-emf-json
+
+
+ github-sirius-web
+ Apache Maven Packages
+ https://maven.pkg.github.com/eclipse-sirius/sirius-web
+
+
+ Eclipse EEF
+ EEF Repository - Snapshots
+ https://repo.eclipse.org/content/repositories/eef-snapshots/
+
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ io.micrometer
+ micrometer-core
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+
+
+ org.eclipse.sirius
+ sirius-components-starter
+ ${sirius.web.version}
+
+
+ org.eclipse.sirius
+ sirius-web-graphql
+ ${sirius.web.version}
+
+
+ org.eclipse.sirius
+ sirius-web-services
+ ${sirius.web.version}
+
+
+ org.eclipse.sirius
+ sirius-web-spring
+ ${sirius.web.version}
+
+
+ org.eclipse.sirius
+ sirius-web-frontend
+ ${sirius.web.version}
+
+
+ org.eclipse.sirius
+ sirius-components-domain-edit
+ ${sirius.web.version}
+
+
+ org.eclipse.sirius
+ sirius-components-widget-reference-view-edit
+ ${sirius.web.version}
+
+
+ org.eclipse.sirius
+ sirius-components-domain-design
+ ${sirius.web.version}
+
+
+ org.eclipse.sirius
+ sirius-components-view-diagram-edit
+ ${sirius.web.version}
+
+
+ org.eclipse.sirius
+ sirius-components-view-builder
+ ${sirius.web.version}
+
+
+ org.eclipse.eef
+ org.eclipse.eef.core
+ ${eef.version}
+
+
+ org.eclipse.eef
+ org.eclipse.eef.common
+ ${eef.version}
+
+
+ org.eclipse.sirius
+ sirius-web-customwidgets
+ ${sirius.web.version}
+
+
+ org.eclipse.sirius
+ sirius-web-customwidgets-edit
+ ${sirius.web.version}
+
+
+ org.eclipse.sirius
+ sirius-components-widget-reference
+ ${sirius.web.version}
+
+
+ org.eclipse.sirius
+ sirius-components-collaborative-widget-reference
+ ${sirius.web.version}
+
+
+ org.eclipse.sirius
+ sirius-web-customnodes
+ ${sirius.web.version}
+
+
+ org.eclipse.sirius
+ sirius-web-customnodes-edit
+ ${sirius.web.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ io.projectreactor
+ reactor-test
+ test
+
+
+ org.testcontainers
+ postgresql
+ 1.15.3
+ test
+
+
+ org.testcontainers
+ junit-jupiter
+ 1.15.3
+ test
+
+
+ org.eclipse.syson
+ syson-sysml-metamodel
+ 2023.10.6
+
+
+ org.eclipse.syson
+ syson-sysml-metamodel-edit
+ 2023.10.6
+
+
+ org.eclipse.syson
+ syson-diagram-general-view
+ 2023.10.6
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ build-info
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ 3.2.0
+
+ ../../releng/syson-resources/checkstyle/CheckstyleConfiguration.xml
+ true
+ true
+ true
+
+
+
+ validate
+ validate
+
+ check
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.8.10
+
+
+
+ prepare-agent
+
+
+
+ report
+ prepare-package
+
+ report
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
+
+ attach-sources
+
+ jar
+
+
+
+
+
+
+
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/SysONApplication.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/SysONApplication.java
new file mode 100644
index 0000000..451646f
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/SysONApplication.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson;
+
+import org.eclipse.sirius.components.compatibility.emf.properties.PropertiesDefaultDescriptionProvider;
+import org.eclipse.sirius.web.services.documents.UploadDocumentEventHandler;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.FilterType;
+
+/**
+ * Main class of the server, used as the entry point which will start the whole server properly initialized with a
+ * Spring ApplicationContext (see {@link org.springframework.context.ApplicationContext}).
+ *
+ * Thanks to the annotation {@link SpringBootApplication}, this class will act as a configuration which allows us to
+ * declare beans and configure other features but we will not use this capacity in order to properly separate our code.
+ * As such our configurations will be contained in dedicated classes elsewhere.
+ *
+ *
+ * Starting this class will also trigger the scan of the classpath. In order to build our ApplicationContext Spring will
+ * only scan the current package and its subpackages by default. Beans outside of those packages will not be discovered
+ * automatically unless specified by additional information in our annotations.
+ *
+ *
+ * @author arichard
+ */
+@SpringBootApplication
+@ComponentScan(basePackages = { "org.eclipse.syson", "org.eclipse.sirius.web", "org.eclipse.sirius.components" },
+ excludeFilters = { @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = PropertiesDefaultDescriptionProvider.class),
+ @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = UploadDocumentEventHandler.class) })
+public class SysONApplication {
+
+ /**
+ * The entry point of the server.
+ *
+ * @param args
+ * The command line arguments
+ */
+ public static void main(String[] args) {
+ SpringApplication.run(SysONApplication.class, args);
+ }
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/CustomImagesLoader.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/CustomImagesLoader.java
new file mode 100644
index 0000000..b35ca1d
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/CustomImagesLoader.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.configuration;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.UUID;
+
+import org.eclipse.sirius.web.persistence.entities.CustomImageEntity;
+import org.eclipse.sirius.web.persistence.repositories.ICustomImageRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.stereotype.Component;
+
+/**
+ * Import custom images into the database on startup.
+ *
+ * @author pcdavid
+ */
+@Component
+public class CustomImagesLoader implements CommandLineRunner {
+
+ private final Logger logger = LoggerFactory.getLogger(CustomImagesLoader.class);
+
+ private final ICustomImageRepository customImageRepository;
+
+ private final String imagesPathPattern;
+
+ private final PathMatchingResourcePatternResolver patternResolver;
+
+ public CustomImagesLoader(ICustomImageRepository customImageRepository, @Value("${org.eclipse.sirius.web.customImages.pattern:#{null}}") String imagesPathPattern, ResourceLoader resourceLoader) {
+ this.customImageRepository = Objects.requireNonNull(customImageRepository);
+ this.imagesPathPattern = imagesPathPattern;
+ this.patternResolver = new PathMatchingResourcePatternResolver(Objects.requireNonNull(resourceLoader));
+ }
+
+ @Override
+ public void run(String... args) throws Exception {
+ if (this.imagesPathPattern != null) {
+ Resource[] resources = this.patternResolver.getResources(this.imagesPathPattern);
+ for (Resource resource : resources) {
+ Optional contentType = this.getContentType(resource);
+ if (contentType.isPresent() && contentType.get().startsWith("image/")) {
+ this.importImageFromResource(resource, contentType.get());
+ }
+ }
+ }
+ }
+
+ private void importImageFromResource(Resource resource, String contentType) {
+ try {
+ CustomImageEntity customImageEntity = new CustomImageEntity();
+ // No project set: these are global images
+ customImageEntity.setLabel(Optional.ofNullable(resource.getFilename()).map(this::trimFileExtension).orElse(""));
+ customImageEntity.setContentType(contentType);
+ try (BufferedInputStream stream = new BufferedInputStream(resource.getInputStream())) {
+ customImageEntity.setContent(stream.readAllBytes());
+ }
+ customImageEntity.setId(UUID.nameUUIDFromBytes(customImageEntity.getContent()));
+
+ this.logger.debug(resource.getFilename() + ": " + customImageEntity.getId().toString());
+
+ this.customImageRepository.save(customImageEntity);
+ } catch (IOException e) {
+ this.logger.warn("Error loading resource {}: {}", resource, e.getMessage());
+ }
+ }
+
+ private Optional getContentType(Resource resource) {
+ try {
+ return Optional.ofNullable(resource.getURL().openConnection().getContentType());
+ } catch (IOException e) {
+ return Optional.empty();
+ }
+ }
+
+ private String trimFileExtension(String fileName) {
+ int extensionStart = fileName.lastIndexOf('.');
+ if (extensionStart != -1) {
+ return fileName.substring(0, extensionStart);
+ } else {
+ return fileName;
+ }
+ }
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/DomainPropertiesConfigurer.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/DomainPropertiesConfigurer.java
new file mode 100644
index 0000000..ae6ae63
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/DomainPropertiesConfigurer.java
@@ -0,0 +1,203 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.configuration;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
+import org.eclipse.sirius.components.collaborative.forms.services.api.IPropertiesDescriptionRegistry;
+import org.eclipse.sirius.components.collaborative.forms.services.api.IPropertiesDescriptionRegistryConfigurer;
+import org.eclipse.sirius.components.core.api.IFeedbackMessageService;
+import org.eclipse.sirius.components.domain.DomainPackage;
+import org.eclipse.sirius.components.emf.services.EditingContext;
+import org.eclipse.sirius.components.emf.services.IDAdapter;
+import org.eclipse.sirius.components.interpreter.AQLInterpreter;
+import org.eclipse.sirius.components.representations.IRepresentationDescription;
+import org.eclipse.sirius.components.view.ChangeContext;
+import org.eclipse.sirius.components.view.SetValue;
+import org.eclipse.sirius.components.view.View;
+import org.eclipse.sirius.components.view.ViewFactory;
+import org.eclipse.sirius.components.view.emf.form.ViewFormDescriptionConverter;
+import org.eclipse.sirius.components.view.form.CheckboxDescription;
+import org.eclipse.sirius.components.view.form.FormDescription;
+import org.eclipse.sirius.components.view.form.FormFactory;
+import org.eclipse.sirius.components.view.form.GroupDescription;
+import org.eclipse.sirius.components.view.form.GroupDisplayMode;
+import org.eclipse.sirius.components.view.form.LabelDescription;
+import org.eclipse.sirius.components.view.form.PageDescription;
+import org.eclipse.sirius.components.view.form.SelectDescription;
+import org.eclipse.sirius.components.view.form.TextfieldDescription;
+import org.eclipse.sirius.components.view.form.WidgetDescription;
+import org.eclipse.sirius.components.widgets.reference.ReferenceFactory;
+import org.eclipse.sirius.components.widgets.reference.ReferenceWidgetDescription;
+import org.eclipse.sirius.web.services.api.representations.IInMemoryViewRegistry;
+import org.eclipse.syson.services.DomainAttributeServices;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Provides custom Details view for some of the Domain DSL elements based on a View-based Form description.
+ *
+ * @author pcdavid
+ */
+@Configuration
+public class DomainPropertiesConfigurer implements IPropertiesDescriptionRegistryConfigurer {
+
+ private static final String CORE_PROPERTIES = "Core Properties";
+
+ private final ViewFormDescriptionConverter converter;
+
+ private final IFeedbackMessageService feedbackMessageService;
+
+ private final IInMemoryViewRegistry viewRegistry;
+
+ public DomainPropertiesConfigurer(ViewFormDescriptionConverter converter, IFeedbackMessageService feedbackMessageService, IInMemoryViewRegistry viewRegistry) {
+ this.viewRegistry = Objects.requireNonNull(viewRegistry);
+ this.converter = Objects.requireNonNull(converter);
+ this.feedbackMessageService = Objects.requireNonNull(feedbackMessageService);
+ }
+
+ @Override
+ public void addPropertiesDescriptions(IPropertiesDescriptionRegistry registry) {
+ // Build the actual FormDescription
+ FormDescription viewFormDescription = this.getAttributeDetails();
+
+ // The FormDescription must be part of View inside a proper EMF Resource to be correctly handled
+ URI uri = URI.createURI(EditingContext.RESOURCE_SCHEME + ":///" + UUID.nameUUIDFromBytes(DomainPropertiesConfigurer.class.getCanonicalName().getBytes()));
+ Resource resource = new XMIResourceImpl(uri);
+ View view = org.eclipse.sirius.components.view.ViewFactory.eINSTANCE.createView();
+ resource.getContents().add(view);
+ view.getDescriptions().add(viewFormDescription);
+
+ view.eAllContents().forEachRemaining(eObject -> {
+ eObject.eAdapters().add(new IDAdapter(UUID.nameUUIDFromBytes(EcoreUtil.getURI(eObject).toString().getBytes())));
+ });
+
+ this.viewRegistry.register(view);
+
+ // Convert the View-based FormDescription and register the result into the system
+ AQLInterpreter interpreter = new AQLInterpreter(List.of(), List.of(new DomainAttributeServices(this.feedbackMessageService)), List.of(DomainPackage.eINSTANCE));
+ IRepresentationDescription converted = this.converter.convert(viewFormDescription, List.of(), interpreter);
+ if (converted instanceof org.eclipse.sirius.components.forms.description.FormDescription formDescription) {
+ formDescription.getPageDescriptions().forEach(registry::add);
+ }
+ }
+
+ private FormDescription getAttributeDetails() {
+ FormDescription form = FormFactory.eINSTANCE.createFormDescription();
+ form.setName("Attribute Details");
+ form.setDomainType("domain::Attribute");
+ form.setTitleExpression("Attribute Details");
+
+ PageDescription page = FormFactory.eINSTANCE.createPageDescription();
+ page.setDomainType("domain::Attribute");
+ page.setPreconditionExpression("");
+ page.setLabelExpression("aql:self.name + ': ' + self.getDataType().capitalize()");
+ form.getPages().add(page);
+ page.getGroups().add(this.createGroup());
+
+ PageDescription entityPage = FormFactory.eINSTANCE.createPageDescription();
+ entityPage.setDomainType("domain::Entity");
+ entityPage.setPreconditionExpression("");
+ entityPage.setLabelExpression("aql:self.name");
+ form.getPages().add(entityPage);
+ entityPage.getGroups().add(this.createEntityGroup());
+ return form;
+ }
+
+ private GroupDescription createEntityGroup() {
+ GroupDescription group = FormFactory.eINSTANCE.createGroupDescription();
+ group.setDisplayMode(GroupDisplayMode.LIST);
+ group.setName(CORE_PROPERTIES);
+ group.setLabelExpression(CORE_PROPERTIES);
+ group.setSemanticCandidatesExpression("aql:self");
+ group.getChildren().add(this.createStringAttributeEditWidget("Name", DomainPackage.Literals.NAMED_ELEMENT__NAME.getName()));
+ group.getChildren().add(this.createReferenceWidget("Super Type", DomainPackage.Literals.ENTITY__SUPER_TYPES.getName()));
+ group.getChildren().add(this.createReferenceWidget("Attributes", DomainPackage.Literals.ENTITY__ATTRIBUTES.getName()));
+ group.getChildren().add(this.createReferenceWidget("Relations", DomainPackage.Literals.ENTITY__RELATIONS.getName()));
+ group.getChildren().add(this.createBooleanAttributeEditWidget("Abstract", DomainPackage.Literals.ENTITY__ABSTRACT.getName()));
+ return group;
+ }
+
+ private GroupDescription createGroup() {
+ GroupDescription group = FormFactory.eINSTANCE.createGroupDescription();
+ group.setDisplayMode(GroupDisplayMode.LIST);
+ group.setName(CORE_PROPERTIES);
+ group.setLabelExpression(CORE_PROPERTIES);
+ group.setSemanticCandidatesExpression("aql:self");
+ group.getChildren().add(this.createStringAttributeEditWidget("Name", DomainPackage.Literals.NAMED_ELEMENT__NAME.getName()));
+ group.getChildren().add(this.createTypeSelectorWidget());
+ group.getChildren().add(this.createBooleanAttributeEditWidget("Optional", DomainPackage.Literals.FEATURE__OPTIONAL.getName()));
+ group.getChildren().add(this.createBooleanAttributeEditWidget("Many", DomainPackage.Literals.FEATURE__MANY.getName()));
+ group.getChildren().add(this.createCardinalityLabel());
+ return group;
+ }
+
+ private WidgetDescription createStringAttributeEditWidget(String title, String attributeName) {
+ TextfieldDescription textfield = FormFactory.eINSTANCE.createTextfieldDescription();
+ textfield.setName(title);
+ textfield.setLabelExpression(title);
+ textfield.setValueExpression("aql:self.%s".formatted(attributeName));
+ SetValue setValueOperation = ViewFactory.eINSTANCE.createSetValue();
+ setValueOperation.setFeatureName(attributeName);
+ setValueOperation.setValueExpression("aql:" + ViewFormDescriptionConverter.NEW_VALUE);
+ textfield.getBody().add(setValueOperation);
+ return textfield;
+ }
+
+ private WidgetDescription createBooleanAttributeEditWidget(String title, String attributeName) {
+ CheckboxDescription checkbox = FormFactory.eINSTANCE.createCheckboxDescription();
+ checkbox.setName(title);
+ checkbox.setLabelExpression(title);
+ checkbox.setValueExpression("aql:self.%s".formatted(attributeName));
+ SetValue setValueOperation = ViewFactory.eINSTANCE.createSetValue();
+ setValueOperation.setFeatureName(attributeName);
+ setValueOperation.setValueExpression("aql:" + ViewFormDescriptionConverter.NEW_VALUE);
+ checkbox.getBody().add(setValueOperation);
+ return checkbox;
+ }
+
+ private WidgetDescription createTypeSelectorWidget() {
+ SelectDescription selectWidget = FormFactory.eINSTANCE.createSelectDescription();
+ selectWidget.setName("Type");
+ selectWidget.setLabelExpression("Type");
+ selectWidget.setCandidatesExpression("aql:self.getAvailableDataTypes()");
+ selectWidget.setValueExpression("aql:self.getDataType()");
+ selectWidget.setCandidateLabelExpression("aql:candidate.capitalize()");
+ ChangeContext setValueOperation = ViewFactory.eINSTANCE.createChangeContext();
+ setValueOperation.setExpression("aql:self.setDataType(newValue)");
+ selectWidget.getBody().add(setValueOperation);
+ return selectWidget;
+ }
+
+ private WidgetDescription createReferenceWidget(String name, String referenceName) {
+ ReferenceWidgetDescription refWidget = ReferenceFactory.eINSTANCE.createReferenceWidgetDescription();
+ refWidget.setName(name);
+ refWidget.setLabelExpression(name);
+ refWidget.setReferenceNameExpression(referenceName);
+ return refWidget;
+ }
+
+ private WidgetDescription createCardinalityLabel() {
+ LabelDescription cardinalityLabel = FormFactory.eINSTANCE.createLabelDescription();
+ cardinalityLabel.setName("Cardinality");
+ cardinalityLabel.setLabelExpression("Cardinality");
+ cardinalityLabel.setValueExpression("aql:(if self.optional then '0' else '1' endif) + '..' + (if self.many then '*' else '1' endif)");
+ return cardinalityLabel;
+ }
+
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/JPAConfiguration.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/JPAConfiguration.java
new file mode 100644
index 0000000..5265019
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/JPAConfiguration.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.configuration;
+
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+/**
+ * Configuration of JPA.
+ *
+ * @author sbegaudeau
+ */
+@Configuration
+@EntityScan(basePackages = { "org.eclipse.sirius.web.persistence.entities" })
+@EnableJpaRepositories(basePackages = { "org.eclipse.sirius.web.persistence.repositories" })
+public class JPAConfiguration {
+
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/MonitoringConfiguration.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/MonitoringConfiguration.java
new file mode 100644
index 0000000..860dfd0
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/MonitoringConfiguration.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.configuration;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
+
+/**
+ * Configuration of the monitoring support for SysON.
+ *
+ * @author arichard
+ */
+@Configuration
+public class MonitoringConfiguration {
+ @Bean
+ MeterRegistry meterRegistry() {
+ return new SimpleMeterRegistry();
+ }
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/MultipleDomainPropertiesConfigurer.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/MultipleDomainPropertiesConfigurer.java
new file mode 100644
index 0000000..997549f
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/MultipleDomainPropertiesConfigurer.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.configuration;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
+import org.eclipse.sirius.components.collaborative.forms.services.api.IPropertiesDescriptionRegistry;
+import org.eclipse.sirius.components.collaborative.forms.services.api.IPropertiesDescriptionRegistryConfigurer;
+import org.eclipse.sirius.components.domain.DomainPackage;
+import org.eclipse.sirius.components.emf.services.EditingContext;
+import org.eclipse.sirius.components.interpreter.AQLInterpreter;
+import org.eclipse.sirius.components.representations.IRepresentationDescription;
+import org.eclipse.sirius.components.view.ChangeContext;
+import org.eclipse.sirius.components.view.View;
+import org.eclipse.sirius.components.view.ViewFactory;
+import org.eclipse.sirius.components.view.emf.form.ViewFormDescriptionConverter;
+import org.eclipse.sirius.components.view.form.CheckboxDescription;
+import org.eclipse.sirius.components.view.form.FormDescription;
+import org.eclipse.sirius.components.view.form.FormFactory;
+import org.eclipse.sirius.components.view.form.GroupDescription;
+import org.eclipse.sirius.components.view.form.GroupDisplayMode;
+import org.eclipse.sirius.components.view.form.PageDescription;
+import org.eclipse.sirius.components.view.form.SelectDescription;
+import org.eclipse.sirius.components.view.form.WidgetDescription;
+import org.eclipse.syson.services.DomainAttributeServices;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Provides custom Details view for a multiple selection of domain Attribute elements.
+ *
+ * @author frouene
+ */
+@Configuration
+public class MultipleDomainPropertiesConfigurer implements IPropertiesDescriptionRegistryConfigurer {
+
+ private final ViewFormDescriptionConverter converter;
+
+ public MultipleDomainPropertiesConfigurer(ViewFormDescriptionConverter converter) {
+ this.converter = Objects.requireNonNull(converter);
+ }
+
+ @Override
+ public void addPropertiesDescriptions(IPropertiesDescriptionRegistry registry) {
+ // Build the actual FormDescription
+ FormDescription viewFormDescription = this.getAttributeDetails();
+
+ // The FormDescription must be part of View inside a proper EMF Resource to be correctly handled
+ URI uri = URI.createURI(EditingContext.RESOURCE_SCHEME + ":///" + UUID.nameUUIDFromBytes(MultipleDomainPropertiesConfigurer.class.getCanonicalName().getBytes()));
+ Resource resource = new XMIResourceImpl(uri);
+ View view = ViewFactory.eINSTANCE.createView();
+ resource.getContents().add(view);
+ view.getDescriptions().add(viewFormDescription);
+
+ // Convert the View-based FormDescription and register the result into the system
+ AQLInterpreter interpreter = new AQLInterpreter(List.of(DomainAttributeServices.class), List.of(), List.of(DomainPackage.eINSTANCE));
+ IRepresentationDescription converted = this.converter.convert(viewFormDescription, List.of(), interpreter);
+ if (converted instanceof org.eclipse.sirius.components.forms.description.FormDescription formDescription) {
+ formDescription.getPageDescriptions().forEach(registry::add);
+ }
+ }
+
+ private FormDescription getAttributeDetails() {
+ FormDescription form = FormFactory.eINSTANCE.createFormDescription();
+ form.setName("Attribute Details");
+ form.setDomainType("domain::Attribute");
+ form.setTitleExpression("Attribute Details");
+
+ PageDescription page = FormFactory.eINSTANCE.createPageDescription();
+ page.setSemanticCandidatesExpression("aql:self");
+ page.setDomainType("domain::Attribute");
+ page.setPreconditionExpression("aql:selection->filter(domain::Attribute)->size()>1");
+ page.setLabelExpression("MultiSelection");
+ form.getPages().add(page);
+ page.getGroups().add(this.createGroup());
+ return form;
+ }
+
+ private GroupDescription createGroup() {
+ GroupDescription group = FormFactory.eINSTANCE.createGroupDescription();
+ group.setDisplayMode(GroupDisplayMode.LIST);
+ group.setName("Core Properties");
+ group.setLabelExpression("Core Properties");
+ group.setSemanticCandidatesExpression("aql:self");
+ group.getChildren().add(this.createTypeSelectorWidget());
+ group.getChildren().add(this.createBooleanAttributeEditWidget("Optional", DomainPackage.Literals.FEATURE__OPTIONAL.getName()));
+ group.getChildren().add(this.createBooleanAttributeEditWidget("Many", DomainPackage.Literals.FEATURE__MANY.getName()));
+ return group;
+ }
+
+
+ private WidgetDescription createBooleanAttributeEditWidget(String title, String attributeName) {
+ CheckboxDescription checkbox = FormFactory.eINSTANCE.createCheckboxDescription();
+ checkbox.setName(title);
+ checkbox.setLabelExpression(title);
+ checkbox.setValueExpression("aql:self.%s".formatted(attributeName));
+ ChangeContext changeContext = ViewFactory.eINSTANCE.createChangeContext();
+ changeContext.setExpression("aql:selection->filter(domain::Attribute).setValue('%s',newValue)".formatted(attributeName));
+ checkbox.getBody().add(changeContext);
+ return checkbox;
+ }
+
+ private WidgetDescription createTypeSelectorWidget() {
+ SelectDescription selectWidget = FormFactory.eINSTANCE.createSelectDescription();
+ selectWidget.setName("Type");
+ selectWidget.setLabelExpression("Type");
+ selectWidget.setCandidatesExpression("aql:self.getAvailableDataTypes()");
+ selectWidget.setValueExpression("aql:self.getDataType()");
+ selectWidget.setCandidateLabelExpression("aql:candidate.capitalize()");
+ ChangeContext setValueOperation = ViewFactory.eINSTANCE.createChangeContext();
+ setValueOperation.setExpression("aql:selection->filter(domain::Attribute).setDataType(newValue)");
+ selectWidget.getBody().add(setValueOperation);
+ return selectWidget;
+ }
+
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/SpringWebMvcConfigurer.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/SpringWebMvcConfigurer.java
new file mode 100644
index 0000000..779ce80
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/SpringWebMvcConfigurer.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.configuration;
+
+import java.util.Arrays;
+
+import org.eclipse.sirius.web.spring.configuration.SiriusWebPathResourceResolver;
+import org.eclipse.sirius.web.spring.configuration.SpringWebMvcConfigurerConstants;
+import org.eclipse.sirius.web.spring.controllers.URLConstants;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * Used to configure the server side routing.
+ *
+ * @author sbegaudeau
+ */
+@Configuration
+public class SpringWebMvcConfigurer implements WebMvcConfigurer {
+ private static final String[] ALLOWED_ORIGIN_PATTERNS = { "*" };
+
+ /**
+ * The Spring environment.
+ */
+ private Environment environment;
+
+ public SpringWebMvcConfigurer(Environment environment) {
+ this.environment = environment;
+ }
+
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+ // @formatter:off
+
+ // Make sure that all static assets are redirected properly to the proper path
+ registry.addResourceHandler(
+ SpringWebMvcConfigurerConstants.CSS_PATTERN,
+ SpringWebMvcConfigurerConstants.HTML_PATTERN,
+ SpringWebMvcConfigurerConstants.JS_PATTERN,
+ SpringWebMvcConfigurerConstants.JS_CHUNK_PATTERN,
+ SpringWebMvcConfigurerConstants.JS_MAP_PATTERN,
+ SpringWebMvcConfigurerConstants.JSON_PATTERN,
+ SpringWebMvcConfigurerConstants.ICO_PATTERN,
+ SpringWebMvcConfigurerConstants.TTF_PATTERN,
+ SpringWebMvcConfigurerConstants.MEDIA_PATTERN
+ ).addResourceLocations(SpringWebMvcConfigurerConstants.STATIC_ASSETS_PATH);
+
+ // Make sure that all other requests are redirected to index.html, the React router will handle it
+ registry.addResourceHandler(
+ SpringWebMvcConfigurerConstants.EMPTY_PATTERN,
+ SpringWebMvcConfigurerConstants.HOMEPAGE_PATTERN,
+ SpringWebMvcConfigurerConstants.ANY_PATTERN
+ ).addResourceLocations(SpringWebMvcConfigurerConstants.INDEX_HTML_PATH)
+ .resourceChain(true)
+ .addResolver(new SiriusWebPathResourceResolver(URLConstants.API_BASE_PATH));
+
+ // @formatter:on
+ }
+
+ @Override
+ public void addViewControllers(ViewControllerRegistry registry) {
+ registry.addRedirectViewController("/graphiql", "/graphiql/index.html");
+ registry.addRedirectViewController("/voyager", "/voyager/index.html");
+ }
+
+ @Override
+ public void addCorsMappings(CorsRegistry registry) {
+ boolean inDevMode = Arrays.asList(this.environment.getActiveProfiles()).contains("dev");
+ if (inDevMode) {
+ registry.addMapping(URLConstants.API_BASE_PATH + SpringWebMvcConfigurerConstants.ANY_PATTERN).allowedOriginPatterns(ALLOWED_ORIGIN_PATTERNS).allowCredentials(true);
+ }
+ }
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/StereotypeBuilder.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/StereotypeBuilder.java
new file mode 100644
index 0000000..97a9511
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/StereotypeBuilder.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.configuration;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.xmi.XMLParserPool;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
+import org.eclipse.emf.ecore.xmi.impl.XMLParserPoolImpl;
+import org.eclipse.sirius.components.emf.services.JSONResourceFactory;
+import org.eclipse.sirius.components.emf.utils.EMFResourceUtils;
+import org.eclipse.sirius.emfjson.resource.JsonResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.io.ClassPathResource;
+
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.Timer;
+
+/**
+ * Helper to create a document stereotype from an EMF model.
+ *
+ * @author pcdavid
+ */
+public class StereotypeBuilder {
+ private static XMLParserPool parserPool = new XMLParserPoolImpl();
+
+ private final Logger logger = LoggerFactory.getLogger(StereotypeBuilder.class);
+
+ private final Timer timer;
+
+ public StereotypeBuilder(String timerName, MeterRegistry meterRegistry) {
+ this.timer = Timer.builder(timerName).register(meterRegistry);
+ }
+
+ public String getStereotypeBody(List rootEObjects) {
+ JsonResource resource = new JSONResourceFactory().createResourceFromPath("inmemory");
+ if (rootEObjects != null) {
+ resource.getContents().addAll(rootEObjects);
+ }
+
+ String content = "";
+ try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
+ Map options = new HashMap<>();
+ options.put(JsonResource.OPTION_ENCODING, JsonResource.ENCODING_UTF_8);
+ options.put(JsonResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
+
+ resource.save(outputStream, options);
+
+ content = outputStream.toString();
+ } catch (IOException exception) {
+ this.logger.error(exception.getMessage(), exception);
+ }
+ return content;
+ }
+
+ public String getStereotypeBody(ClassPathResource classPathResource) {
+ long start = System.currentTimeMillis();
+
+ String content = "";
+ try (var inputStream = classPathResource.getInputStream()) {
+ URI uri = new JSONResourceFactory().createResourceURI(classPathResource.getFilename());
+ Resource inputResource = this.loadFromXMI(uri, inputStream);
+ content = this.saveAsJSON(uri, inputResource);
+ } catch (IOException exception) {
+ this.logger.error(exception.getMessage(), exception);
+ }
+
+ long end = System.currentTimeMillis();
+ this.timer.record(end - start, TimeUnit.MILLISECONDS);
+
+ return content;
+ }
+
+ private Resource loadFromXMI(URI uri, InputStream inputStream) throws IOException {
+ Resource inputResource = new XMIResourceImpl(uri);
+ Map xmiLoadOptions = new EMFResourceUtils().getXMILoadOptions(parserPool);
+ inputResource.load(inputStream, xmiLoadOptions);
+ return inputResource;
+ }
+
+ private String saveAsJSON(URI uri, Resource inputResource) throws IOException {
+ String content;
+ JsonResource ouputResource = new JSONResourceFactory().createResource(uri);
+ ouputResource.getContents().addAll(inputResource.getContents());
+ try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
+ Map jsonSaveOptions = new EMFResourceUtils().getFastJSONSaveOptions();
+ jsonSaveOptions.put(JsonResource.OPTION_ENCODING, JsonResource.ENCODING_UTF_8);
+ jsonSaveOptions.put(JsonResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
+ ouputResource.save(outputStream, jsonSaveOptions);
+ content = outputStream.toString(StandardCharsets.UTF_8);
+ }
+ return content;
+ }
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/StereotypeDescriptionRegistryConfigurer.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/StereotypeDescriptionRegistryConfigurer.java
new file mode 100644
index 0000000..37c2620
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/StereotypeDescriptionRegistryConfigurer.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.configuration;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.eclipse.sirius.components.core.configuration.IStereotypeDescriptionRegistry;
+import org.eclipse.sirius.components.core.configuration.IStereotypeDescriptionRegistryConfigurer;
+import org.eclipse.sirius.components.core.configuration.StereotypeDescription;
+import org.eclipse.sirius.components.domain.Domain;
+import org.eclipse.sirius.components.domain.DomainFactory;
+import org.eclipse.sirius.components.view.View;
+import org.eclipse.sirius.components.view.ViewFactory;
+import org.eclipse.sirius.components.view.diagram.DiagramDescription;
+import org.eclipse.sirius.components.view.diagram.DiagramFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+import io.micrometer.core.instrument.MeterRegistry;
+
+/**
+ * Configuration used to register new stereotype descriptions.
+ *
+ * @author sbegaudeau
+ */
+@Configuration
+public class StereotypeDescriptionRegistryConfigurer implements IStereotypeDescriptionRegistryConfigurer {
+
+ public static final UUID EMPTY_ID = UUID.nameUUIDFromBytes("empty".getBytes());
+
+ public static final String EMPTY_LABEL = "Others...";
+
+ public static final UUID EMPTY_VIEW_ID = UUID.nameUUIDFromBytes("empty_view".getBytes());
+
+ public static final String EMPTY_VIEW_LABEL = "View";
+
+ private static final UUID EMPTY_DOMAIN_ID = UUID.nameUUIDFromBytes("empty_domain".getBytes());
+
+ private static final String EMPTY_DOMAIN_LABEL = "Domain";
+
+ private static final String TIMER_NAME = "siriusweb_stereotype_load";
+
+ private final StereotypeBuilder stereotypeBuilder;
+
+ private final SysONDomainNameProvider domainNameProvider;
+
+ private final boolean studiosEnabled;
+
+ public StereotypeDescriptionRegistryConfigurer(MeterRegistry meterRegistry, @Value("${org.eclipse.sirius.web.features.studioDefinition:false}") boolean studiosEnabled) {
+ this.stereotypeBuilder = new StereotypeBuilder(TIMER_NAME, meterRegistry);
+ this.studiosEnabled = studiosEnabled;
+ this.domainNameProvider = new SysONDomainNameProvider();
+ }
+
+ @Override
+ public void addStereotypeDescriptions(IStereotypeDescriptionRegistry registry) {
+ if (this.studiosEnabled) {
+ registry.add(new StereotypeDescription(EMPTY_DOMAIN_ID, EMPTY_DOMAIN_LABEL, this::getEmptyDomainContent));
+ registry.add(new StereotypeDescription(EMPTY_VIEW_ID, EMPTY_VIEW_LABEL, this::getEmptyViewContent));
+ }
+ registry.add(new StereotypeDescription(EMPTY_ID, EMPTY_LABEL, "New", this::getEmptyContent));
+ }
+
+ private String getEmptyDomainContent() {
+ Domain domain = DomainFactory.eINSTANCE.createDomain();
+ domain.setName("SampleDomain");
+ domain.setName(this.domainNameProvider.getSampleDomainName());
+ return this.stereotypeBuilder.getStereotypeBody(List.of(domain));
+ }
+
+ private String getEmptyViewContent() {
+ View newView = ViewFactory.eINSTANCE.createView();
+ DiagramDescription diagramDescription = DiagramFactory.eINSTANCE.createDiagramDescription();
+ diagramDescription.setName("New Diagram Description");
+ newView.getDescriptions().add(diagramDescription);
+
+ return this.stereotypeBuilder.getStereotypeBody(List.of(newView));
+ }
+
+ private String getEmptyContent() {
+ return this.stereotypeBuilder.getStereotypeBody(List.of());
+ }
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/StudioProjectTemplatesInitializer.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/StudioProjectTemplatesInitializer.java
new file mode 100644
index 0000000..57f1bc9
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/StudioProjectTemplatesInitializer.java
@@ -0,0 +1,397 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.configuration;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.UUID;
+
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
+import org.eclipse.sirius.components.collaborative.api.IRepresentationPersistenceService;
+import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramCreationService;
+import org.eclipse.sirius.components.core.RepresentationMetadata;
+import org.eclipse.sirius.components.core.api.IEditingContext;
+import org.eclipse.sirius.components.core.api.IRepresentationDescriptionSearchService;
+import org.eclipse.sirius.components.diagrams.Diagram;
+import org.eclipse.sirius.components.diagrams.description.DiagramDescription;
+import org.eclipse.sirius.components.domain.Attribute;
+import org.eclipse.sirius.components.domain.DataType;
+import org.eclipse.sirius.components.domain.Domain;
+import org.eclipse.sirius.components.domain.DomainFactory;
+import org.eclipse.sirius.components.domain.Entity;
+import org.eclipse.sirius.components.domain.Relation;
+import org.eclipse.sirius.components.emf.ResourceMetadataAdapter;
+import org.eclipse.sirius.components.emf.services.EditingContext;
+import org.eclipse.sirius.components.emf.services.JSONResourceFactory;
+import org.eclipse.sirius.components.view.ChangeContext;
+import org.eclipse.sirius.components.view.ColorPalette;
+import org.eclipse.sirius.components.view.CreateInstance;
+import org.eclipse.sirius.components.view.FixedColor;
+import org.eclipse.sirius.components.view.SetValue;
+import org.eclipse.sirius.components.view.UserColor;
+import org.eclipse.sirius.components.view.View;
+import org.eclipse.sirius.components.view.ViewFactory;
+import org.eclipse.sirius.components.view.diagram.DiagramFactory;
+import org.eclipse.sirius.components.view.diagram.EdgeDescription;
+import org.eclipse.sirius.components.view.diagram.EdgeStyle;
+import org.eclipse.sirius.components.view.diagram.EdgeTool;
+import org.eclipse.sirius.components.view.diagram.NodeDescription;
+import org.eclipse.sirius.components.view.diagram.NodeTool;
+import org.eclipse.sirius.components.view.diagram.RectangularNodeStyleDescription;
+import org.eclipse.sirius.components.view.diagram.SynchronizationPolicy;
+import org.eclipse.sirius.components.view.diagram.provider.DefaultToolsFactory;
+import org.eclipse.sirius.emfjson.resource.JsonResource;
+import org.eclipse.sirius.web.persistence.entities.DocumentEntity;
+import org.eclipse.sirius.web.persistence.repositories.IDocumentRepository;
+import org.eclipse.sirius.web.persistence.repositories.IProjectRepository;
+import org.eclipse.sirius.web.services.api.id.IDParser;
+import org.eclipse.sirius.web.services.api.projects.IProjectTemplateInitializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Configuration;
+
+import io.micrometer.core.instrument.MeterRegistry;
+
+/**
+ * Provides Studio-specific project templates initializers.
+ *
+ * @author pcdavid
+ */
+@Configuration
+public class StudioProjectTemplatesInitializer implements IProjectTemplateInitializer {
+
+ private static final String NAME_ATTRIBUTE = "name";
+
+ private static final String DOMAIN_DOCUMENT_NAME = "DomainNewModel";
+
+ private static final String VIEW_DOCUMENT_NAME = "ViewNewModel";
+
+ private final Logger logger = LoggerFactory.getLogger(StudioProjectTemplatesInitializer.class);
+
+ private final IProjectRepository projectRepository;
+
+ private final IDocumentRepository documentRepository;
+
+ private final IRepresentationDescriptionSearchService representationDescriptionSearchService;
+
+ private final IDiagramCreationService diagramCreationService;
+
+ private final IRepresentationPersistenceService representationPersistenceService;
+
+ private final StereotypeBuilder stereotypeBuilder;
+
+ public StudioProjectTemplatesInitializer(IProjectRepository projectRepository, IDocumentRepository documentRepository,
+ IRepresentationDescriptionSearchService representationDescriptionSearchService, IDiagramCreationService diagramCreationService,
+ IRepresentationPersistenceService representationPersistenceService, MeterRegistry meterRegistry) {
+ this.projectRepository = Objects.requireNonNull(projectRepository);
+ this.documentRepository = Objects.requireNonNull(documentRepository);
+ this.representationDescriptionSearchService = Objects.requireNonNull(representationDescriptionSearchService);
+ this.diagramCreationService = Objects.requireNonNull(diagramCreationService);
+ this.representationPersistenceService = Objects.requireNonNull(representationPersistenceService);
+ this.stereotypeBuilder = new StereotypeBuilder("studio-template-initializer", meterRegistry);
+ }
+
+ @Override
+ public boolean canHandle(String templateId) {
+ return List.of(StudioProjectTemplatesProvider.STUDIO_TEMPLATE_ID, StudioProjectTemplatesProvider.BLANK_STUDIO_TEMPLATE_ID).contains(templateId);
+ }
+
+ @Override
+ public Optional handle(String templateId, IEditingContext editingContext) {
+ if (StudioProjectTemplatesProvider.STUDIO_TEMPLATE_ID.equals(templateId)) {
+ return this.initializeStudioProject(editingContext);
+ }
+ return Optional.empty();
+ }
+
+ private Optional initializeStudioProject(IEditingContext editingContext) {
+ Optional result = Optional.empty();
+ // @formatter:off
+ Optional optionalEditingDomain = Optional.of(editingContext)
+ .filter(EditingContext.class::isInstance)
+ .map(EditingContext.class::cast)
+ .map(EditingContext::getDomain);
+ // @formatter:on
+ Optional editingContextUUID = new IDParser().parse(editingContext.getId());
+ if (optionalEditingDomain.isPresent() && editingContextUUID.isPresent()) {
+ AdapterFactoryEditingDomain adapterFactoryEditingDomain = optionalEditingDomain.get();
+ ResourceSet resourceSet = adapterFactoryEditingDomain.getResourceSet();
+
+ var optionalDomainDocumentEntity = this.projectRepository.findById(editingContextUUID.get()).map(projectEntity -> {
+ DocumentEntity documentEntity = new DocumentEntity();
+ documentEntity.setProject(projectEntity);
+ documentEntity.setName(DOMAIN_DOCUMENT_NAME);
+ documentEntity.setContent(this.getDomainContent());
+
+ documentEntity = this.documentRepository.save(documentEntity);
+ return documentEntity;
+ });
+
+ String domainName = "sampledomain";
+
+ if (optionalDomainDocumentEntity.isPresent()) {
+ DocumentEntity documentEntity = optionalDomainDocumentEntity.get();
+
+ JsonResource resource = new JSONResourceFactory().createResourceFromPath(documentEntity.getId().toString());
+ try (var inputStream = new ByteArrayInputStream(documentEntity.getContent().getBytes())) {
+ resource.load(inputStream, null);
+
+ var optionalTopographyDiagram = this.findDiagramDescription(editingContext, "Domain");
+ if (optionalTopographyDiagram.isPresent()) {
+ DiagramDescription topographyDiagram = optionalTopographyDiagram.get();
+ Object semanticTarget = resource.getContents().get(0);
+ domainName = ((Domain) semanticTarget).getName();
+
+ Diagram diagram = this.diagramCreationService.create(topographyDiagram.getLabel(), semanticTarget, topographyDiagram, editingContext);
+ this.representationPersistenceService.save(editingContext, diagram);
+
+ result = Optional.of(new RepresentationMetadata(diagram.getId(), diagram.getKind(), diagram.getLabel(), diagram.getDescriptionId()));
+ }
+ } catch (IOException exception) {
+ this.logger.warn(exception.getMessage(), exception);
+ }
+
+ resource.eAdapters().add(new ResourceMetadataAdapter(DOMAIN_DOCUMENT_NAME));
+
+ resourceSet.getResources().add(resource);
+ }
+
+ final String theDomainName = domainName;
+ var optionalViewDocumentEntity = this.projectRepository.findById(editingContextUUID.get()).map(projectEntity -> {
+ DocumentEntity documentEntity = new DocumentEntity();
+ documentEntity.setProject(projectEntity);
+ documentEntity.setName(VIEW_DOCUMENT_NAME);
+ documentEntity.setContent(this.getViewContent(theDomainName));
+
+ documentEntity = this.documentRepository.save(documentEntity);
+ return documentEntity;
+ });
+ if (optionalViewDocumentEntity.isPresent()) {
+ DocumentEntity documentEntity = optionalViewDocumentEntity.get();
+ JsonResource resource = new JSONResourceFactory().createResourceFromPath(documentEntity.getId().toString());
+ resource.eAdapters().add(new ResourceMetadataAdapter(VIEW_DOCUMENT_NAME));
+ try (var inputStream = new ByteArrayInputStream(documentEntity.getContent().getBytes())) {
+ resource.load(inputStream, null);
+ } catch (IOException exception) {
+ this.logger.warn(exception.getMessage(), exception);
+ }
+ resourceSet.getResources().add(resource);
+ }
+ }
+ return result;
+ }
+
+ private String getDomainContent() {
+ Domain domain = DomainFactory.eINSTANCE.createDomain();
+ domain.setName(new SysONDomainNameProvider().getSampleDomainName());
+
+ Entity root = DomainFactory.eINSTANCE.createEntity();
+ root.setName("Root");
+ domain.getTypes().add(root);
+
+ Entity entity1 = DomainFactory.eINSTANCE.createEntity();
+ entity1.setName("Entity1");
+ domain.getTypes().add(entity1);
+
+ Relation entity1s = DomainFactory.eINSTANCE.createRelation();
+ entity1s.setName("entity1s");
+ entity1s.setContainment(true);
+ entity1s.setOptional(true);
+ entity1s.setMany(true);
+ entity1s.setTargetType(entity1);
+ root.getRelations().add(entity1s);
+
+ Entity entity2 = DomainFactory.eINSTANCE.createEntity();
+ entity2.setName("Entity2");
+ domain.getTypes().add(entity2);
+
+ Relation entity2s = DomainFactory.eINSTANCE.createRelation();
+ entity2s.setName("entity2s");
+ entity2s.setContainment(true);
+ entity2s.setOptional(true);
+ entity2s.setMany(true);
+ entity2s.setTargetType(entity2);
+ root.getRelations().add(entity2s);
+
+ Relation linkedTo = DomainFactory.eINSTANCE.createRelation();
+ linkedTo.setName("linkedTo");
+ linkedTo.setContainment(false);
+ linkedTo.setOptional(true);
+ linkedTo.setMany(true);
+ linkedTo.setTargetType(entity2);
+ entity1.getRelations().add(linkedTo);
+
+ this.addAttribute(entity1, NAME_ATTRIBUTE, DataType.STRING);
+ this.addAttribute(entity1, "attribute2", DataType.BOOLEAN);
+ this.addAttribute(entity1, "attribute3", DataType.NUMBER);
+ this.addAttribute(entity2, NAME_ATTRIBUTE, DataType.STRING);
+
+ return this.stereotypeBuilder.getStereotypeBody(List.of(domain));
+ }
+
+ private void addAttribute(Entity entity, String name, DataType type) {
+ Attribute attr = DomainFactory.eINSTANCE.createAttribute();
+ attr.setName(name);
+ attr.setOptional(true);
+ attr.setType(type);
+ entity.getAttributes().add(attr);
+ }
+
+ @SuppressWarnings("checkstyle:MultipleStringLiterals")
+ private String getViewContent(String domainName) {
+ View view = ViewFactory.eINSTANCE.createView();
+ DefaultToolsFactory defaultToolsFactory = new DefaultToolsFactory();
+
+ org.eclipse.sirius.components.view.diagram.DiagramDescription viewDiagramDescription = DiagramFactory.eINSTANCE.createDiagramDescription();
+ viewDiagramDescription.setName(domainName + " Diagram Description");
+ viewDiagramDescription.setDomainType(domainName + "::Root");
+ viewDiagramDescription.setTitleExpression(domainName + " diagram");
+ viewDiagramDescription.setPalette(defaultToolsFactory.createDefaultDiagramPalette());
+ view.getDescriptions().add(viewDiagramDescription);
+
+ view.getColorPalettes().add(this.createColorPalette());
+
+ NodeDescription entity1Node = DiagramFactory.eINSTANCE.createNodeDescription();
+ entity1Node.setName("Entity1 Node");
+ entity1Node.setDomainType(domainName + "::Entity1");
+ entity1Node.setSemanticCandidatesExpression("aql:self.eContents()");
+ entity1Node.setLabelExpression("aql:self.name");
+ entity1Node.setSynchronizationPolicy(SynchronizationPolicy.SYNCHRONIZED);
+ entity1Node.setStyle(this.createRectangularNodeStyle(view, "color_blue", "border_blue"));
+ entity1Node.setPalette(defaultToolsFactory.createDefaultNodePalette());
+
+ viewDiagramDescription.getNodeDescriptions().add(entity1Node);
+ viewDiagramDescription.getPalette().getNodeTools().add(this.createNewInstanceTool(domainName + "::Entity1", "entity1s"));
+
+ NodeDescription entity2Node = DiagramFactory.eINSTANCE.createNodeDescription();
+ entity2Node.setName("Entity2 Node");
+ entity2Node.setDomainType(domainName + "::Entity2");
+ entity2Node.setSemanticCandidatesExpression("aql:self.eContents()");
+ entity2Node.setLabelExpression("aql:self.name");
+ entity2Node.setSynchronizationPolicy(SynchronizationPolicy.SYNCHRONIZED);
+ entity2Node.setStyle(this.createRectangularNodeStyle(view, "color_green", "border_green"));
+ entity2Node.setPalette(defaultToolsFactory.createDefaultNodePalette());
+
+ viewDiagramDescription.getNodeDescriptions().add(entity2Node);
+ viewDiagramDescription.getPalette().getNodeTools().add(this.createNewInstanceTool(domainName + "::Entity2", "entity2s"));
+
+ EdgeTool createLinkTo = DiagramFactory.eINSTANCE.createEdgeTool();
+ createLinkTo.setName("Link to");
+ createLinkTo.getTargetElementDescriptions().add(entity2Node);
+ ChangeContext gotoSemanticSource = ViewFactory.eINSTANCE.createChangeContext();
+ gotoSemanticSource.setExpression("aql:semanticEdgeSource");
+ createLinkTo.getBody().add(gotoSemanticSource);
+ SetValue setLink = ViewFactory.eINSTANCE.createSetValue();
+ setLink.setFeatureName("linkedTo");
+ setLink.setValueExpression("aql:semanticEdgeTarget");
+ gotoSemanticSource.getChildren().add(setLink);
+ entity1Node.getPalette().getEdgeTools().add(createLinkTo);
+
+ EdgeDescription linkedToEdge = DiagramFactory.eINSTANCE.createEdgeDescription();
+ linkedToEdge.setName("LinkedTo Edge");
+ linkedToEdge.setSemanticCandidatesExpression("");
+ linkedToEdge.setLabelExpression("");
+ linkedToEdge.getSourceNodeDescriptions().add(entity1Node);
+ linkedToEdge.setSourceNodesExpression("aql:self");
+ linkedToEdge.getTargetNodeDescriptions().add(entity2Node);
+ linkedToEdge.setTargetNodesExpression("aql:self.linkedTo");
+ linkedToEdge.setPalette(defaultToolsFactory.createDefaultEdgePalette());
+ viewDiagramDescription.getEdgeDescriptions().add(linkedToEdge);
+
+ EdgeStyle edgeStyle = DiagramFactory.eINSTANCE.createEdgeStyle();
+ edgeStyle.setColor(this.getColorFromPalette(view, "color_dark"));
+ linkedToEdge.setStyle(edgeStyle);
+
+ return this.stereotypeBuilder.getStereotypeBody(List.of(view));
+ }
+
+ private RectangularNodeStyleDescription createRectangularNodeStyle(View view, String color, String borderColor) {
+ RectangularNodeStyleDescription entity2Style = DiagramFactory.eINSTANCE.createRectangularNodeStyleDescription();
+ entity2Style.setWidthComputationExpression("150");
+ entity2Style.setHeightComputationExpression("70");
+ entity2Style.setColor(this.getColorFromPalette(view, color));
+ entity2Style.setBorderColor(this.getColorFromPalette(view, borderColor));
+ entity2Style.setBorderRadius(3);
+ return entity2Style;
+ }
+
+ private NodeTool createNewInstanceTool(String typeName, String referenceName) {
+ String simpleName = typeName.split("::")[1];
+ NodeTool tool = DiagramFactory.eINSTANCE.createNodeTool();
+ tool.setName("New " + simpleName);
+
+ CreateInstance createInstance = ViewFactory.eINSTANCE.createCreateInstance();
+ createInstance.setReferenceName(referenceName);
+ createInstance.setTypeName(typeName);
+ createInstance.setVariableName("newInstance");
+ tool.getBody().add(createInstance);
+
+ ChangeContext gotoNewInstance = ViewFactory.eINSTANCE.createChangeContext();
+ gotoNewInstance.setExpression("aql:newInstance");
+ createInstance.getChildren().add(gotoNewInstance);
+
+ SetValue setInitialName = ViewFactory.eINSTANCE.createSetValue();
+ setInitialName.setFeatureName(NAME_ATTRIBUTE);
+ setInitialName.setValueExpression("New" + simpleName);
+ gotoNewInstance.getChildren().add(setInitialName);
+
+ return tool;
+ }
+
+ private Optional findDiagramDescription(IEditingContext editingContext, String label) {
+ // @formatter:off
+ return this.representationDescriptionSearchService.findAll(editingContext).values().stream()
+ .filter(DiagramDescription.class::isInstance)
+ .map(DiagramDescription.class::cast)
+ .filter(diagramDescription -> Objects.equals(label, diagramDescription.getLabel()))
+ .findFirst();
+ // @formatter:on
+ }
+
+ private ColorPalette createColorPalette() {
+ var colorPalette = ViewFactory.eINSTANCE.createColorPalette();
+
+ colorPalette.getColors().add(this.createFixedColor("color_dark", "#002639"));
+ colorPalette.getColors().add(this.createFixedColor("color_blue", "#E5F5F8"));
+ colorPalette.getColors().add(this.createFixedColor("color_green", "#B1D8B7"));
+ colorPalette.getColors().add(this.createFixedColor("border_blue", "#33B0C3"));
+ colorPalette.getColors().add(this.createFixedColor("border_green", "#76B947"));
+
+ return colorPalette;
+ }
+
+ private FixedColor createFixedColor(String name, String value) {
+ var fixedColor = ViewFactory.eINSTANCE.createFixedColor();
+ fixedColor.setName(name);
+ fixedColor.setValue(value);
+ return fixedColor;
+ }
+
+ private UserColor getColorFromPalette(View view, String colorName) {
+ return view.getColorPalettes()
+ .stream()
+ .findFirst()
+ .map(ColorPalette::getColors)
+ .stream()
+ .flatMap(Collection::stream)
+ .filter(userColor -> userColor.getName().equals(colorName))
+ .findFirst()
+ .orElse(null);
+ }
+
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/StudioProjectTemplatesProvider.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/StudioProjectTemplatesProvider.java
new file mode 100644
index 0000000..8683640
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/StudioProjectTemplatesProvider.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.configuration;
+
+import java.util.List;
+
+import org.eclipse.sirius.web.services.api.projects.IProjectTemplateProvider;
+import org.eclipse.sirius.web.services.api.projects.Nature;
+import org.eclipse.sirius.web.services.api.projects.ProjectTemplate;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Provides Studio-specific project templates.
+ *
+ * @author pcdavid
+ */
+@Configuration
+public class StudioProjectTemplatesProvider implements IProjectTemplateProvider {
+
+ public static final String STUDIO_TEMPLATE_ID = "studio-template";
+
+ public static final String BLANK_STUDIO_TEMPLATE_ID = "blank-studio-template";
+
+ @Override
+ public List getProjectTemplates() {
+ var studioTemplate = ProjectTemplate.newProjectTemplate(STUDIO_TEMPLATE_ID)
+ .label("Studio")
+ .imageURL("/images/Studio-Template.png")
+ .natures(List.of(new Nature("siriusComponents://nature?kind=studio")))
+ .build();
+ var blankStudioTemplate = ProjectTemplate.newProjectTemplate(BLANK_STUDIO_TEMPLATE_ID)
+ .label("Blank Studio")
+ .imageURL("/images/Studio-Template.png")
+ .natures(List.of(new Nature("siriusComponents://nature?kind=studio")))
+ .build();
+ return List.of(studioTemplate, blankStudioTemplate);
+ }
+
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/SysONDomainNameProvider.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/SysONDomainNameProvider.java
new file mode 100644
index 0000000..8e57a49
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/SysONDomainNameProvider.java
@@ -0,0 +1,272 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.configuration;
+
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Provides a sample domain name which has a good chance to be unique though it is not guaranteed.
+ *
+ * @author pcdavid
+ */
+public class SysONDomainNameProvider {
+ // @formatter:off
+ private final List sampleDomainNames = List.of(
+ "agnesi",
+ "albattani",
+ "allen",
+ "almeida",
+ "antonelli",
+ "archimedes",
+ "ardinghelli",
+ "aryabhata",
+ "austin",
+ "babbage",
+ "banach",
+ "banzai",
+ "bardeen",
+ "bartik",
+ "bassi",
+ "beaver",
+ "bell",
+ "benz",
+ "bhabha",
+ "bhaskara",
+ "black",
+ "blackburn",
+ "blackwell",
+ "bohr",
+ "booth",
+ "borg",
+ "bose",
+ "bouman",
+ "boyd",
+ "brahmagupta",
+ "brattain",
+ "brown",
+ "buck",
+ "burnell",
+ "cannon",
+ "carson",
+ "cartwright",
+ "carver",
+ "cerf",
+ "chandrasekhar",
+ "chaplygin",
+ "chatelet",
+ "chatterjee",
+ "chaum",
+ "chebyshev",
+ "clarke",
+ "cohen",
+ "colden",
+ "cori",
+ "cray",
+ "curran",
+ "curie",
+ "darwin",
+ "davinci",
+ "dewdney",
+ "dhawan",
+ "diffie",
+ "dijkstra",
+ "dirac",
+ "driscoll",
+ "dubinsky",
+ "easley",
+ "edison",
+ "einstein",
+ "elbakyan",
+ "elgamal",
+ "elion",
+ "ellis",
+ "engelbart",
+ "euclid",
+ "euler",
+ "faraday",
+ "feistel",
+ "fermat",
+ "fermi",
+ "feynman",
+ "franklin",
+ "gagarin",
+ "galileo",
+ "galois",
+ "ganguly",
+ "gates",
+ "gauss",
+ "germain",
+ "goldberg",
+ "goldstine",
+ "goldwasser",
+ "golick",
+ "goodall",
+ "gould",
+ "greider",
+ "grothendieck",
+ "haibt",
+ "hamilton",
+ "haslett",
+ "hawking",
+ "hellman",
+ "heisenberg",
+ "hermann",
+ "herschel",
+ "hertz",
+ "heyrovsky",
+ "hodgkin",
+ "hofstadter",
+ "hoover",
+ "hopper",
+ "hugle",
+ "hypatia",
+ "ishizaka",
+ "jackson",
+ "jang",
+ "jemison",
+ "jennings",
+ "jepsen",
+ "johnson",
+ "joliot",
+ "jones",
+ "kalam",
+ "kapitsa",
+ "kare",
+ "keldysh",
+ "keller",
+ "kepler",
+ "khayyam",
+ "khorana",
+ "kilby",
+ "kirch",
+ "knuth",
+ "kowalevski",
+ "lalande",
+ "lamarr",
+ "lamport",
+ "leakey",
+ "leavitt",
+ "lederberg",
+ "lehmann",
+ "lewin",
+ "lichterman",
+ "liskov",
+ "lovelace",
+ "lumiere",
+ "mahavira",
+ "margulis",
+ "matsumoto",
+ "maxwell",
+ "mayer",
+ "mccarthy",
+ "mcclintock",
+ "mclaren",
+ "mclean",
+ "mcnulty",
+ "mendel",
+ "mendeleev",
+ "meitner",
+ "meninsky",
+ "merkle",
+ "mestorf",
+ "mirzakhani",
+ "montalcini",
+ "moore",
+ "morse",
+ "murdock",
+ "moser",
+ "napier",
+ "nash",
+ "neumann",
+ "newton",
+ "nightingale",
+ "nobel",
+ "noether",
+ "northcutt",
+ "noyce",
+ "panini",
+ "pare",
+ "pascal",
+ "pasteur",
+ "payne",
+ "perlman",
+ "pike",
+ "poincare",
+ "poitras",
+ "proskuriakova",
+ "ptolemy",
+ "raman",
+ "ramanujan",
+ "ride",
+ "ritchie",
+ "rhodes",
+ "robinson",
+ "roentgen",
+ "rosalind",
+ "rubin",
+ "saha",
+ "sammet",
+ "sanderson",
+ "satoshi",
+ "shamir",
+ "shannon",
+ "shaw",
+ "shirley",
+ "shockley",
+ "shtern",
+ "sinoussi",
+ "snyder",
+ "solomon",
+ "spence",
+ "stonebraker",
+ "sutherland",
+ "swanson",
+ "swartz",
+ "swirles",
+ "taussig",
+ "tereshkova",
+ "tesla",
+ "tharp",
+ "thompson",
+ "torvalds",
+ "tu",
+ "turing",
+ "varahamihira",
+ "vaughan",
+ "villani",
+ "visvesvaraya",
+ "volhard",
+ "wescoff",
+ "wilbur",
+ "wiles",
+ "williams",
+ "williamson",
+ "wilson",
+ "wing",
+ "wozniak",
+ "wright",
+ "wu",
+ "yalow",
+ "yonath",
+ "zhukovsky"
+ );
+ // @formatter:on
+
+ private final Random random = new Random();
+
+ public String getSampleDomainName() {
+ int randomIndex = this.random.nextInt(this.sampleDomainNames.size());
+ return this.sampleDomainNames.get(randomIndex);
+ }
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/SysONEMFConfiguration.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/SysONEMFConfiguration.java
new file mode 100644
index 0000000..1b1f82f
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/SysONEMFConfiguration.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.configuration;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.sirius.components.domain.DomainPackage;
+import org.eclipse.sirius.components.domain.provider.DomainItemProviderAdapterFactory;
+import org.eclipse.sirius.components.emf.configuration.ChildExtenderProvider;
+import org.eclipse.sirius.components.view.ViewPackage;
+import org.eclipse.sirius.components.view.diagram.DiagramPackage;
+import org.eclipse.sirius.components.view.diagram.provider.DiagramItemProviderAdapterFactory;
+import org.eclipse.sirius.components.view.form.FormPackage;
+import org.eclipse.sirius.components.view.form.provider.FormItemProviderAdapterFactory;
+import org.eclipse.sirius.components.view.provider.ViewItemProviderAdapterFactory;
+import org.eclipse.sirius.web.customnodes.CustomnodesPackage;
+import org.eclipse.sirius.web.customnodes.provider.CustomnodesItemProviderAdapterFactory;
+import org.eclipse.sirius.web.customwidgets.CustomwidgetsPackage;
+import org.eclipse.sirius.web.customwidgets.provider.CustomwidgetsItemProviderAdapterFactory;
+import org.eclipse.syson.sysml.SysmlPackage;
+import org.eclipse.syson.sysml.provider.SysmlItemProviderAdapterFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Configuration of the EMF support for Sirius Web.
+ *
+ * @author arichard
+ */
+@Configuration
+public class SysONEMFConfiguration {
+ @Bean
+ AdapterFactory sysmlAdapterFactory() {
+ return new SysmlItemProviderAdapterFactory();
+ }
+
+ @Bean
+ EPackage sysmlEPackage() {
+ return SysmlPackage.eINSTANCE;
+ }
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ EPackage domainEPackage() {
+ return DomainPackage.eINSTANCE;
+ }
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ AdapterFactory domainAdapterFactory() {
+ return new DomainItemProviderAdapterFactory();
+ }
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ EPackage viewEPackage() {
+ return ViewPackage.eINSTANCE;
+ }
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ AdapterFactory viewAdapterFactory() {
+ return new ViewItemProviderAdapterFactory();
+ }
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ EPackage viewDiagramEPackage() {
+ return DiagramPackage.eINSTANCE;
+ }
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ AdapterFactory diagramAdapterFactory() {
+ return new DiagramItemProviderAdapterFactory();
+ }
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ ChildExtenderProvider diagramChildExtenderProvider() {
+ return new ChildExtenderProvider(ViewPackage.eNS_URI, DiagramItemProviderAdapterFactory.ViewChildCreationExtender::new);
+ }
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ EPackage viewFormEPackage() {
+ return FormPackage.eINSTANCE;
+ }
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ AdapterFactory formAdapterFactory() {
+ return new FormItemProviderAdapterFactory();
+ }
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ ChildExtenderProvider formChildExtenderProvider() {
+ return new ChildExtenderProvider(ViewPackage.eNS_URI, FormItemProviderAdapterFactory.ViewChildCreationExtender::new);
+ }
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ EPackage customWidgetsEPackage() {
+ return CustomwidgetsPackage.eINSTANCE;
+ }
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ AdapterFactory customWidgetsAdapterFactory() {
+ return new CustomwidgetsItemProviderAdapterFactory();
+ }
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ ChildExtenderProvider sliderChildExtenderProvider() {
+ return new ChildExtenderProvider(FormPackage.eNS_URI, CustomwidgetsItemProviderAdapterFactory.FormChildCreationExtender::new);
+ }
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ EPackage customNodesEPackage() {
+ return CustomnodesPackage.eINSTANCE;
+ }
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ AdapterFactory customNodesAdapterFactory() {
+ return new CustomnodesItemProviderAdapterFactory();
+ }
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ ChildExtenderProvider customNodesChildExtenderProvider() {
+ return new ChildExtenderProvider(DiagramPackage.eNS_URI, CustomnodesItemProviderAdapterFactory.DiagramChildCreationExtender::new);
+ }
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/SysONSiriusConfiguration.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/SysONSiriusConfiguration.java
new file mode 100644
index 0000000..fa8cf0d
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/configuration/SysONSiriusConfiguration.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.configuration;
+
+import java.util.List;
+
+import org.eclipse.sirius.components.compatibility.services.api.ISiriusConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Configuration of the Sirius compatibility layer.
+ *
+ * @author arichard
+ */
+@Configuration
+public class SysONSiriusConfiguration implements ISiriusConfiguration {
+
+ @Override
+ public List getODesignPaths() {
+ return List.of();
+ }
+
+ @Bean
+ @ConditionalOnProperty(prefix = "org.eclipse.sirius.web.features", name = "studioDefinition")
+ ISiriusConfiguration domainModelerDefinition() {
+ return () -> List.of("description/domain.odesign");
+ }
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/filters/SiriusWebAuthenticationFilter.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/filters/SiriusWebAuthenticationFilter.java
new file mode 100644
index 0000000..ced2456
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/filters/SiriusWebAuthenticationFilter.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.filters;
+
+import java.io.IOException;
+import java.util.Base64;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletRequestWrapper;
+
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.HttpHeaders;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.GenericFilterBean;
+
+/**
+ * Filter used to provide the authentication support.
+ *
+ * @author sbegaudeau
+ */
+@Component
+@Order(Ordered.HIGHEST_PRECEDENCE)
+public class SiriusWebAuthenticationFilter extends GenericFilterBean {
+
+ private final String authorizationHeader;
+
+ public SiriusWebAuthenticationFilter() {
+ String rawCredentials = "system:012345678910";
+ String credentials = Base64.getEncoder().encodeToString(rawCredentials.getBytes());
+ this.authorizationHeader = "Basic " + credentials;
+ }
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+ if (request instanceof HttpServletRequest) {
+ HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+ HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(httpServletRequest) {
+ @Override
+ public Enumeration getHeaders(String name) {
+ if (name.equals(HttpHeaders.AUTHORIZATION)) {
+ return Collections.enumeration(List.of(SiriusWebAuthenticationFilter.this.authorizationHeader));
+ }
+ return super.getHeaders(name);
+ }
+
+ @Override
+ public String getHeader(String name) {
+ if (name.equals(HttpHeaders.AUTHORIZATION)) {
+ return SiriusWebAuthenticationFilter.this.authorizationHeader;
+ }
+ return super.getHeader(name);
+ }
+ };
+ chain.doFilter(wrapper, response);
+ } else {
+ chain.doFilter(request, response);
+ }
+ }
+
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/nodes/ellipse/EllipseNodeStyle.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/nodes/ellipse/EllipseNodeStyle.java
new file mode 100644
index 0000000..6270b19
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/nodes/ellipse/EllipseNodeStyle.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.nodes.ellipse;
+
+import java.text.MessageFormat;
+import java.util.Objects;
+
+import org.eclipse.sirius.components.annotations.Immutable;
+import org.eclipse.sirius.components.diagrams.INodeStyle;
+import org.eclipse.sirius.components.diagrams.LineStyle;
+
+/**
+ * The ellipse node style.
+ *
+ * @author frouene
+ */
+@Immutable
+public final class EllipseNodeStyle implements INodeStyle {
+
+ private String color;
+
+ private String borderColor;
+
+ private int borderSize;
+
+ private LineStyle borderStyle;
+
+ private EllipseNodeStyle() {
+ // Prevent instantiation
+ }
+
+ public static Builder newEllipseNodeStyle() {
+ return new Builder();
+ }
+
+ public String getColor() {
+ return this.color;
+ }
+
+ public String getBorderColor() {
+ return this.borderColor;
+ }
+
+ public int getBorderSize() {
+ return this.borderSize;
+ }
+
+ public LineStyle getBorderStyle() {
+ return this.borderStyle;
+ }
+
+ @Override
+ public String toString() {
+ String pattern = "{0} '{'color: {1}, border: '{' color: {2}, size: {3}, style: {4} '}''}'";
+ return MessageFormat.format(pattern, this.getClass().getSimpleName(), this.color, this.borderColor, this.borderSize, this.borderStyle);
+ }
+
+ /**
+ * The builder used to create the ellipse node style.
+ *
+ * @author hmarchadour
+ */
+ @SuppressWarnings("checkstyle:HiddenField")
+ public static final class Builder {
+
+ private String color;
+
+ private String borderColor;
+
+ private int borderSize;
+
+ private LineStyle borderStyle;
+
+ private Builder() {
+ // Prevent instantiation
+ }
+
+ public Builder color(String color) {
+ this.color = Objects.requireNonNull(color);
+ return this;
+ }
+
+ public Builder borderColor(String borderColor) {
+ this.borderColor = Objects.requireNonNull(borderColor);
+ return this;
+ }
+
+ public Builder borderSize(int borderSize) {
+ this.borderSize = borderSize;
+ return this;
+ }
+
+ public Builder borderStyle(LineStyle borderStyle) {
+ this.borderStyle = Objects.requireNonNull(borderStyle);
+ return this;
+ }
+
+ public EllipseNodeStyle build() {
+ EllipseNodeStyle nodeStyleDescription = new EllipseNodeStyle();
+ nodeStyleDescription.color = Objects.requireNonNull(this.color);
+ nodeStyleDescription.borderColor = Objects.requireNonNull(this.borderColor);
+ nodeStyleDescription.borderSize = this.borderSize;
+ nodeStyleDescription.borderStyle = Objects.requireNonNull(this.borderStyle);
+ return nodeStyleDescription;
+ }
+ }
+}
\ No newline at end of file
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/nodes/ellipse/EllipseNodeStyleProvider.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/nodes/ellipse/EllipseNodeStyleProvider.java
new file mode 100644
index 0000000..a9c893c
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/nodes/ellipse/EllipseNodeStyleProvider.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.nodes.ellipse;
+
+import java.util.Optional;
+
+import org.eclipse.sirius.components.diagrams.INodeStyle;
+import org.eclipse.sirius.components.diagrams.LineStyle;
+import org.eclipse.sirius.components.view.FixedColor;
+import org.eclipse.sirius.components.view.diagram.NodeStyleDescription;
+import org.eclipse.sirius.components.view.emf.diagram.INodeStyleProvider;
+import org.eclipse.sirius.web.customnodes.EllipseNodeStyleDescription;
+import org.springframework.stereotype.Service;
+
+/**
+ * This class provides style information for the custom node ellipse.
+ *
+ * @author frouene
+ */
+@Service
+public class EllipseNodeStyleProvider implements INodeStyleProvider {
+
+ public static final String NODE_ELLIPSE = "customnode:ellipse";
+
+ @Override
+ public Optional getNodeType(NodeStyleDescription nodeStyle) {
+ if (nodeStyle instanceof EllipseNodeStyleDescription) {
+ return Optional.of(NODE_ELLIPSE);
+ }
+ return Optional.empty();
+ }
+
+ @Override
+ public Optional createNodeStyle(NodeStyleDescription nodeStyle, Optional optionalEditingContextId) {
+ Optional iNodeStyle = Optional.empty();
+ Optional nodeType = this.getNodeType(nodeStyle);
+ if (nodeType.isPresent()) {
+ return Optional.of(EllipseNodeStyle.newEllipseNodeStyle()
+ .color(Optional.ofNullable(nodeStyle.getColor())
+ .filter(FixedColor.class::isInstance)
+ .map(FixedColor.class::cast)
+ .map(FixedColor::getValue)
+ .orElse("transparent"))
+ .borderColor(Optional.ofNullable(nodeStyle.getBorderColor())
+ .filter(FixedColor.class::isInstance)
+ .map(FixedColor.class::cast)
+ .map(FixedColor::getValue)
+ .orElse("black"))
+ .borderSize(nodeStyle.getBorderSize())
+ .borderStyle(LineStyle.valueOf(nodeStyle.getBorderLineStyle().getLiteral()))
+ .build());
+ }
+
+ return iNodeStyle;
+ }
+}
\ No newline at end of file
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/services/DomainAttributeServices.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/DomainAttributeServices.java
new file mode 100644
index 0000000..7db3b9a
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/DomainAttributeServices.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.services;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.sirius.components.core.api.IFeedbackMessageService;
+import org.eclipse.sirius.components.domain.Attribute;
+import org.eclipse.sirius.components.domain.DataType;
+import org.eclipse.sirius.components.representations.Message;
+import org.eclipse.sirius.components.representations.MessageLevel;
+import org.eclipse.sirius.components.view.form.FormDescription;
+
+/**
+ * Java services needed to execute the AQL expressions used in the {@link FormDescription} created.
+ *
+ * @author pcdavid
+ */
+public final class DomainAttributeServices {
+
+ private final IFeedbackMessageService feedbackMessageService;
+
+ public DomainAttributeServices(IFeedbackMessageService feedbackMessageService) {
+ this.feedbackMessageService = Objects.requireNonNull(feedbackMessageService);
+ }
+
+ public List getAvailableDataTypes(EObject self) {
+ return DataType.VALUES.stream().map(DataType::getName).toList();
+ }
+
+ public String getDataType(Attribute attr) {
+ return Optional.ofNullable(attr.getType()).map(DataType::getName).orElse(null);
+ }
+
+ public EObject setDataType(Attribute attr, String typeName) {
+ var type = DataType.getByName(typeName);
+ attr.setType(type);
+ if (type == null) {
+ this.feedbackMessageService.addFeedbackMessage(new Message("Reverting type of %s to the default type %s".formatted(attr.getName(),
+ this.capitalize(DataType.STRING.getLiteral())), MessageLevel.WARNING));
+ }
+ return attr;
+ }
+
+ public EObject setValue(EObject eObject, String attributeName, Object value) {
+ eObject.eSet(eObject.eClass().getEStructuralFeature(attributeName), value);
+ return eObject;
+ }
+
+ public String capitalize(String str) {
+ return str.substring(0, 1).toUpperCase().concat(str.substring(1).toLowerCase());
+ }
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/services/EditingContextActionHandler.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/EditingContextActionHandler.java
new file mode 100644
index 0000000..bd8683a
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/EditingContextActionHandler.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.services;
+
+import static org.eclipse.syson.services.EditingContextActionProvider.EMPTY_ACTION_ID;
+import static org.eclipse.syson.services.EditingContextActionProvider.EMPTY_DOMAIN_ID;
+import static org.eclipse.syson.services.EditingContextActionProvider.EMPTY_SYSML_ID;
+import static org.eclipse.syson.services.EditingContextActionProvider.EMPTY_VIEW_ID;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.function.Consumer;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.xmi.XMLParserPool;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
+import org.eclipse.emf.ecore.xmi.impl.XMLParserPoolImpl;
+import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
+import org.eclipse.sirius.components.collaborative.api.ChangeKind;
+import org.eclipse.sirius.components.collaborative.api.IEditingContextActionHandler;
+import org.eclipse.sirius.components.core.api.IEditingContext;
+import org.eclipse.sirius.components.domain.Domain;
+import org.eclipse.sirius.components.domain.DomainFactory;
+import org.eclipse.sirius.components.emf.ResourceMetadataAdapter;
+import org.eclipse.sirius.components.emf.services.EditingContext;
+import org.eclipse.sirius.components.emf.services.JSONResourceFactory;
+import org.eclipse.sirius.components.emf.utils.EMFResourceUtils;
+import org.eclipse.sirius.components.representations.Failure;
+import org.eclipse.sirius.components.representations.IStatus;
+import org.eclipse.sirius.components.representations.Success;
+import org.eclipse.sirius.components.view.View;
+import org.eclipse.sirius.components.view.ViewFactory;
+import org.eclipse.sirius.components.view.diagram.DiagramDescription;
+import org.eclipse.sirius.components.view.diagram.DiagramFactory;
+import org.eclipse.sirius.emfjson.resource.JsonResource;
+import org.eclipse.syson.configuration.SysONDomainNameProvider;
+import org.eclipse.syson.sysml.SysmlFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.stereotype.Service;
+
+
+/**
+ * Handler used to perform an action on the editingContext.
+ *
+ * @author frouene
+ */
+@Service
+public class EditingContextActionHandler implements IEditingContextActionHandler {
+
+ private static final XMLParserPool PARSER_POOL = new XMLParserPoolImpl();
+
+ private static final List HANDLED_ACTIONS = List.of(EMPTY_ACTION_ID, EMPTY_SYSML_ID, EMPTY_DOMAIN_ID);
+
+ private final Logger logger = LoggerFactory.getLogger(EditingContextActionHandler.class);
+
+ private final SysONDomainNameProvider domainNameProvider;
+
+ public EditingContextActionHandler() {
+ this.domainNameProvider = new SysONDomainNameProvider();
+ }
+
+ @Override
+ public boolean canHandle(IEditingContext editingContext, String actionId) {
+ return HANDLED_ACTIONS.contains(actionId);
+ }
+
+ @Override
+ public IStatus handle(IEditingContext editingContext, String actionId) {
+ return Optional.of(editingContext)
+ .filter(EditingContext.class::isInstance)
+ .map(EditingContext.class::cast)
+ .map(EditingContext::getDomain)
+ .map(AdapterFactoryEditingDomain::getResourceSet)
+ .map(resourceSet -> this.performActionOnResourceSet(resourceSet, actionId))
+ .orElse(new Failure("Something went wrong while handling this action."));
+ }
+
+ private IStatus performActionOnResourceSet(ResourceSet resourceSet, String actionId) {
+ return switch (actionId) {
+ case EMPTY_ACTION_ID -> this.createResourceAndReturnSuccess(resourceSet, this::createEmptyResource);
+ case EMPTY_SYSML_ID -> this.createResourceAndReturnSuccess(resourceSet, this::createEmptySysMLResource);
+ case EMPTY_DOMAIN_ID -> this.createResourceAndReturnSuccess(resourceSet, this::createEmptyDomainResource);
+ case EMPTY_VIEW_ID -> this.createResourceAndReturnSuccess(resourceSet, this::createEmptyViewResource);
+ default -> new Failure("Unknown action.");
+ };
+
+ }
+
+ private IStatus createResourceAndReturnSuccess(ResourceSet resourceSet, Consumer createResource) {
+ createResource.accept(resourceSet);
+ return new Success(ChangeKind.SEMANTIC_CHANGE, Map.of());
+ }
+
+ private void createEmptyResource(ResourceSet resourceSet) {
+ JsonResource resource = new JSONResourceFactory().createResourceFromPath(UUID.randomUUID().toString());
+ resource.eAdapters().add(new ResourceMetadataAdapter("Others..."));
+ resourceSet.getResources().add(resource);
+ }
+
+ private void createEmptySysMLResource(ResourceSet resourceSet) {
+ JsonResource resource = new JSONResourceFactory().createResourceFromPath(UUID.randomUUID().toString());
+ resource.getContents().add(SysmlFactory.eINSTANCE.createPackage());
+ resource.eAdapters().add(new ResourceMetadataAdapter("SysML"));
+ resourceSet.getResources().add(resource);
+ }
+
+ private void createEmptyDomainResource(ResourceSet resourceSet) {
+ JsonResource resource = new JSONResourceFactory().createResourceFromPath(UUID.randomUUID().toString());
+ Domain domain = DomainFactory.eINSTANCE.createDomain();
+ domain.setName(this.domainNameProvider.getSampleDomainName());
+ resource.getContents().add(domain);
+ resource.eAdapters().add(new ResourceMetadataAdapter("Domain"));
+ resourceSet.getResources().add(resource);
+ }
+
+ private void createEmptyViewResource(ResourceSet resourceSet) {
+ View newView = ViewFactory.eINSTANCE.createView();
+ DiagramDescription diagramDescription = DiagramFactory.eINSTANCE.createDiagramDescription();
+ diagramDescription.setName("New Diagram Description");
+ newView.getDescriptions().add(diagramDescription);
+
+ JsonResource resource = new JSONResourceFactory().createResourceFromPath(UUID.randomUUID().toString());
+ resource.getContents().add(newView);
+ resource.eAdapters().add(new ResourceMetadataAdapter("View"));
+ resourceSet.getResources().add(resource);
+ }
+
+ public Optional getResourceFromClassPathResource(ClassPathResource classPathResource) {
+
+ try (var inputStream = classPathResource.getInputStream()) {
+ URI uri = new JSONResourceFactory().createResourceURI(UUID.randomUUID().toString());
+ return Optional.of(this.loadFromXMIAndTransformToJSONResource(uri, inputStream));
+ } catch (IOException exception) {
+ this.logger.error(exception.getMessage(), exception);
+ return Optional.empty();
+ }
+ }
+
+ private Resource loadFromXMIAndTransformToJSONResource(URI uri, InputStream inputStream) throws IOException {
+ Resource inputResource = new XMIResourceImpl(uri);
+ Map xmiLoadOptions = new EMFResourceUtils().getXMILoadOptions(PARSER_POOL);
+ inputResource.load(inputStream, xmiLoadOptions);
+ return this.transformToJSON(uri, inputResource);
+ }
+
+ private JsonResource transformToJSON(URI uri, Resource inputResource) throws IOException {
+ JsonResource outputResource = new JSONResourceFactory().createResource(uri);
+ outputResource.getContents().addAll(inputResource.getContents());
+ try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
+ Map jsonSaveOptions = new EMFResourceUtils().getFastJSONSaveOptions();
+ jsonSaveOptions.put(JsonResource.OPTION_ENCODING, JsonResource.ENCODING_UTF_8);
+ jsonSaveOptions.put(JsonResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
+ outputResource.save(outputStream, jsonSaveOptions);
+ }
+ return outputResource;
+ }
+
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/services/EditingContextActionProvider.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/EditingContextActionProvider.java
new file mode 100644
index 0000000..8a36142
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/EditingContextActionProvider.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.services;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.sirius.components.collaborative.api.IEditingContextActionProvider;
+import org.eclipse.sirius.components.collaborative.dto.EditingContextAction;
+import org.eclipse.sirius.components.core.api.IEditingContext;
+import org.eclipse.sirius.components.domain.DomainPackage;
+import org.eclipse.sirius.components.emf.services.EditingContext;
+import org.eclipse.sirius.components.view.ViewPackage;
+import org.springframework.stereotype.Service;
+
+/**
+ * Provides the list of possible actions on the editingContext.
+ *
+ * @author frouene
+ */
+@Service
+public class EditingContextActionProvider implements IEditingContextActionProvider {
+
+ public static final String EMPTY_ACTION_ID = "empty";
+
+ public static final String EMPTY_SYSML_ID = "empty_sysml";
+
+ public static final String EMPTY_DOMAIN_ID = "empty_domain";
+
+ public static final String EMPTY_VIEW_ID = "empty_view";
+
+ private static final EditingContextAction EMPTY_EDITING_CONTEXT_ACTION = new EditingContextAction(EMPTY_ACTION_ID, "Others...");
+
+ private static final EditingContextAction EMPTY_FLOW_EDITING_CONTEXT_ACTION = new EditingContextAction(EMPTY_SYSML_ID, "SysML");
+
+ private static final EditingContextAction EMPTY_DOMAIN_EDITING_CONTEXT_ACTION = new EditingContextAction(EMPTY_DOMAIN_ID, "Domain");
+
+ private static final EditingContextAction EMPTY_VIEW_EDITING_CONTEXT_ACTION = new EditingContextAction(EMPTY_VIEW_ID, "View");
+
+ @Override
+ public List getEditingContextAction(IEditingContext editingContext) {
+ var actions = new ArrayList();
+ if (editingContext instanceof EditingContext emfEditingContext) {
+ var nsURIs = emfEditingContext.getDomain().getResourceSet().getPackageRegistry().values()
+ .stream()
+ .filter(EPackage.class::isInstance)
+ .map(EPackage.class::cast)
+ .map(EPackage::getNsURI)
+ .toList();
+
+ var containsDomain = nsURIs.contains(DomainPackage.eNS_URI);
+ var containsView = nsURIs.contains(ViewPackage.eNS_URI);
+
+ actions.add(EMPTY_FLOW_EDITING_CONTEXT_ACTION);
+ if (containsDomain) {
+ actions.add(EMPTY_DOMAIN_EDITING_CONTEXT_ACTION);
+ }
+ if (containsView) {
+ actions.add(EMPTY_VIEW_EDITING_CONTEXT_ACTION);
+ }
+ actions.add(EMPTY_EDITING_CONTEXT_ACTION);
+ }
+ return actions;
+ }
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/services/EditingDomainServicesProvider.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/EditingDomainServicesProvider.java
new file mode 100644
index 0000000..10c50b2
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/EditingDomainServicesProvider.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.services;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.sirius.components.view.View;
+import org.eclipse.sirius.components.view.emf.IJavaServiceProvider;
+import org.eclipse.sirius.ext.emf.edit.EditingDomainServices;
+import org.springframework.stereotype.Service;
+
+/**
+ * Provider for {@link org.eclipse.sirius.ext.emf.edit.EditingDomainServices} services.
+ *
+ * @author adaussy
+ */
+@Service
+public class EditingDomainServicesProvider implements IJavaServiceProvider {
+
+ @Override
+ public List> getServiceClasses(View view) {
+ return Collections.singletonList(EditingDomainServices.class);
+ }
+
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/services/ImagePathService.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/ImagePathService.java
new file mode 100644
index 0000000..7fdd47a
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/ImagePathService.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.services;
+
+import java.util.List;
+
+import org.eclipse.sirius.components.core.api.IImagePathService;
+import org.springframework.stereotype.Service;
+
+/**
+ * Implementation of {@link IImagePathService} for the Flow domain.
+ *
+ * @author lfasani
+ */
+@Service
+public class ImagePathService implements IImagePathService {
+
+ private static final List IMAGES_PATHS = List.of("/img", "/images", "/icons", "/icons2");
+
+ @Override
+ public List getPaths() {
+ return IMAGES_PATHS;
+ }
+
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/services/ViewerProvider.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/ViewerProvider.java
new file mode 100644
index 0000000..adec249
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/ViewerProvider.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.services;
+
+import java.util.Optional;
+import java.util.UUID;
+
+import org.eclipse.sirius.web.graphql.datafetchers.IViewerProvider;
+import org.eclipse.sirius.web.services.api.viewer.IViewer;
+import org.eclipse.sirius.web.services.api.viewer.User;
+import org.springframework.stereotype.Service;
+
+import graphql.schema.DataFetchingEnvironment;
+
+/**
+ * Service used to retrieve the current viewer.
+ *
+ * @author sbegaudeau
+ */
+@Service
+public class ViewerProvider implements IViewerProvider {
+ @Override
+ public Optional getViewer(DataFetchingEnvironment environment) {
+ return Optional.of(new User(UUID.randomUUID(), "system"));
+ }
+
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/services/properties/EStringIfDescriptionProvider.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/properties/EStringIfDescriptionProvider.java
new file mode 100644
index 0000000..7e38740
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/properties/EStringIfDescriptionProvider.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.services.properties;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.sirius.components.compatibility.emf.properties.api.IPropertiesValidationProvider;
+import org.eclipse.sirius.components.compatibility.forms.WidgetIdProvider;
+import org.eclipse.sirius.components.forms.description.IfDescription;
+import org.eclipse.sirius.components.forms.description.TextareaDescription;
+import org.eclipse.sirius.components.representations.Failure;
+import org.eclipse.sirius.components.representations.IStatus;
+import org.eclipse.sirius.components.representations.Success;
+import org.eclipse.sirius.components.representations.VariableManager;
+import org.eclipse.syson.sysml.SysmlPackage;
+
+/**
+ * Provides the default description of the widget to use to support an EString feature.
+ *
+ * @author sbegaudeau
+ */
+public class EStringIfDescriptionProvider {
+ private static final String IF_DESCRIPTION_ID = "EString";
+
+ private static final String TEXTAREA_DESCRIPTION_ID = "Textarea";
+
+ private final ComposedAdapterFactory composedAdapterFactory;
+
+ private final IPropertiesValidationProvider propertiesValidationProvider;
+
+ private final Function semanticTargetIdProvider;
+
+ public EStringIfDescriptionProvider(ComposedAdapterFactory composedAdapterFactory, IPropertiesValidationProvider propertiesValidationProvider, Function semanticTargetIdProvider) {
+ this.composedAdapterFactory = Objects.requireNonNull(composedAdapterFactory);
+ this.propertiesValidationProvider = Objects.requireNonNull(propertiesValidationProvider);
+ this.semanticTargetIdProvider = Objects.requireNonNull(semanticTargetIdProvider);
+ }
+
+ public IfDescription getIfDescription() {
+ return IfDescription.newIfDescription(IF_DESCRIPTION_ID)
+ .targetObjectIdProvider(this.semanticTargetIdProvider)
+ .predicate(this.getPredicate())
+ .controlDescriptions(List.of(this.getTextareaDescription()))
+ .build();
+ }
+
+ private Function getPredicate() {
+ return variableManager -> {
+ var optionalEAttribute = variableManager.get(PropertiesDefaultDescriptionProvider.ESTRUCTURAL_FEATURE, EAttribute.class);
+ return optionalEAttribute.filter(eAttribute -> {
+ EClassifier eType = eAttribute.getEType();
+ boolean readOnlyProperty = false;
+ if (SysmlPackage.eINSTANCE.getElement_ElementId().equals(eAttribute)) {
+ readOnlyProperty = true;
+ } else if (eAttribute.isDerived() || !eAttribute.isChangeable()) {
+ readOnlyProperty = true;
+ }
+ return !readOnlyProperty && (!eAttribute.isMany() && (eType.equals(EcorePackage.Literals.ESTRING) || Objects.equals(eType.getInstanceClassName(), String.class.getName())));
+ }).isPresent();
+ };
+ }
+
+ private TextareaDescription getTextareaDescription() {
+ return TextareaDescription.newTextareaDescription(TEXTAREA_DESCRIPTION_ID)
+ .targetObjectIdProvider(this.semanticTargetIdProvider)
+ .idProvider(new WidgetIdProvider())
+ .labelProvider(this.getLabelProvider())
+ .valueProvider(this.getValueProvider())
+ .newValueHandler(this.getNewValueHandler())
+ .isReadOnlyProvider(this.isReadOnlyPovider())
+ .diagnosticsProvider(this.propertiesValidationProvider.getDiagnosticsProvider())
+ .kindProvider(this.propertiesValidationProvider.getKindProvider())
+ .messageProvider(this.propertiesValidationProvider.getMessageProvider())
+ .build();
+ }
+
+ private Function getLabelProvider() {
+ return new EStructuralFeatureLabelProvider(PropertiesDefaultDescriptionProvider.ESTRUCTURAL_FEATURE, this.composedAdapterFactory);
+ }
+
+ private Function getValueProvider() {
+ return variableManager -> {
+ var optionalEObject = variableManager.get(VariableManager.SELF, EObject.class);
+ var optionalEAttribute = variableManager.get(PropertiesDefaultDescriptionProvider.ESTRUCTURAL_FEATURE, EAttribute.class);
+
+ if (optionalEObject.isPresent() && optionalEAttribute.isPresent()) {
+ EObject eObject = optionalEObject.get();
+ EAttribute eAttribute = optionalEAttribute.get();
+
+ Object value = eObject.eGet(eAttribute);
+ if (value != null && !eAttribute.isMany()) {
+ return EcoreUtil.convertToString(EcorePackage.Literals.ESTRING, value);
+ }
+ }
+
+ return "";
+ };
+ }
+
+ private BiFunction getNewValueHandler() {
+ return (variableManager, newValue) -> {
+ var optionalEObject = variableManager.get(VariableManager.SELF, EObject.class);
+ var optionalEAttribute = variableManager.get(PropertiesDefaultDescriptionProvider.ESTRUCTURAL_FEATURE, EAttribute.class);
+ if (optionalEObject.isPresent() && optionalEAttribute.isPresent()) {
+ EObject eObject = optionalEObject.get();
+ EAttribute eAttribute = optionalEAttribute.get();
+
+ String value = EcoreUtil.createFromString(EcorePackage.Literals.ESTRING, newValue).toString();
+ eObject.eSet(eAttribute, value);
+
+ return new Success();
+ }
+ return new Failure("");
+ };
+ }
+
+ private Function isReadOnlyPovider() {
+ return variableManager -> {
+ var optionalEObject = variableManager.get(VariableManager.SELF, EObject.class);
+ var optionalEAttribute = variableManager.get(PropertiesDefaultDescriptionProvider.ESTRUCTURAL_FEATURE, EAttribute.class);
+
+ if (optionalEObject.isPresent() && optionalEAttribute.isPresent()) {
+ EAttribute eAttribute = optionalEAttribute.get();
+ return !eAttribute.isChangeable();
+ }
+
+ return false;
+ };
+ }
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/services/properties/EStringReadOnlyIfDescriptionProvider.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/properties/EStringReadOnlyIfDescriptionProvider.java
new file mode 100644
index 0000000..88d3531
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/properties/EStringReadOnlyIfDescriptionProvider.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.services.properties;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+
+import org.eclipse.emf.common.util.Enumerator;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.sirius.components.compatibility.emf.properties.EStructuralFeatureLabelProvider;
+import org.eclipse.sirius.components.compatibility.emf.properties.PropertiesDefaultDescriptionProvider;
+import org.eclipse.sirius.components.compatibility.emf.properties.api.IPropertiesValidationProvider;
+import org.eclipse.sirius.components.compatibility.forms.WidgetIdProvider;
+import org.eclipse.sirius.components.forms.description.IfDescription;
+import org.eclipse.sirius.components.forms.description.LabelDescription;
+import org.eclipse.sirius.components.representations.VariableManager;
+import org.eclipse.syson.sysml.Element;
+import org.eclipse.syson.sysml.SysmlPackage;
+
+/**
+ * Provides the custom SysMLv2 description of the widget to use to support the Element#elementId attribute which is a
+ * read-only feature. Also supports derived and non changeable attributes.
+ *
+ * @author arichard
+ */
+public class EStringReadOnlyIfDescriptionProvider {
+ private static final String IF_DESCRIPTION_ID = "EString";
+
+ private static final String LABEL_DESCRIPTION_ID = "Label";
+
+ private final ComposedAdapterFactory composedAdapterFactory;
+
+ private final IPropertiesValidationProvider propertiesValidationProvider;
+
+ private final Function semanticTargetIdProvider;
+
+ public EStringReadOnlyIfDescriptionProvider(ComposedAdapterFactory composedAdapterFactory, IPropertiesValidationProvider propertiesValidationProvider,
+ Function semanticTargetIdProvider) {
+ this.composedAdapterFactory = Objects.requireNonNull(composedAdapterFactory);
+ this.propertiesValidationProvider = Objects.requireNonNull(propertiesValidationProvider);
+ this.semanticTargetIdProvider = Objects.requireNonNull(semanticTargetIdProvider);
+ }
+
+ public IfDescription getIfDescription() {
+ return IfDescription.newIfDescription(IF_DESCRIPTION_ID)
+ .targetObjectIdProvider(this.semanticTargetIdProvider)
+ .predicate(this.getPredicate())
+ .controlDescriptions(List.of(this.getLabelDescription()))
+ .build();
+ }
+
+ private Function getPredicate() {
+ return variableManager -> {
+ var optionalEStructuralFeature = variableManager.get(PropertiesDefaultDescriptionProvider.ESTRUCTURAL_FEATURE, EAttribute.class);
+ return optionalEStructuralFeature.filter(eAttribute -> {
+ EClassifier eType = eAttribute.getEType();
+ boolean readOnlyProperty = false;
+ if (SysmlPackage.eINSTANCE.getElement_ElementId().equals(eAttribute)) {
+ readOnlyProperty = true;
+ } else if (eAttribute.isDerived() || !eAttribute.isChangeable()) {
+ readOnlyProperty = true;
+ }
+ return readOnlyProperty && (!eAttribute.isMany() && (eType.equals(EcorePackage.Literals.ESTRING) || Objects.equals(eType.getInstanceClassName(), String.class.getName())));
+ }).isPresent();
+ };
+ }
+
+ private LabelDescription getLabelDescription() {
+ return LabelDescription.newLabelDescription(LABEL_DESCRIPTION_ID)
+ .idProvider(new WidgetIdProvider())
+ .targetObjectIdProvider(this.semanticTargetIdProvider)
+ .labelProvider(this.getLabelProvider())
+ .valueProvider(this.getValueProvider())
+ .diagnosticsProvider(this.propertiesValidationProvider.getDiagnosticsProvider())
+ .kindProvider(this.propertiesValidationProvider.getKindProvider())
+ .messageProvider(this.propertiesValidationProvider.getMessageProvider())
+ .build();
+ }
+
+ private Function getLabelProvider() {
+ return new EStructuralFeatureLabelProvider(PropertiesDefaultDescriptionProvider.ESTRUCTURAL_FEATURE, this.composedAdapterFactory);
+ }
+
+ private Function getValueProvider() {
+ return variableManager -> {
+ var optionalEObject = variableManager.get(VariableManager.SELF, EObject.class);
+ var optionalEAttribute = variableManager.get(PropertiesDefaultDescriptionProvider.ESTRUCTURAL_FEATURE, EStructuralFeature.class);
+
+ String value = "";
+ if (optionalEObject.isPresent() && optionalEAttribute.isPresent()) {
+ EObject eObject = optionalEObject.get();
+ EStructuralFeature eSF = optionalEAttribute.get();
+
+ Object eSFValue = eObject.eGet(eSF);
+ if (eSFValue != null && !eSF.isMany()) {
+ if (eSFValue instanceof Enumerator enumerator) {
+ value = enumerator.getName();
+ } else if (eSFValue instanceof Element element) {
+ value = element.getName();
+ } else {
+ value = EcoreUtil.convertToString(EcorePackage.Literals.ESTRING, eSFValue);
+ }
+ }
+ }
+
+ return value;
+ };
+ }
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/services/properties/EStructuralFeatureChoiceOfValueProvider.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/properties/EStructuralFeatureChoiceOfValueProvider.java
new file mode 100644
index 0000000..3bd055c
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/properties/EStructuralFeatureChoiceOfValueProvider.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.services.properties;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
+import org.eclipse.emf.edit.provider.IItemPropertySource;
+import org.eclipse.sirius.components.representations.VariableManager;
+
+/**
+ * Utility class used to provide a choice of values for a structural feature and an object in the variable manager.
+ *
+ * @author arichard
+ */
+public class EStructuralFeatureChoiceOfValueProvider implements Function> {
+
+ private final String featureVariableName;
+
+ private final AdapterFactory adapterFactory;
+
+ public EStructuralFeatureChoiceOfValueProvider(String featureVariableName, AdapterFactory adapterFactory) {
+ this.featureVariableName = Objects.requireNonNull(featureVariableName);
+ this.adapterFactory = Objects.requireNonNull(adapterFactory);
+ }
+
+ @Override
+ public List> apply(VariableManager variableManager) {
+ var optionalEObject = variableManager.get(VariableManager.SELF, EObject.class);
+ var optionalEReference = variableManager.get(this.featureVariableName, EReference.class);
+
+ if (optionalEObject.isPresent() && optionalEReference.isPresent()) {
+ EObject eObject = optionalEObject.get();
+ EReference eReference = optionalEReference.get();
+
+ Object adapter = this.adapterFactory.adapt(eObject, IItemPropertySource.class);
+ if (adapter instanceof IItemPropertySource itemPropertySource) {
+ IItemPropertyDescriptor descriptor = itemPropertySource.getPropertyDescriptor(eObject, eReference);
+ if (descriptor != null) {
+ return descriptor.getChoiceOfValues(eObject).stream()
+ .filter(Objects::nonNull)
+ .toList();
+ }
+ }
+ }
+
+ return new ArrayList<>();
+ }
+
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/services/properties/EStructuralFeatureLabelProvider.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/properties/EStructuralFeatureLabelProvider.java
new file mode 100644
index 0000000..7edcb0a
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/properties/EStructuralFeatureLabelProvider.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.services.properties;
+
+import java.util.Objects;
+import java.util.function.Function;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
+import org.eclipse.emf.edit.provider.IItemPropertySource;
+import org.eclipse.sirius.components.representations.VariableManager;
+
+/**
+ * Utility class used to provide a label for a structural feature in the variable manager.
+ *
+ * @author arichard
+ */
+public class EStructuralFeatureLabelProvider implements Function {
+
+ private String featureVariableName;
+
+ private AdapterFactory adapterFactory;
+
+ public EStructuralFeatureLabelProvider(String featureVariableName, AdapterFactory adapterFactory) {
+ this.featureVariableName = Objects.requireNonNull(featureVariableName);
+ this.adapterFactory = Objects.requireNonNull(adapterFactory);
+ }
+
+ @Override
+ public String apply(VariableManager variableManager) {
+ Object object = variableManager.getVariables().get(VariableManager.SELF);
+ Object feature = variableManager.getVariables().get(this.featureVariableName);
+
+ if (object instanceof EObject && feature instanceof EStructuralFeature) {
+ EObject eObject = (EObject) object;
+ EStructuralFeature eStructuralFeature = (EStructuralFeature) feature;
+
+ Adapter adapter = this.adapterFactory.adapt(eObject, IItemPropertySource.class);
+ if (adapter instanceof IItemPropertySource) {
+ IItemPropertySource itemPropertySource = (IItemPropertySource) adapter;
+ IItemPropertyDescriptor descriptor = itemPropertySource.getPropertyDescriptor(eObject, eStructuralFeature);
+ if (descriptor != null) {
+ String displayName = descriptor.getDisplayName(eStructuralFeature);
+ return displayName;
+ }
+ }
+ }
+ return "";
+ }
+
+}
diff --git a/backend/application/syson-application/src/main/java/org/eclipse/syson/services/properties/NonContainmentReferenceIfDescriptionProvider.java b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/properties/NonContainmentReferenceIfDescriptionProvider.java
new file mode 100644
index 0000000..94ed0b5
--- /dev/null
+++ b/backend/application/syson-application/src/main/java/org/eclipse/syson/services/properties/NonContainmentReferenceIfDescriptionProvider.java
@@ -0,0 +1,347 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Obeo.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.syson.services.properties;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Function;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.sirius.components.collaborative.api.ChangeKind;
+import org.eclipse.sirius.components.compatibility.emf.properties.api.IPropertiesValidationProvider;
+import org.eclipse.sirius.components.compatibility.forms.WidgetIdProvider;
+import org.eclipse.sirius.components.core.api.IEditService;
+import org.eclipse.sirius.components.core.api.IFeedbackMessageService;
+import org.eclipse.sirius.components.core.api.IObjectService;
+import org.eclipse.sirius.components.emf.services.api.IEMFKindService;
+import org.eclipse.sirius.components.forms.description.IfDescription;
+import org.eclipse.sirius.components.representations.Failure;
+import org.eclipse.sirius.components.representations.IStatus;
+import org.eclipse.sirius.components.representations.Message;
+import org.eclipse.sirius.components.representations.MessageLevel;
+import org.eclipse.sirius.components.representations.Success;
+import org.eclipse.sirius.components.representations.VariableManager;
+import org.eclipse.sirius.components.widget.reference.ReferenceWidgetComponent;
+import org.eclipse.sirius.components.widget.reference.ReferenceWidgetDescription;
+
+/**
+ * Provides the default description of the widget to use to support non-containment reference.
+ *
+ * @author frouene
+ */
+public class NonContainmentReferenceIfDescriptionProvider {
+
+ private static final String REFERENCE_WIDGET_DESCRIPTION_ID = "NonContainmentReferenceIfDescriptionProvider.ReferenceWidget";
+
+ private static final String ID_DESCRIPTION_ID = "NonContainment Reference";
+
+ private final ComposedAdapterFactory composedAdapterFactory;
+
+ private final IObjectService objectService;
+
+ private final IPropertiesValidationProvider propertiesValidationProvider;
+
+ private final Function semanticTargetIdProvider;
+
+ private final IEMFKindService emfKindService;
+
+ private final IFeedbackMessageService feedbackMessageService;
+
+ private final IEditService editService;
+
+ public NonContainmentReferenceIfDescriptionProvider(ComposedAdapterFactory composedAdapterFactory, IObjectService objectService, IEditService editService, IEMFKindService emfKindService,
+ IFeedbackMessageService feedbackMessageService, IPropertiesValidationProvider propertiesValidationProvider, Function semanticTargetIdProvider) {
+ this.composedAdapterFactory = Objects.requireNonNull(composedAdapterFactory);
+ this.objectService = Objects.requireNonNull(objectService);
+ this.editService = Objects.requireNonNull(editService);
+ this.propertiesValidationProvider = Objects.requireNonNull(propertiesValidationProvider);
+ this.semanticTargetIdProvider = Objects.requireNonNull(semanticTargetIdProvider);
+ this.emfKindService = Objects.requireNonNull(emfKindService);
+ this.feedbackMessageService = Objects.requireNonNull(feedbackMessageService);
+ }
+
+ public IfDescription getIfDescription() {
+ return IfDescription.newIfDescription(ID_DESCRIPTION_ID)
+ .targetObjectIdProvider(this.semanticTargetIdProvider)
+ .predicate(this.getPredicate())
+ .controlDescriptions(List.of(this.getReferenceWidgetDescription()))
+ .build();
+ }
+
+ private Function getPredicate() {
+ return variableManager -> {
+ var optionalEReference = variableManager.get(PropertiesDefaultDescriptionProvider.ESTRUCTURAL_FEATURE, EReference.class);
+ return optionalEReference.filter(eReference -> !eReference.isContainment() && eReference.isChangeable()).isPresent();
+ };
+ }
+
+ private ReferenceWidgetDescription getReferenceWidgetDescription() {
+ return ReferenceWidgetDescription.newReferenceWidgetDescription(REFERENCE_WIDGET_DESCRIPTION_ID)
+ .targetObjectIdProvider(this.semanticTargetIdProvider)
+ .idProvider(new WidgetIdProvider())
+ .labelProvider(this.getLabelProvider())
+ .optionsProvider(this.getOptionsProvider())
+ .iconURLProvider(variableManager -> List.of())
+ .itemsProvider(this::getReferenceValue)
+ .itemIdProvider(this::getItemId)
+ .itemKindProvider(this::getItemKind)
+ .itemLabelProvider(this::getItemLabel)
+ .itemImageURLProvider(this::getItemIconURL)
+ .ownerKindProvider(this::getTypeName)
+ .referenceKindProvider(this::getReferenceKind)
+ .isContainmentProvider(this::isContainment)
+ .isManyProvider(this::isMany)
+ .styleProvider(variableManager -> null)
+ .ownerIdProvider(this::getOwnerId)
+ .diagnosticsProvider(this.propertiesValidationProvider.getDiagnosticsProvider())
+ .kindProvider(this.propertiesValidationProvider.getKindProvider())
+ .messageProvider(this.propertiesValidationProvider.getMessageProvider())
+ .clearHandlerProvider(this::handleClearReference)
+ .itemRemoveHandlerProvider(this::handleRemoveValue)
+ .setHandlerProvider(this::handleSetReference)
+ .addHandlerProvider(this::handleAddReferenceValues)
+ .moveHandlerProvider(this::handleMoveReferenceValue)
+ .isReadOnlyProvider(this.isReadOnlyPovider())
+ .build();
+ }
+
+ private List> getReferenceValue(VariableManager variableManager) {
+ List> value = List.of();
+ EStructuralFeature.Setting setting = this.resolveSetting(variableManager);
+ if (setting != null) {
+ var rawValue = setting.get(true);
+ if (setting.getEStructuralFeature().isMany()) {
+ value = (List>) rawValue;
+ } else if (rawValue != null) {
+ value = List.of(rawValue);
+ } else {
+ value = List.of();
+ }
+ }
+ return value;
+ }
+
+ private Function> getOptionsProvider() {
+ return new EStructuralFeatureChoiceOfValueProvider(PropertiesDefaultDescriptionProvider.ESTRUCTURAL_FEATURE, this.composedAdapterFactory);
+ }
+
+ private EStructuralFeature.Setting resolveSetting(VariableManager variableManager) {
+ EObject referenceOwner = variableManager.get(VariableManager.SELF, EObject.class).orElse(null);
+ var optionalEReference = variableManager.get(PropertiesDefaultDescriptionProvider.ESTRUCTURAL_FEATURE, EReference.class);
+
+ if (referenceOwner != null && optionalEReference.isPresent()) {
+ return ((InternalEObject) referenceOwner).eSetting(optionalEReference.get());
+ } else {
+ return null;
+ }
+ }
+
+ private Optional