diff options
| author | Christian W. Damus | 2017-01-04 15:04:43 +0000 |
|---|---|---|
| committer | Christian W. Damus | 2017-01-06 14:48:44 +0000 |
| commit | de71cbb178b0118ba0556dd31853bbe0c4d15af7 (patch) | |
| tree | bb6e070f2c2e4cb804d2994bb6132754635bfd7f | |
| parent | d1cc24a419ea1dde28d7ba870c0e4c11b7f333e0 (diff) | |
| download | org.eclipse.papyrus-rt-de71cbb178b0118ba0556dd31853bbe0c4d15af7.tar.gz org.eclipse.papyrus-rt-de71cbb178b0118ba0556dd31853bbe0c4d15af7.tar.xz org.eclipse.papyrus-rt-de71cbb178b0118ba0556dd31853bbe0c4d15af7.zip | |
Bug 467545: [UML-RT] PapyrusRT shall provide a UML specific implementation to support redefinition
Introduction of a custom UML metamodel implementation for UML-RT semantics of incremental
redefinition. Includes a façade API for simplified UML-RT view of the UML model content.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=467545
Change-Id: I9575241217f8d7655b8cf4002488ecfb3e96a728
162 files changed, 28946 insertions, 8 deletions
diff --git a/features/profile/org.eclipse.papyrusrt.umlrt.profile.feature/feature.xml b/features/profile/org.eclipse.papyrusrt.umlrt.profile.feature/feature.xml index f39d0c616..e2a5f7ecc 100644 --- a/features/profile/org.eclipse.papyrusrt.umlrt.profile.feature/feature.xml +++ b/features/profile/org.eclipse.papyrusrt.umlrt.profile.feature/feature.xml @@ -18,10 +18,10 @@ </license> <requires> - <import plugin="org.eclipse.core.runtime" version="3.12.0" match="greaterOrEqual"/> - <import plugin="org.eclipse.emf.ecore" version="2.12.0" match="greaterOrEqual"/> - <import plugin="org.eclipse.uml2.types" version="2.0.0" match="greaterOrEqual"/> - <import plugin="org.eclipse.uml2.uml" version="5.2.0" match="greaterOrEqual"/> + <import plugin="org.eclipse.core.runtime" version="3.12.0" match="compatible"/> + <import plugin="org.eclipse.emf.ecore" version="2.12.0" match="compatible"/> + <import plugin="org.eclipse.uml2.types" version="2.0.0" match="compatible"/> + <import plugin="org.eclipse.uml2.uml" version="5.2.0" match="equivalent"/> </requires> <plugin @@ -31,4 +31,11 @@ version="0.0.0" unpack="false"/> + <plugin + id="org.eclipse.papyrusrt.umlrt.uml" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + </feature> diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/.checkstyle b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/.checkstyle new file mode 100644 index 000000000..f479982cb --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/.checkstyle @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false"> + <fileset name="all" enabled="true" check-config-name="Papyrus-RT" local="false"> + <file-match-pattern match-pattern="." include-pattern="true"/> + </fileset> +</fileset-config> diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/.classpath b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/.classpath new file mode 100644 index 000000000..6ac0226a2 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/.classpath @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src-gen"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"> + <accessrules> + <accessrule kind="accessible" pattern="org/eclipse/uml2/uml/internal/**"/> + </accessrules> + </classpathentry> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/.project b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/.project new file mode 100644 index 000000000..73b99de54 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/.project @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.papyrusrt.umlrt.uml</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>net.sf.eclipsecs.core.CheckstyleBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.m2e.core.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.m2e.core.maven2Nature</nature> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>net.sf.eclipsecs.core.CheckstyleNature</nature> + </natures> +</projectDescription> diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/.settings/org.eclipse.core.resources.prefs b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 000000000..99f26c020 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/<project>=UTF-8 diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/.settings/org.eclipse.jdt.core.prefs b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..9b6d675fd --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,297 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +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.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +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_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +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_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +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_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=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_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_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +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_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_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=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.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=260 +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_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=false +org.eclipse.jdt.core.formatter.indentation.size=4 +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=do not 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_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=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_binary_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_superinterfaces=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_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_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_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_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=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_binary_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_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_superinterfaces=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_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_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_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_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_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=false +org.eclipse.jdt.core.formatter.join_wrapped_lines=false +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_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=260 +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_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=5 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=tab +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=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/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/.settings/org.eclipse.jdt.ui.prefs b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..b22a3a0ce --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,127 @@ +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.always_use_blocks=true +cleanup.always_use_parentheses_in_expressions=false +cleanup.always_use_this_for_non_static_field_access=false +cleanup.always_use_this_for_non_static_method_access=false +cleanup.convert_functional_interfaces=false +cleanup.convert_to_enhanced_for_loop=false +cleanup.correct_indentation=false +cleanup.format_source_code=false +cleanup.format_source_code_changes_only=false +cleanup.insert_inferred_type_arguments=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.never_use_blocks=false +cleanup.never_use_parentheses_in_expressions=true +cleanup.organize_imports=false +cleanup.qualify_static_field_accesses_with_declaring_class=false +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=true +cleanup.qualify_static_method_accesses_with_declaring_class=false +cleanup.remove_private_constructors=true +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_casts=true +cleanup.remove_unnecessary_nls_tags=true +cleanup.remove_unused_imports=true +cleanup.remove_unused_local_variables=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.sort_members=false +cleanup.sort_members_all=false +cleanup.use_anonymous_class_creation=false +cleanup.use_blocks=true +cleanup.use_blocks_only_for_return_and_throw=false +cleanup.use_lambda=true +cleanup.use_parentheses_in_expressions=false +cleanup.use_this_for_non_static_field_access=false +cleanup.use_this_for_non_static_field_access_only_if_necessary=true +cleanup.use_this_for_non_static_method_access=false +cleanup.use_this_for_non_static_method_access_only_if_necessary=true +cleanup.use_type_arguments=false +cleanup_profile=_Papyrus +cleanup_settings_version=2 +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=_Papyrus +formatter_settings_version=12 +org.eclipse.jdt.ui.ignorelowercasenames=true +org.eclipse.jdt.ui.importorder=java;javax;org;com; +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=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="false" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * Constructor.\n *\n * ${tags}\n */</template><template autoinsert\="false" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/*****************************************************************************\n * Copyright (c) ${year} CEA LIST and others.\n * \n * All rights reserved. This program and the accompanying materials\n * are made available under the terms of the Eclipse Public License v1.0\n * which accompanies this distribution, and is available at\n * http\://www.eclipse.org/legal/epl-v10.html\n *\n * Contributors\:\n * CEA LIST - Initial API and implementation\n * \n *****************************************************************************/\n</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/**\n * ${see_to_overridden}\n *\n * ${tags}\n */</template><template autoinsert\="false" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${see_to_target}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates> +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_missing_override_annotations_interface_methods=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_functional_interfaces=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=true +sp_cleanup.format_source_code_changes_only=false +sp_cleanup.insert_inferred_type_arguments=false +sp_cleanup.make_local_variable_final=true +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_type_abstract_if_missing_method=false +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=true +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_redundant_type_arguments=true +sp_cleanup.remove_trailing_whitespaces=false +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=false +sp_cleanup.remove_unused_imports=false +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_anonymous_class_creation=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_lambda=true +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +sp_cleanup.use_type_arguments=false diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/META-INF/MANIFEST.MF b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/META-INF/MANIFEST.MF new file mode 100644 index 000000000..29226db6c --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/META-INF/MANIFEST.MF @@ -0,0 +1,26 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.eclipse.papyrusrt.umlrt.uml;singleton:=true +Bundle-Version: 0.8.0.qualifier +Bundle-ClassPath: . +Bundle-Vendor: %providerName +Bundle-Localization: plugin +Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.12.0,4.0.0)", + org.eclipse.emf.ecore;bundle-version="[2.12.0,3.0.0)";visibility:=reexport, + org.eclipse.uml2.types;bundle-version="[2.0.0,3.0.0)";visibility:=reexport, + org.eclipse.uml2.uml;bundle-version="[5.2.0,5.3.0)";visibility:=reexport, + org.eclipse.uml2.common;bundle-version="[2.1.0,3.0.0)";visibility:=reexport, + org.eclipse.uml2.uml.resources;bundle-version="[5.2.0,6.0.0)";resolution:=optional, + org.eclipse.papyrusrt.umlrt.profile;bundle-version="0.8.0";visibility:=reexport +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-ActivationPolicy: lazy +Export-Package: org.eclipse.papyrusrt.umlrt.uml, + org.eclipse.papyrusrt.umlrt.uml.internal.impl;x-internal:=true, + org.eclipse.papyrusrt.umlrt.uml.internal.operations;x-internal:=true, + org.eclipse.papyrusrt.umlrt.uml.internal.umlext;x-internal:=true, + org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl;x-internal:=true, + org.eclipse.papyrusrt.umlrt.uml.internal.umlext.operations;x-internal:=true, + org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util;x-internal:=true, + org.eclipse.papyrusrt.umlrt.uml.internal.util;x-internal:=true, + org.eclipse.papyrusrt.umlrt.uml.util diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/about.html b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/about.html new file mode 100644 index 000000000..dd3c089a9 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/about.html @@ -0,0 +1,28 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/> +<title>About</title> +</head> +<body lang="EN-US"> +<h2>About This Content</h2> + +<p>November 14, 2008</p> +<h3>License</h3> + +<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>. +For purposes of the EPL, "Program" will mean the Content.</p> + +<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p> + +</body> +</html>
\ No newline at end of file diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/build.properties b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/build.properties new file mode 100644 index 000000000..ac2317528 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/build.properties @@ -0,0 +1,23 @@ +# +# Copyright (c) 2016 Christian W. Damus and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Christian W. Damus - initial API and implementation +# + +bin.includes = .,\ + META-INF/,\ + about.html,\ + plugin.properties,\ + plugin.xml,\ + model/ +jars.compile.order = . +source.. = src-gen/,\ + src/ +output.. = bin/ +src.includes = about.html diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/model/uml-ext.genmodel b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/model/uml-ext.genmodel new file mode 100644 index 000000000..7b7b7c19f --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/model/uml-ext.genmodel @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8"?> +<genmodel:GenModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:genmodel="http://www.eclipse.org/uml2/2.2.0/GenModel" + copyrightText="Copyright (c) 2016 Christian W. Damus and others.

All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html

Contributors:
 Christian W. Damus - initial API and implementation
" + modelDirectory="/org.eclipse.papyrusrt.umlrt.uml/src-gen" editDirectory="/org.eclipse.papyrusrt.umlrt.uml.edit/src-gen" + editorDirectory="/org.eclipse.papyrusrt.umlrt.uml.editor/src-gen" modelPluginID="org.eclipse.papyrusrt.umlrt.uml" + modelName="UML-Ext" nonNLSMarkers="true" rootExtendsClass="org.eclipse.emf.ecore.impl.MinimalEObjectImpl$Container" + codeFormatting="true" testsDirectory="/org.eclipse.papyrusrt.umlrt.uml.tests/src-gen" + importerID="org.eclipse.uml2.uml.ecore.importer" complianceLevel="8.0" copyrightFields="false" + usedGenPackages="../../org.eclipse.emf.ecore/model/Ecore.genmodel#//ecore ../../org.eclipse.uml2.types/model/Types.genmodel#//types ../../org.eclipse.uml2.uml/model/UML.genmodel#//uml" + interfaceNamePattern="Ext{0}" classNamePattern="Ext{0}Impl" operationReflection="true" + importOrganizing="true" cleanup="true" factoryMethods="true" pluralizedGetters="true" + cacheAdapterSupport="true"> + <genAnnotations source="http://www.eclipse.org/emf/2002/GenModel/importer/org.eclipse.uml2.uml.ecore.importer"> + <details key="OPPOSITE_ROLE_NAMES" value="IGNORE"/> + <details key="DUPLICATE_FEATURES" value="DISCARD"/> + <details key="ANNOTATION_DETAILS" value="PROCESS"/> + <details key="PROPERTY_DEFAULT_EXPRESSIONS" value="IGNORE"/> + <details key="DUPLICATE_FEATURE_INHERITANCE" value="DISCARD"/> + <details key="COMMENTS" value="PROCESS"/> + <details key="DERIVED_FEATURES" value="PROCESS"/> + <details key="SUPER_CLASS_ORDER" value="PROCESS"/> + <details key="DUPLICATE_OPERATION_INHERITANCE" value="DISCARD"/> + <details key="REDEFINING_OPERATIONS" value="PROCESS"/> + <details key="INVARIANT_CONSTRAINTS" value="PROCESS"/> + <details key="UNION_PROPERTIES" value="PROCESS"/> + <details key="DUPLICATE_OPERATIONS" value="DISCARD"/> + <details key="NON_API_INVARIANTS" value="IGNORE"/> + <details key="CAMEL_CASE_NAMES" value="IGNORE"/> + <details key="SUBSETTING_PROPERTIES" value="PROCESS"/> + <details key="OPERATION_BODIES" value="IGNORE"/> + <details key="ECORE_TAGGED_VALUES" value="PROCESS"/> + <details key="UNTYPED_PROPERTIES" value="REPORT"/> + <details key="REDEFINING_PROPERTIES" value="PROCESS"/> + <details key="INVOCATION_DELEGATES" value="IGNORE"/> + <details key="VALIDATION_DELEGATES" value="IGNORE"/> + </genAnnotations> + <foreignModel>uml-ext.metamodel.uml</foreignModel> + <genPackages xsi:type="genmodel:GenPackage" prefix="UMLExt" basePackage="org.eclipse.papyrusrt.umlrt.uml.internal" + disposableProviderFactory="true" ecorePackage="umlext.ecore#/" operationsPackage="org.eclipse.papyrusrt.umlrt.uml.internal.umlext.operations"> + <genDataTypes xsi:type="genmodel:GenDataType" ecoreDataType="umlext.ecore#//UMLElement"/> + <genClasses xsi:type="genmodel:GenClass" image="false" ecoreClass="umlext.ecore#//Element"> + <genFeatures xsi:type="genmodel:GenFeature" createChild="false" ecoreFeature="ecore:EAttribute umlext.ecore#//Element/extendedElement"/> + <genFeatures xsi:type="genmodel:GenFeature" property="Readonly" notify="false" + createChild="false" ecoreFeature="ecore:EReference umlext.ecore#//Element/extension"/> + <genOperations xsi:type="genmodel:GenOperation" ecoreOperation="umlext.ecore#//Element/getExtension"/> + </genClasses> + <genClasses xsi:type="genmodel:GenClass" image="false" ecoreClass="umlext.ecore#//Namespace"> + <genFeatures xsi:type="genmodel:GenFeature" property="None" children="true" + createChild="true" ecoreFeature="ecore:EReference umlext.ecore#//Namespace/implicitMember"/> + <genFeatures xsi:type="genmodel:GenFeature" property="Readonly" notify="false" + createChild="false" ecoreFeature="ecore:EReference umlext.ecore#//Namespace/excludedMember"/> + <genOperations xsi:type="genmodel:GenOperation" ecoreOperation="umlext.ecore#//Namespace/getExcludedMembers" + cacheAdapterScope="Global"/> + </genClasses> + <genClasses xsi:type="genmodel:GenClass" image="false" ecoreClass="umlext.ecore#//StructuredClassifier"> + <genFeatures xsi:type="genmodel:GenFeature" property="None" children="true" + createChild="true" ecoreFeature="ecore:EReference umlext.ecore#//StructuredClassifier/implicitAttribute"/> + <genFeatures xsi:type="genmodel:GenFeature" property="None" children="true" + createChild="true" ecoreFeature="ecore:EReference umlext.ecore#//StructuredClassifier/implicitConnector"/> + </genClasses> + <genClasses xsi:type="genmodel:GenClass" image="false" ecoreClass="umlext.ecore#//EncapsulatedClassifier"> + <genFeatures xsi:type="genmodel:GenFeature" createChild="true" propertySortChoices="true" + ecoreFeature="ecore:EReference umlext.ecore#//EncapsulatedClassifier/implicitPort"/> + </genClasses> + <genClasses xsi:type="genmodel:GenClass" ecoreClass="umlext.ecore#//Class"> + <genFeatures xsi:type="genmodel:GenFeature" property="None" children="true" + createChild="true" ecoreFeature="ecore:EReference umlext.ecore#//Class/implicitOperation"/> + </genClasses> + <genClasses xsi:type="genmodel:GenClass" ecoreClass="umlext.ecore#//Interface"> + <genFeatures xsi:type="genmodel:GenFeature" property="None" children="true" + createChild="true" ecoreFeature="ecore:EReference umlext.ecore#//Interface/implicitOperation"/> + </genClasses> + </genPackages> +</genmodel:GenModel> diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/model/uml-ext.metamodel.properties b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/model/uml-ext.metamodel.properties new file mode 100644 index 000000000..60e360e61 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/model/uml-ext.metamodel.properties @@ -0,0 +1,13 @@ +# +# Copyright (c) 2016 Christian W. Damus and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Christian W. Damus - initial API and implementation +# + +_label_umlext: UML Extensions for UML-RT diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/model/uml-ext.metamodel.uml b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/model/uml-ext.metamodel.uml new file mode 100644 index 000000000..9d731cbda --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/model/uml-ext.metamodel.uml @@ -0,0 +1,144 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:Ecore="http://www.eclipse.org/uml2/schemas/Ecore/5" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:standard="http://www.eclipse.org/uml2/5.0.0/UML/Profile/Standard" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xsi:schemaLocation="http://www.eclipse.org/uml2/schemas/Ecore/5 pathmap://UML_PROFILES/Ecore.profile.uml#_z1OFcHjqEdy8S4Cr8Rc_NA"> + <uml:Model xmi:id="_0" name="umlext" URI="http://www.eclipse.org/papyrus/umlrt/uml-ext"> + <ownedComment xmi:id="_ownedComment.0"> + <body>UML extensions for UML-RT semantics. +This metamodel defines features that are mixed in, in ad hoc +fashion (not by package merge) to the UML-RT implementation +of the UML Metamodel.</body> + </ownedComment> + <packagedElement xmi:type="uml:PrimitiveType" xmi:id="UMLElement" name="UMLElement" isAbstract="true"/> + <packagedElement xmi:type="uml:Class" xmi:id="Element" name="Element" isAbstract="true"> + <ownedAttribute xmi:id="Element-extendedElement" name="extendedElement" type="UMLElement"> + <ownedComment xmi:id="Element-extendedElement-_ownedComment.0"> + <body>This is modeled as an attribute of UML::Element data type because we don't +want the reference to the extended element to be indexed in the CacheAdapter.</body> + </ownedComment> + </ownedAttribute> + <ownedAttribute xmi:id="Element-extension" name="extension" type="Element" isReadOnly="true" isDerived="true"> + <ownedComment xmi:id="Element-extension-_ownedComment.0"> + <body>This looks odd as a required self-reference, but it is actually meant +to be accessed as an extension feature of the extended UML model +element, in order to access the extension object.</body> + </ownedComment> + </ownedAttribute> + <ownedOperation xmi:id="Element-getExtension" name="getExtension" visibility="protected"> + <ownedParameter xmi:id="Element-getExtension-_ownedParameter.0" type="Element" direction="return"/> + </ownedOperation> + </packagedElement> + <packagedElement xmi:type="uml:Class" xmi:id="Namespace" name="Namespace" isAbstract="true"> + <generalization xmi:id="Namespace-_generalization.0" general="Element"/> + <ownedAttribute xmi:id="Namespace-implicitMember" name="implicitMember" isReadOnly="true" aggregation="composite" isDerived="true" isDerivedUnion="true" association="_packagedElement.3"> + <type xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#RedefinableElement"/> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="Namespace-implicitMember-_lowerValue"/> + <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="Namespace-implicitMember-_upperValue" value="*"/> + </ownedAttribute> + <ownedAttribute xmi:id="Namespace-excludedMember" name="excludedMember" isReadOnly="true" isDerived="true"> + <type xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#NamedElement"/> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="Namespace-excludedMember-_lowerValue"/> + <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="Namespace-excludedMember-_upperValue" value="*"/> + </ownedAttribute> + <ownedOperation xmi:id="Namespace-getExcludedMembers" name="getExcludedMembers" visibility="protected"> + <ownedParameter xmi:id="Namespace-getExcludedMembers-_ownedParameter.0" direction="return"> + <type xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#NamedElement"/> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="Namespace-getExcludedMembers-_ownedParameter.0-_lowerValue"/> + <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="Namespace-getExcludedMembers-_ownedParameter.0-_upperValue" value="*"/> + </ownedParameter> + </ownedOperation> + </packagedElement> + <packagedElement xmi:type="uml:Association" xmi:id="_packagedElement.3" visibility="private" memberEnd="Namespace-implicitMember _packagedElement.3-implicitNamespace"> + <ownedEnd xmi:id="_packagedElement.3-implicitNamespace" name="implicitNamespace" type="Namespace" association="_packagedElement.3"> + <subsettedProperty href="pathmap://UML_METAMODELS/UML.metamodel.uml#NamedElement-namespace"/> + </ownedEnd> + </packagedElement> + <packagedElement xmi:type="uml:Class" xmi:id="StructuredClassifier" name="StructuredClassifier" isAbstract="true"> + <generalization xmi:id="StructuredClassifier-_generalization.0" general="Namespace"/> + <ownedAttribute xmi:id="StructuredClassifier-implicitAttribute" name="implicitAttribute" aggregation="composite" subsettedProperty="Namespace-implicitMember" association="_packagedElement.5"> + <type xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#Property"/> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="StructuredClassifier-implicitAttribute-_lowerValue"/> + <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="StructuredClassifier-implicitAttribute-_upperValue" value="*"/> + </ownedAttribute> + <ownedAttribute xmi:id="StructuredClassifier-implicitConnector" name="implicitConnector" aggregation="composite" subsettedProperty="Namespace-implicitMember" association="_packagedElement.6"> + <type xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#Connector"/> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="StructuredClassifier-implicitConnector-_lowerValue"/> + <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="StructuredClassifier-implicitConnector-_upperValue" value="*"/> + </ownedAttribute> + </packagedElement> + <packagedElement xmi:type="uml:Association" xmi:id="_packagedElement.5" visibility="private" memberEnd="StructuredClassifier-implicitAttribute _packagedElement.5-implicitClass"> + <ownedEnd xmi:id="_packagedElement.5-implicitClass" name="implicitClass" type="StructuredClassifier" association="_packagedElement.5"> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="_packagedElement.5-implicitClass-_lowerValue"/> + </ownedEnd> + </packagedElement> + <packagedElement xmi:type="uml:Association" xmi:id="_packagedElement.6" visibility="private" memberEnd="StructuredClassifier-implicitConnector _packagedElement.6-implicitClass"> + <ownedEnd xmi:id="_packagedElement.6-implicitClass" name="implicitClass" type="StructuredClassifier" association="_packagedElement.6"> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="_packagedElement.6-implicitClass-_lowerValue"/> + </ownedEnd> + </packagedElement> + <packagedElement xmi:type="uml:Class" xmi:id="EncapsulatedClassifier" name="EncapsulatedClassifier" isAbstract="true"> + <generalization xmi:id="EncapsulatedClassifier-_generalization.0" general="StructuredClassifier"/> + <ownedAttribute xmi:id="EncapsulatedClassifier-implicitPort" name="implicitPort" aggregation="composite" isDerived="true" subsettedProperty="StructuredClassifier-implicitAttribute" association="_packagedElement.8"> + <type xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#Port"/> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="EncapsulatedClassifier-implicitPort-_lowerValue"/> + <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="EncapsulatedClassifier-implicitPort-_upperValue" value="*"/> + </ownedAttribute> + </packagedElement> + <packagedElement xmi:type="uml:Association" xmi:id="_packagedElement.8" visibility="private" memberEnd="EncapsulatedClassifier-implicitPort _packagedElement.8-implicitClass"> + <ownedEnd xmi:id="_packagedElement.8-implicitClass" name="implicitClass" type="EncapsulatedClassifier" association="_packagedElement.8"> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="_packagedElement.8-implicitClass-_lowerValue"/> + </ownedEnd> + </packagedElement> + <packagedElement xmi:type="uml:Class" xmi:id="Class" name="Class"> + <generalization xmi:id="Class-_generalization.0" general="EncapsulatedClassifier"/> + <ownedAttribute xmi:id="Class-implicitOperation" name="implicitOperation" aggregation="composite" subsettedProperty="Namespace-implicitMember" association="_packagedElement.10"> + <type xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#Operation"/> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="Class-implicitOperation-_lowerValue"/> + <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="Class-implicitOperation-_upperValue" value="*"/> + </ownedAttribute> + </packagedElement> + <packagedElement xmi:type="uml:Association" xmi:id="_packagedElement.10" visibility="private" memberEnd="Class-implicitOperation _packagedElement.10-implicitClass"> + <ownedEnd xmi:id="_packagedElement.10-implicitClass" name="implicitClass" type="Class" association="_packagedElement.10"> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="_packagedElement.10-implicitClass-_lowerValue"/> + </ownedEnd> + </packagedElement> + <packagedElement xmi:type="uml:Class" xmi:id="Interface" name="Interface"> + <generalization xmi:id="Interface-_generalization.0" general="Namespace"/> + <ownedAttribute xmi:id="Interface-implicitOperation" name="implicitOperation" aggregation="composite" subsettedProperty="Namespace-implicitMember" association="_packagedElement.12"> + <type xmi:type="uml:Class" href="pathmap://UML_METAMODELS/UML.metamodel.uml#Operation"/> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="Interface-implicitOperation-_lowerValue"/> + <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="Interface-implicitOperation-_upperValue" value="*"/> + </ownedAttribute> + </packagedElement> + <packagedElement xmi:type="uml:Association" xmi:id="_packagedElement.12" visibility="private" memberEnd="Interface-implicitOperation _packagedElement.12-implicitInterface"> + <ownedEnd xmi:id="_packagedElement.12-implicitInterface" name="implicitInterface" type="Interface" association="_packagedElement.12"> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="_packagedElement.12-implicitInterface-_lowerValue"/> + </ownedEnd> + </packagedElement> + <profileApplication xmi:id="_profileApplication.0"> + <eAnnotations xmi:id="_profileApplication.0-_http2F2Fwww.eclipse.org2Fuml22F2.0.02FUML" source="http://www.eclipse.org/uml2/2.0.0/UML"> + <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/uml2/5.0.0/UML/Profile/Standard#/"/> + </eAnnotations> + <appliedProfile href="pathmap://UML_PROFILES/Standard.profile.uml#_0"/> + </profileApplication> + <profileApplication xmi:id="_profileApplication.1"> + <eAnnotations xmi:id="_profileApplication.1-_http2F2Fwww.eclipse.org2Fuml22F2.0.02FUML" source="http://www.eclipse.org/uml2/2.0.0/UML"> + <references xmi:type="ecore:EPackage" href="pathmap://UML_PROFILES/Ecore.profile.uml#_z1OFcHjqEdy8S4Cr8Rc_NA"/> + </eAnnotations> + <appliedProfile href="pathmap://UML_PROFILES/Ecore.profile.uml#_0"/> + </profileApplication> + </uml:Model> + <Ecore:EReference xmi:id="_Y6eFMKdkEeaVuqljGw-fqQ" isTransient="true" base_Property="_packagedElement.3-implicitNamespace"/> + <Ecore:EPackage xmi:id="_lUR6gKdkEeaVuqljGw-fqQ" base_Package="_0" nsPrefix="umlext" basePackage="org.eclipse.papyrusrt.umlrt.uml.internal" prefix="UMLExt"/> + <standard:Metamodel xmi:id="_wkH3EKdkEeaVuqljGw-fqQ" base_Model="_0"/> + <standard:Metaclass xmi:id="_wkJFMKdkEeaVuqljGw-fqQ" base_Class="Namespace"/> + <standard:Metaclass xmi:id="_Vi05EKgWEeaVuqljGw-fqQ" base_Class="StructuredClassifier"/> + <standard:Metaclass xmi:id="_dJdTQ6gWEeaVuqljGw-fqQ" base_Class="EncapsulatedClassifier"/> + <standard:Metaclass xmi:id="_shDj0KggEeaVuqljGw-fqQ" base_Class="Class"/> + <Ecore:EDataType xmi:id="_EkC7YKgkEeaVuqljGw-fqQ" instanceClassName="org.eclipse.uml2.uml.Element" base_PrimitiveType="UMLElement"/> + <Ecore:EAttribute xmi:id="_X5gUMKgkEeaVuqljGw-fqQ" base_Property="Element-extendedElement"/> + <standard:Metaclass xmi:id="_hamP8KgkEeaVuqljGw-fqQ" base_Class="Element"/> + <Ecore:EReference xmi:id="_nuGvkLcxEeaYpJpPVa7-0w" isTransient="true" isVolatile="true" base_Property="Element-extension" isResolveProxies="false"/> + <Ecore:EOperation xmi:id="_vKxgALcyEeaYpJpPVa7-0w" base_Operation="Namespace-getExcludedMembers" visibility="None"/> + <Ecore:EOperation xmi:id="_yPzXQLcyEeaYpJpPVa7-0w" base_Operation="Element-getExtension" visibility="None"/> + <Ecore:EReference xmi:id="_PiML4Lc2EeaYpJpPVa7-0w" isVolatile="true" base_Property="Namespace-excludedMember"/> + <standard:Metaclass xmi:id="_jhYCQMZMEeaGEbJYZtSZBg" base_Class="Interface"/> +</xmi:XMI> diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/model/umlext.ecore b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/model/umlext.ecore new file mode 100644 index 000000000..ea9e17309 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/model/umlext.ecore @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="umlext" nsURI="http://www.eclipse.org/papyrus/umlrt/uml-ext" + nsPrefix="umlext"> + <eClassifiers xsi:type="ecore:EDataType" name="UMLElement" instanceClassName="org.eclipse.uml2.uml.Element"/> + <eClassifiers xsi:type="ecore:EClass" name="Element" abstract="true"> + <eOperations name="getExtension" ordered="false" lowerBound="1" eType="#//Element"> + <eAnnotations source="http://www.eclipse.org/emf/2002/GenModel"> + <details key="suppressedVisibility" value="true"/> + </eAnnotations> + </eOperations> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="extendedElement" ordered="false" + lowerBound="1" eType="#//UMLElement"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="extension" ordered="false" + lowerBound="1" eType="#//Element" changeable="false" volatile="true" transient="true" + derived="true" resolveProxies="false"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Namespace" abstract="true" eSuperTypes="#//Element"> + <eOperations name="getExcludedMembers" ordered="false" upperBound="-1" eType="ecore:EClass ../../org.eclipse.uml2.uml/model/UML.ecore#//NamedElement"> + <eAnnotations source="http://www.eclipse.org/emf/2002/GenModel"> + <details key="suppressedVisibility" value="true"/> + </eAnnotations> + </eOperations> + <eStructuralFeatures xsi:type="ecore:EReference" name="implicitMember" ordered="false" + upperBound="-1" eType="ecore:EClass ../../org.eclipse.uml2.uml/model/UML.ecore#//RedefinableElement" + changeable="false" volatile="true" transient="true" derived="true"> + <eAnnotations source="union"/> + </eStructuralFeatures> + <eStructuralFeatures xsi:type="ecore:EReference" name="excludedMember" ordered="false" + upperBound="-1" eType="ecore:EClass ../../org.eclipse.uml2.uml/model/UML.ecore#//NamedElement" + changeable="false" volatile="true" transient="true" derived="true"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="StructuredClassifier" abstract="true" + eSuperTypes="#//Namespace"> + <eStructuralFeatures xsi:type="ecore:EReference" name="implicitAttribute" ordered="false" + upperBound="-1" eType="ecore:EClass ../../org.eclipse.uml2.uml/model/UML.ecore#//Property" + containment="true"> + <eAnnotations source="subsets" references="#//Namespace/implicitMember"/> + </eStructuralFeatures> + <eStructuralFeatures xsi:type="ecore:EReference" name="implicitConnector" ordered="false" + upperBound="-1" eType="ecore:EClass ../../org.eclipse.uml2.uml/model/UML.ecore#//Connector" + containment="true"> + <eAnnotations source="subsets" references="#//Namespace/implicitMember"/> + </eStructuralFeatures> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="EncapsulatedClassifier" abstract="true" + eSuperTypes="#//StructuredClassifier"> + <eStructuralFeatures xsi:type="ecore:EReference" name="implicitPort" ordered="false" + upperBound="-1" eType="ecore:EClass ../../org.eclipse.uml2.uml/model/UML.ecore#//Port" + volatile="true" transient="true" derived="true"> + <eAnnotations source="subsets" references="#//StructuredClassifier/implicitAttribute"/> + </eStructuralFeatures> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Class" eSuperTypes="#//EncapsulatedClassifier"> + <eStructuralFeatures xsi:type="ecore:EReference" name="implicitOperation" ordered="false" + upperBound="-1" eType="ecore:EClass ../../org.eclipse.uml2.uml/model/UML.ecore#//Operation" + containment="true"> + <eAnnotations source="subsets" references="#//Namespace/implicitMember"/> + </eStructuralFeatures> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Interface" eSuperTypes="#//Namespace"> + <eStructuralFeatures xsi:type="ecore:EReference" name="implicitOperation" ordered="false" + upperBound="-1" eType="ecore:EClass ../../org.eclipse.uml2.uml/model/UML.ecore#//Operation" + containment="true"> + <eAnnotations source="subsets" references="#//Namespace/implicitMember"/> + </eStructuralFeatures> + </eClassifiers> +</ecore:EPackage> diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/plugin.properties b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/plugin.properties new file mode 100644 index 000000000..8c7a45a0c --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/plugin.properties @@ -0,0 +1,14 @@ +# +# Copyright (c) 2016 Christian W. Damus and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Christian W. Damus - initial API and implementation +# + +pluginName = Papyrus-RT UML Semantics for UML-RT (Incubation) +providerName = Eclipse Modeling Project diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/plugin.xml b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/plugin.xml new file mode 100644 index 000000000..3a38d8e66 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/plugin.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.0"?> + +<!-- + Copyright (c) 2016 Christian W. Damus and others. + + All rights reserved. This program and the accompanying materials + are made available under the terms of the Eclipse Public License v1.0 + which accompanies this distribution, and is available at + http://www.eclipse.org/legal/epl-v10.html + + Contributors: + Christian W. Damus - initial API and implementation + +--> + +<plugin> + + <extension point="org.eclipse.emf.ecore.generated_package"> + <!-- @generated uml-ext --> + <package + uri="http://www.eclipse.org/papyrus/umlrt/uml-ext" + class="org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage" + genModel="model/uml-ext.genmodel"/> + </extension> + + <extension + point="org.eclipse.emf.ecore.uri_mapping"> + <mapping + source="pathmap://UML_RT_UML/" + target="platform:/plugin/org.eclipse.papyrusrt.umlrt.uml/model/"> + </mapping> + </extension> + <extension + point="org.eclipse.uml2.uml.generated_package"> + <profile + location="pathmap://UML_RT_UML/uml-ext.metamodel.uml#_0" + uri="http://www.eclipse.org/papyrus/umlrt/uml-ext"> + </profile> + </extension> + +</plugin> diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/pom.xml b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/pom.xml new file mode 100644 index 000000000..ce7958bcf --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/pom.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>org.eclipse.papyrusrt.profile</artifactId> + <groupId>org.eclipse.papyrusrt</groupId> + <version>0.8.0-SNAPSHOT</version> + </parent> + <artifactId>org.eclipse.papyrusrt.umlrt.uml</artifactId> + <packaging>eclipse-plugin</packaging> +</project> diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtClass.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtClass.java new file mode 100644 index 000000000..8bb0383ee --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtClass.java @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.uml2.uml.Operation; +import org.eclipse.uml2.uml.Type; + + +/** + * <!-- begin-user-doc --> + * A representation of the model object '<em><b>Class</b></em>'. + * <!-- end-user-doc --> + * + * <p> + * The following features are supported: + * </p> + * <ul> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtClass#getImplicitOperations <em>Implicit Operation</em>}</li> + * </ul> + * + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage#getClass_() + * @model + * @generated + */ +public interface ExtClass extends ExtEncapsulatedClassifier { + + /** + * Returns the value of the '<em><b>Implicit Operation</b></em>' containment reference list. + * The list contents are of type {@link org.eclipse.uml2.uml.Operation}. + * <p> + * This feature subsets the following features: + * </p> + * <ul> + * <li>'{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace#getImplicitMembers() <em>Implicit Member</em>}'</li> + * </ul> + * <!-- begin-user-doc --> + * <p> + * If the meaning of the '<em>Implicit Operation</em>' containment reference list isn't clear, + * there really should be more of a description here... + * </p> + * <!-- end-user-doc --> + * @return the value of the '<em>Implicit Operation</em>' containment reference list. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage#getClass_ImplicitOperation() + * @model containment="true" ordered="false" + * @generated + */ + EList<Operation> getImplicitOperations(); + + /** + * Creates a new {@link org.eclipse.uml2.uml.Operation}, with the specified '<em><b>Name</b></em>', '<em><b>Owned Parameter Names</b></em>', and '<em><b>Owned Parameter Types</b></em>', and appends it to the '<em><b>Implicit Operation</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' for the new {@link org.eclipse.uml2.uml.Operation}, or <code>null</code>. + * @param ownedParameterNames The '<em><b>Owned Parameter Names</b></em>' for the new {@link org.eclipse.uml2.uml.Operation}, or <code>null</code>. + * @param ownedParameterTypes The '<em><b>Owned Parameter Types</b></em>' for the new {@link org.eclipse.uml2.uml.Operation}, or <code>null</code>. + * @return The new {@link org.eclipse.uml2.uml.Operation}. + * @see #getImplicitOperations() + * @generated + */ + Operation createImplicitOperation(String name, EList<String> ownedParameterNames, EList<Type> ownedParameterTypes); + + /** + * Retrieves the first {@link org.eclipse.uml2.uml.Operation} with the specified '<em><b>Name</b></em>', '<em><b>Owned Parameter Names</b></em>', and '<em><b>Owned Parameter Types</b></em>' from the '<em><b>Implicit Operation</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' of the {@link org.eclipse.uml2.uml.Operation} to retrieve, or <code>null</code>. + * @param ownedParameterNames The '<em><b>Owned Parameter Names</b></em>' of the {@link org.eclipse.uml2.uml.Operation} to retrieve, or <code>null</code>. + * @param ownedParameterTypes The '<em><b>Owned Parameter Types</b></em>' of the {@link org.eclipse.uml2.uml.Operation} to retrieve, or <code>null</code>. + * @return The first {@link org.eclipse.uml2.uml.Operation} with the specified '<em><b>Name</b></em>', '<em><b>Owned Parameter Names</b></em>', and '<em><b>Owned Parameter Types</b></em>', or <code>null</code>. + * @see #getImplicitOperations() + * @generated + */ + Operation getImplicitOperation(String name, EList<String> ownedParameterNames, EList<Type> ownedParameterTypes); + + /** + * Retrieves the first {@link org.eclipse.uml2.uml.Operation} with the specified '<em><b>Name</b></em>', '<em><b>Owned Parameter Names</b></em>', and '<em><b>Owned Parameter Types</b></em>' from the '<em><b>Implicit Operation</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' of the {@link org.eclipse.uml2.uml.Operation} to retrieve, or <code>null</code>. + * @param ownedParameterNames The '<em><b>Owned Parameter Names</b></em>' of the {@link org.eclipse.uml2.uml.Operation} to retrieve, or <code>null</code>. + * @param ownedParameterTypes The '<em><b>Owned Parameter Types</b></em>' of the {@link org.eclipse.uml2.uml.Operation} to retrieve, or <code>null</code>. + * @param ignoreCase Whether to ignore case in {@link java.lang.String} comparisons. + * @param createOnDemand Whether to create a {@link org.eclipse.uml2.uml.Operation} on demand if not found. + * @return The first {@link org.eclipse.uml2.uml.Operation} with the specified '<em><b>Name</b></em>', '<em><b>Owned Parameter Names</b></em>', and '<em><b>Owned Parameter Types</b></em>', or <code>null</code>. + * @see #getImplicitOperations() + * @generated + */ + Operation getImplicitOperation(String name, EList<String> ownedParameterNames, EList<Type> ownedParameterTypes, boolean ignoreCase, boolean createOnDemand); +} // Class diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtElement.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtElement.java new file mode 100644 index 000000000..59a1a2f8b --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtElement.java @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.uml2.uml.Element; + +/** + * <!-- begin-user-doc --> + * A representation of the model object '<em><b>Extension Element</b></em>'. + * <!-- end-user-doc --> + * + * <p> + * The following features are supported: + * </p> + * <ul> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement#getExtendedElement <em>Extended Element</em>}</li> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement#getExtension <em>Extension</em>}</li> + * </ul> + * + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage#getElement() + * @model abstract="true" + * @generated + */ +public interface ExtElement extends EObject { + /** + * Returns the value of the '<em><b>Extended Element</b></em>' attribute. + * <!-- begin-user-doc --> + * <p> + * If the meaning of the '<em>Extended Element</em>' attribute isn't clear, + * there really should be more of a description here... + * </p> + * <!-- end-user-doc --> + * @return the value of the '<em>Extended Element</em>' attribute. + * @see #setExtendedElement(Element) + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage#getElement_ExtendedElement() + * @model dataType="org.eclipse.papyrusrt.umlrt.uml.internal.umlext.UMLElement" required="true" ordered="false" + * @generated + */ + Element getExtendedElement(); + + /** + * Sets the value of the '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement#getExtendedElement <em>Extended Element</em>}' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param value the new value of the '<em>Extended Element</em>' attribute. + * @see #getExtendedElement() + * @generated + */ + void setExtendedElement(Element value); + + /** + * Returns the value of the '<em><b>Extension</b></em>' reference. + * <!-- begin-user-doc --> + * <p> + * If the meaning of the '<em>Extension</em>' reference isn't clear, + * there really should be more of a description here... + * </p> + * <!-- end-user-doc --> + * @return the value of the '<em>Extension</em>' reference. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage#getElement_Extension() + * @model resolveProxies="false" required="true" transient="true" changeable="false" volatile="true" derived="true" ordered="false" + * @generated + */ + ExtElement getExtension(); + +} // ExtensionElement diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtEncapsulatedClassifier.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtEncapsulatedClassifier.java new file mode 100644 index 000000000..f1f0a0126 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtEncapsulatedClassifier.java @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.Type; + +/** + * <!-- begin-user-doc --> + * A representation of the model object '<em><b>Encapsulated Classifier</b></em>'. + * <!-- end-user-doc --> + * + * <p> + * The following features are supported: + * </p> + * <ul> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtEncapsulatedClassifier#getImplicitPorts <em>Implicit Port</em>}</li> + * </ul> + * + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage#getEncapsulatedClassifier() + * @model abstract="true" + * @generated + */ +public interface ExtEncapsulatedClassifier extends ExtStructuredClassifier { + /** + * Returns the value of the '<em><b>Implicit Port</b></em>' reference list. + * The list contents are of type {@link org.eclipse.uml2.uml.Port}. + * <p> + * This feature subsets the following features: + * </p> + * <ul> + * <li>'{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtStructuredClassifier#getImplicitAttributes() <em>Implicit Attribute</em>}'</li> + * </ul> + * <!-- begin-user-doc --> + * <p> + * If the meaning of the '<em>Implicit Port</em>' reference list isn't clear, + * there really should be more of a description here... + * </p> + * <!-- end-user-doc --> + * @return the value of the '<em>Implicit Port</em>' reference list. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage#getEncapsulatedClassifier_ImplicitPort() + * @model transient="true" volatile="true" derived="true" ordered="false" + * @generated + */ + EList<Port> getImplicitPorts(); + + /** + * Creates a new {@link org.eclipse.uml2.uml.Port}, with the specified '<em><b>Name</b></em>', and '<em><b>Type</b></em>', and appends it to the '<em><b>Implicit Port</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' for the new {@link org.eclipse.uml2.uml.Port}, or <code>null</code>. + * @param type The '<em><b>Type</b></em>' for the new {@link org.eclipse.uml2.uml.Port}, or <code>null</code>. + * @return The new {@link org.eclipse.uml2.uml.Port}. + * @see #getImplicitPorts() + * @generated + */ + Port createImplicitPort(String name, Type type); + + /** + * Retrieves the first {@link org.eclipse.uml2.uml.Port} with the specified '<em><b>Name</b></em>', and '<em><b>Type</b></em>' from the '<em><b>Implicit Port</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' of the {@link org.eclipse.uml2.uml.Port} to retrieve, or <code>null</code>. + * @param type The '<em><b>Type</b></em>' of the {@link org.eclipse.uml2.uml.Port} to retrieve, or <code>null</code>. + * @return The first {@link org.eclipse.uml2.uml.Port} with the specified '<em><b>Name</b></em>', and '<em><b>Type</b></em>', or <code>null</code>. + * @see #getImplicitPorts() + * @generated + */ + Port getImplicitPort(String name, Type type); + + /** + * Retrieves the first {@link org.eclipse.uml2.uml.Port} with the specified '<em><b>Name</b></em>', and '<em><b>Type</b></em>' from the '<em><b>Implicit Port</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' of the {@link org.eclipse.uml2.uml.Port} to retrieve, or <code>null</code>. + * @param type The '<em><b>Type</b></em>' of the {@link org.eclipse.uml2.uml.Port} to retrieve, or <code>null</code>. + * @param ignoreCase Whether to ignore case in {@link java.lang.String} comparisons. + * @param createOnDemand Whether to create a {@link org.eclipse.uml2.uml.Port} on demand if not found. + * @return The first {@link org.eclipse.uml2.uml.Port} with the specified '<em><b>Name</b></em>', and '<em><b>Type</b></em>', or <code>null</code>. + * @see #getImplicitPorts() + * @generated + */ + Port getImplicitPort(String name, Type type, boolean ignoreCase, boolean createOnDemand); + +} // EncapsulatedClassifier diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtInterface.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtInterface.java new file mode 100644 index 000000000..0a116e4a2 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtInterface.java @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.uml2.uml.Operation; +import org.eclipse.uml2.uml.Type; + +/** + * <!-- begin-user-doc --> + * A representation of the model object '<em><b>Interface</b></em>'. + * <!-- end-user-doc --> + * + * <p> + * The following features are supported: + * </p> + * <ul> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtInterface#getImplicitOperations <em>Implicit Operation</em>}</li> + * </ul> + * + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage#getInterface() + * @model + * @generated + */ +public interface ExtInterface extends ExtNamespace { + /** + * Returns the value of the '<em><b>Implicit Operation</b></em>' containment reference list. + * The list contents are of type {@link org.eclipse.uml2.uml.Operation}. + * <p> + * This feature subsets the following features: + * </p> + * <ul> + * <li>'{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace#getImplicitMembers() <em>Implicit Member</em>}'</li> + * </ul> + * <!-- begin-user-doc --> + * <p> + * If the meaning of the '<em>Implicit Operation</em>' containment reference list isn't clear, + * there really should be more of a description here... + * </p> + * <!-- end-user-doc --> + * @return the value of the '<em>Implicit Operation</em>' containment reference list. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage#getInterface_ImplicitOperation() + * @model containment="true" ordered="false" + * @generated + */ + EList<Operation> getImplicitOperations(); + + /** + * Creates a new {@link org.eclipse.uml2.uml.Operation}, with the specified '<em><b>Name</b></em>', '<em><b>Owned Parameter Names</b></em>', and '<em><b>Owned Parameter Types</b></em>', and appends it to the '<em><b>Implicit Operation</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' for the new {@link org.eclipse.uml2.uml.Operation}, or <code>null</code>. + * @param ownedParameterNames The '<em><b>Owned Parameter Names</b></em>' for the new {@link org.eclipse.uml2.uml.Operation}, or <code>null</code>. + * @param ownedParameterTypes The '<em><b>Owned Parameter Types</b></em>' for the new {@link org.eclipse.uml2.uml.Operation}, or <code>null</code>. + * @return The new {@link org.eclipse.uml2.uml.Operation}. + * @see #getImplicitOperations() + * @generated + */ + Operation createImplicitOperation(String name, EList<String> ownedParameterNames, EList<Type> ownedParameterTypes); + + /** + * Retrieves the first {@link org.eclipse.uml2.uml.Operation} with the specified '<em><b>Name</b></em>', '<em><b>Owned Parameter Names</b></em>', and '<em><b>Owned Parameter Types</b></em>' from the '<em><b>Implicit Operation</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' of the {@link org.eclipse.uml2.uml.Operation} to retrieve, or <code>null</code>. + * @param ownedParameterNames The '<em><b>Owned Parameter Names</b></em>' of the {@link org.eclipse.uml2.uml.Operation} to retrieve, or <code>null</code>. + * @param ownedParameterTypes The '<em><b>Owned Parameter Types</b></em>' of the {@link org.eclipse.uml2.uml.Operation} to retrieve, or <code>null</code>. + * @return The first {@link org.eclipse.uml2.uml.Operation} with the specified '<em><b>Name</b></em>', '<em><b>Owned Parameter Names</b></em>', and '<em><b>Owned Parameter Types</b></em>', or <code>null</code>. + * @see #getImplicitOperations() + * @generated + */ + Operation getImplicitOperation(String name, EList<String> ownedParameterNames, EList<Type> ownedParameterTypes); + + /** + * Retrieves the first {@link org.eclipse.uml2.uml.Operation} with the specified '<em><b>Name</b></em>', '<em><b>Owned Parameter Names</b></em>', and '<em><b>Owned Parameter Types</b></em>' from the '<em><b>Implicit Operation</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' of the {@link org.eclipse.uml2.uml.Operation} to retrieve, or <code>null</code>. + * @param ownedParameterNames The '<em><b>Owned Parameter Names</b></em>' of the {@link org.eclipse.uml2.uml.Operation} to retrieve, or <code>null</code>. + * @param ownedParameterTypes The '<em><b>Owned Parameter Types</b></em>' of the {@link org.eclipse.uml2.uml.Operation} to retrieve, or <code>null</code>. + * @param ignoreCase Whether to ignore case in {@link java.lang.String} comparisons. + * @param createOnDemand Whether to create a {@link org.eclipse.uml2.uml.Operation} on demand if not found. + * @return The first {@link org.eclipse.uml2.uml.Operation} with the specified '<em><b>Name</b></em>', '<em><b>Owned Parameter Names</b></em>', and '<em><b>Owned Parameter Types</b></em>', or <code>null</code>. + * @see #getImplicitOperations() + * @generated + */ + Operation getImplicitOperation(String name, EList<String> ownedParameterNames, EList<Type> ownedParameterTypes, boolean ignoreCase, boolean createOnDemand); + +} // ExtInterface diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtNamespace.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtNamespace.java new file mode 100644 index 000000000..ba60c08e5 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtNamespace.java @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.uml2.uml.NamedElement; +import org.eclipse.uml2.uml.RedefinableElement; + +/** + * <!-- begin-user-doc --> + * A representation of the model object '<em><b>Namespace</b></em>'. + * <!-- end-user-doc --> + * + * <p> + * The following features are supported: + * </p> + * <ul> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace#getImplicitMembers <em>Implicit Member</em>}</li> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace#getExcludedMembers <em>Excluded Member</em>}</li> + * </ul> + * + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage#getNamespace() + * @model abstract="true" + * @generated + */ +public interface ExtNamespace extends ExtElement { + /** + * Returns the value of the '<em><b>Implicit Member</b></em>' reference list. + * The list contents are of type {@link org.eclipse.uml2.uml.RedefinableElement}. + * This feature is a derived union. + * <!-- begin-user-doc --> + * <p> + * If the meaning of the '<em>Implicit Member</em>' containment reference list isn't clear, + * there really should be more of a description here... + * </p> + * <!-- end-user-doc --> + * @return the value of the '<em>Implicit Member</em>' reference list. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage#getNamespace_ImplicitMember() + * @model transient="true" changeable="false" volatile="true" derived="true" ordered="false" + * @generated + */ + EList<RedefinableElement> getImplicitMembers(); + + /** + * Retrieves the first {@link org.eclipse.uml2.uml.RedefinableElement} with the specified '<em><b>Name</b></em>' from the '<em><b>Implicit Member</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' of the {@link org.eclipse.uml2.uml.RedefinableElement} to retrieve, or <code>null</code>. + * @return The first {@link org.eclipse.uml2.uml.RedefinableElement} with the specified '<em><b>Name</b></em>', or <code>null</code>. + * @see #getImplicitMembers() + * @generated + */ + RedefinableElement getImplicitMember(String name); + + /** + * Retrieves the first {@link org.eclipse.uml2.uml.RedefinableElement} with the specified '<em><b>Name</b></em>' from the '<em><b>Implicit Member</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' of the {@link org.eclipse.uml2.uml.RedefinableElement} to retrieve, or <code>null</code>. + * @param ignoreCase Whether to ignore case in {@link java.lang.String} comparisons. + * @param eClass The Ecore class of the {@link org.eclipse.uml2.uml.RedefinableElement} to retrieve, or <code>null</code>. + * @return The first {@link org.eclipse.uml2.uml.RedefinableElement} with the specified '<em><b>Name</b></em>', or <code>null</code>. + * @see #getImplicitMembers() + * @generated + */ + RedefinableElement getImplicitMember(String name, boolean ignoreCase, EClass eClass); + + /** + * Returns the value of the '<em><b>Excluded Member</b></em>' reference list. + * The list contents are of type {@link org.eclipse.uml2.uml.NamedElement}. + * <!-- begin-user-doc --> + * <p> + * If the meaning of the '<em>Excluded Member</em>' reference list isn't clear, + * there really should be more of a description here... + * </p> + * <!-- end-user-doc --> + * @return the value of the '<em>Excluded Member</em>' reference list. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage#getNamespace_ExcludedMember() + * @model transient="true" changeable="false" volatile="true" derived="true" ordered="false" + * @generated + */ + EList<NamedElement> getExcludedMembers(); + + /** + * Retrieves the first {@link org.eclipse.uml2.uml.NamedElement} with the specified '<em><b>Name</b></em>' from the '<em><b>Excluded Member</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' of the {@link org.eclipse.uml2.uml.NamedElement} to retrieve, or <code>null</code>. + * @return The first {@link org.eclipse.uml2.uml.NamedElement} with the specified '<em><b>Name</b></em>', or <code>null</code>. + * @see #getExcludedMembers() + * @generated + */ + NamedElement getExcludedMember(String name); + + /** + * Retrieves the first {@link org.eclipse.uml2.uml.NamedElement} with the specified '<em><b>Name</b></em>' from the '<em><b>Excluded Member</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' of the {@link org.eclipse.uml2.uml.NamedElement} to retrieve, or <code>null</code>. + * @param ignoreCase Whether to ignore case in {@link java.lang.String} comparisons. + * @param eClass The Ecore class of the {@link org.eclipse.uml2.uml.NamedElement} to retrieve, or <code>null</code>. + * @return The first {@link org.eclipse.uml2.uml.NamedElement} with the specified '<em><b>Name</b></em>', or <code>null</code>. + * @see #getExcludedMembers() + * @generated + */ + NamedElement getExcludedMember(String name, boolean ignoreCase, EClass eClass); + +} // Namespace diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtStructuredClassifier.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtStructuredClassifier.java new file mode 100644 index 000000000..4afe41f2d --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtStructuredClassifier.java @@ -0,0 +1,172 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.uml2.uml.Connector; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.Type; + +/** + * <!-- begin-user-doc --> + * A representation of the model object '<em><b>Structured Classifier</b></em>'. + * <!-- end-user-doc --> + * + * <p> + * The following features are supported: + * </p> + * <ul> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtStructuredClassifier#getImplicitAttributes <em>Implicit Attribute</em>}</li> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtStructuredClassifier#getImplicitConnectors <em>Implicit Connector</em>}</li> + * </ul> + * + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage#getStructuredClassifier() + * @model abstract="true" + * @generated + */ +public interface ExtStructuredClassifier extends ExtNamespace { + /** + * Returns the value of the '<em><b>Implicit Attribute</b></em>' containment reference list. + * The list contents are of type {@link org.eclipse.uml2.uml.Property}. + * <p> + * This feature subsets the following features: + * </p> + * <ul> + * <li>'{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace#getImplicitMembers() <em>Implicit Member</em>}'</li> + * </ul> + * <!-- begin-user-doc --> + * <p> + * If the meaning of the '<em>Implicit Attribute</em>' containment reference list isn't clear, + * there really should be more of a description here... + * </p> + * <!-- end-user-doc --> + * @return the value of the '<em>Implicit Attribute</em>' containment reference list. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage#getStructuredClassifier_ImplicitAttribute() + * @model containment="true" ordered="false" + * @generated + */ + EList<Property> getImplicitAttributes(); + + /** + * Creates a new {@link org.eclipse.uml2.uml.Property}, with the specified '<em><b>Name</b></em>', and '<em><b>Type</b></em>', and appends it to the '<em><b>Implicit Attribute</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' for the new {@link org.eclipse.uml2.uml.Property}, or <code>null</code>. + * @param type The '<em><b>Type</b></em>' for the new {@link org.eclipse.uml2.uml.Property}, or <code>null</code>. + * @param eClass The Ecore class of the {@link org.eclipse.uml2.uml.Property} to create. + * @return The new {@link org.eclipse.uml2.uml.Property}. + * @see #getImplicitAttributes() + * @generated + */ + Property createImplicitAttribute(String name, Type type, EClass eClass); + + /** + * Creates a new {@link org.eclipse.uml2.uml.Property}, with the specified '<em><b>Name</b></em>', and '<em><b>Type</b></em>', and appends it to the '<em><b>Implicit Attribute</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' for the new {@link org.eclipse.uml2.uml.Property}, or <code>null</code>. + * @param type The '<em><b>Type</b></em>' for the new {@link org.eclipse.uml2.uml.Property}, or <code>null</code>. + * @return The new {@link org.eclipse.uml2.uml.Property}. + * @see #getImplicitAttributes() + * @generated + */ + Property createImplicitAttribute(String name, Type type); + + /** + * Retrieves the first {@link org.eclipse.uml2.uml.Property} with the specified '<em><b>Name</b></em>', and '<em><b>Type</b></em>' from the '<em><b>Implicit Attribute</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' of the {@link org.eclipse.uml2.uml.Property} to retrieve, or <code>null</code>. + * @param type The '<em><b>Type</b></em>' of the {@link org.eclipse.uml2.uml.Property} to retrieve, or <code>null</code>. + * @return The first {@link org.eclipse.uml2.uml.Property} with the specified '<em><b>Name</b></em>', and '<em><b>Type</b></em>', or <code>null</code>. + * @see #getImplicitAttributes() + * @generated + */ + Property getImplicitAttribute(String name, Type type); + + /** + * Retrieves the first {@link org.eclipse.uml2.uml.Property} with the specified '<em><b>Name</b></em>', and '<em><b>Type</b></em>' from the '<em><b>Implicit Attribute</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' of the {@link org.eclipse.uml2.uml.Property} to retrieve, or <code>null</code>. + * @param type The '<em><b>Type</b></em>' of the {@link org.eclipse.uml2.uml.Property} to retrieve, or <code>null</code>. + * @param ignoreCase Whether to ignore case in {@link java.lang.String} comparisons. + * @param eClass The Ecore class of the {@link org.eclipse.uml2.uml.Property} to retrieve, or <code>null</code>. + * @param createOnDemand Whether to create a {@link org.eclipse.uml2.uml.Property} on demand if not found. + * @return The first {@link org.eclipse.uml2.uml.Property} with the specified '<em><b>Name</b></em>', and '<em><b>Type</b></em>', or <code>null</code>. + * @see #getImplicitAttributes() + * @generated + */ + Property getImplicitAttribute(String name, Type type, boolean ignoreCase, EClass eClass, boolean createOnDemand); + + /** + * Returns the value of the '<em><b>Implicit Connector</b></em>' containment reference list. + * The list contents are of type {@link org.eclipse.uml2.uml.Connector}. + * <p> + * This feature subsets the following features: + * </p> + * <ul> + * <li>'{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace#getImplicitMembers() <em>Implicit Member</em>}'</li> + * </ul> + * <!-- begin-user-doc --> + * <p> + * If the meaning of the '<em>Implicit Connector</em>' containment reference list isn't clear, + * there really should be more of a description here... + * </p> + * <!-- end-user-doc --> + * @return the value of the '<em>Implicit Connector</em>' containment reference list. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage#getStructuredClassifier_ImplicitConnector() + * @model containment="true" ordered="false" + * @generated + */ + EList<Connector> getImplicitConnectors(); + + /** + * Creates a new {@link org.eclipse.uml2.uml.Connector}, with the specified '<em><b>Name</b></em>', and appends it to the '<em><b>Implicit Connector</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' for the new {@link org.eclipse.uml2.uml.Connector}, or <code>null</code>. + * @return The new {@link org.eclipse.uml2.uml.Connector}. + * @see #getImplicitConnectors() + * @generated + */ + Connector createImplicitConnector(String name); + + /** + * Retrieves the first {@link org.eclipse.uml2.uml.Connector} with the specified '<em><b>Name</b></em>' from the '<em><b>Implicit Connector</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' of the {@link org.eclipse.uml2.uml.Connector} to retrieve, or <code>null</code>. + * @return The first {@link org.eclipse.uml2.uml.Connector} with the specified '<em><b>Name</b></em>', or <code>null</code>. + * @see #getImplicitConnectors() + * @generated + */ + Connector getImplicitConnector(String name); + + /** + * Retrieves the first {@link org.eclipse.uml2.uml.Connector} with the specified '<em><b>Name</b></em>' from the '<em><b>Implicit Connector</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param name The '<em><b>Name</b></em>' of the {@link org.eclipse.uml2.uml.Connector} to retrieve, or <code>null</code>. + * @param ignoreCase Whether to ignore case in {@link java.lang.String} comparisons. + * @param createOnDemand Whether to create a {@link org.eclipse.uml2.uml.Connector} on demand if not found. + * @return The first {@link org.eclipse.uml2.uml.Connector} with the specified '<em><b>Name</b></em>', or <code>null</code>. + * @see #getImplicitConnectors() + * @generated + */ + Connector getImplicitConnector(String name, boolean ignoreCase, boolean createOnDemand); + +} // StructuredClassifier diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtUMLExtFactory.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtUMLExtFactory.java new file mode 100644 index 000000000..b6d9d75ac --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtUMLExtFactory.java @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext; + +import org.eclipse.emf.ecore.EFactory; + +/** + * <!-- begin-user-doc --> + * The <b>Factory</b> for the model. + * It provides a create method for each non-abstract class of the model. + * <!-- end-user-doc --> + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage + * @generated + */ +public interface ExtUMLExtFactory extends EFactory { + /** + * The singleton instance of the factory. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + ExtUMLExtFactory eINSTANCE = org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtUMLExtFactoryImpl.init(); + + /** + * Returns a new object of class '<em>Class</em>'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return a new object of class '<em>Class</em>'. + * @generated + */ + ExtClass createClass(); + + /** + * Returns a new object of class '<em>Interface</em>'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return a new object of class '<em>Interface</em>'. + * @generated + */ + ExtInterface createInterface(); + + /** + * Returns the package supported by this factory. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the package supported by this factory. + * @generated + */ + ExtUMLExtPackage getUMLExtPackage(); + +} //UMLExtFactory diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtUMLExtPackage.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtUMLExtPackage.java new file mode 100644 index 000000000..95e4a813f --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/ExtUMLExtPackage.java @@ -0,0 +1,1012 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EOperation; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +/** + * <!-- begin-user-doc --> + * The <b>Package</b> for the model. + * It contains accessors for the meta objects to represent + * <ul> + * <li>each class,</li> + * <li>each feature of each class,</li> + * <li>each operation of each class,</li> + * <li>each enum,</li> + * <li>and each data type</li> + * </ul> + * <!-- end-user-doc --> + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtFactory + * @model kind="package" + * @generated + */ +public interface ExtUMLExtPackage extends EPackage { + /** + * The package name. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + String eNAME = "umlext"; //$NON-NLS-1$ + + /** + * The package namespace URI. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + String eNS_URI = "http://www.eclipse.org/papyrus/umlrt/uml-ext"; //$NON-NLS-1$ + + /** + * The package namespace name. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + String eNS_PREFIX = "umlext"; //$NON-NLS-1$ + + /** + * The singleton instance of the package. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + ExtUMLExtPackage eINSTANCE = org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtUMLExtPackageImpl.init(); + + /** + * The meta object id for the '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtNamespaceImpl <em>Namespace</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtNamespaceImpl + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtUMLExtPackageImpl#getNamespace() + * @generated + */ + int NAMESPACE = 1; + + /** + * The meta object id for the '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtStructuredClassifierImpl <em>Structured Classifier</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtStructuredClassifierImpl + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtUMLExtPackageImpl#getStructuredClassifier() + * @generated + */ + int STRUCTURED_CLASSIFIER = 2; + + /** + * The meta object id for the '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtEncapsulatedClassifierImpl <em>Encapsulated Classifier</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtEncapsulatedClassifierImpl + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtUMLExtPackageImpl#getEncapsulatedClassifier() + * @generated + */ + int ENCAPSULATED_CLASSIFIER = 3; + + /** + * The meta object id for the '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtClassImpl <em>Class</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtClassImpl + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtUMLExtPackageImpl#getClass_() + * @generated + */ + int CLASS = 4; + + /** + * The meta object id for the '<em>UML Element</em>' data type. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.uml2.uml.Element + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtUMLExtPackageImpl#getUMLElement() + * @generated + */ + int UML_ELEMENT = 6; + + /** + * The meta object id for the '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtElementImpl <em>Element</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtElementImpl + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtUMLExtPackageImpl#getElement() + * @generated + */ + int ELEMENT = 0; + + + /** + * The feature id for the '<em><b>Extended Element</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ELEMENT__EXTENDED_ELEMENT = 0; + + /** + * The feature id for the '<em><b>Extension</b></em>' reference. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ELEMENT__EXTENSION = 1; + + /** + * The number of structural features of the '<em>Element</em>' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ELEMENT_FEATURE_COUNT = 2; + + /** + * The operation id for the '<em>Get Extension</em>' operation. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ELEMENT___GET_EXTENSION = 0; + + /** + * The number of operations of the '<em>Element</em>' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ELEMENT_OPERATION_COUNT = 1; + + /** + * The feature id for the '<em><b>Extended Element</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int NAMESPACE__EXTENDED_ELEMENT = ELEMENT__EXTENDED_ELEMENT; + + /** + * The feature id for the '<em><b>Extension</b></em>' reference. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int NAMESPACE__EXTENSION = ELEMENT__EXTENSION; + + /** + * The feature id for the '<em><b>Implicit Member</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int NAMESPACE__IMPLICIT_MEMBER = ELEMENT_FEATURE_COUNT + 0; + + /** + * The feature id for the '<em><b>Excluded Member</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int NAMESPACE__EXCLUDED_MEMBER = ELEMENT_FEATURE_COUNT + 1; + + /** + * The number of structural features of the '<em>Namespace</em>' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int NAMESPACE_FEATURE_COUNT = ELEMENT_FEATURE_COUNT + 2; + + /** + * The operation id for the '<em>Get Extension</em>' operation. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int NAMESPACE___GET_EXTENSION = ELEMENT___GET_EXTENSION; + + /** + * The operation id for the '<em>Get Excluded Members</em>' operation. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int NAMESPACE___GET_EXCLUDED_MEMBERS = ELEMENT_OPERATION_COUNT + 0; + + /** + * The number of operations of the '<em>Namespace</em>' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int NAMESPACE_OPERATION_COUNT = ELEMENT_OPERATION_COUNT + 1; + + /** + * The feature id for the '<em><b>Extended Element</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int STRUCTURED_CLASSIFIER__EXTENDED_ELEMENT = NAMESPACE__EXTENDED_ELEMENT; + + /** + * The feature id for the '<em><b>Extension</b></em>' reference. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int STRUCTURED_CLASSIFIER__EXTENSION = NAMESPACE__EXTENSION; + + /** + * The feature id for the '<em><b>Implicit Member</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int STRUCTURED_CLASSIFIER__IMPLICIT_MEMBER = NAMESPACE__IMPLICIT_MEMBER; + + /** + * The feature id for the '<em><b>Excluded Member</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int STRUCTURED_CLASSIFIER__EXCLUDED_MEMBER = NAMESPACE__EXCLUDED_MEMBER; + + /** + * The feature id for the '<em><b>Implicit Attribute</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE = NAMESPACE_FEATURE_COUNT + 0; + + /** + * The feature id for the '<em><b>Implicit Connector</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR = NAMESPACE_FEATURE_COUNT + 1; + + /** + * The number of structural features of the '<em>Structured Classifier</em>' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int STRUCTURED_CLASSIFIER_FEATURE_COUNT = NAMESPACE_FEATURE_COUNT + 2; + + /** + * The operation id for the '<em>Get Extension</em>' operation. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int STRUCTURED_CLASSIFIER___GET_EXTENSION = NAMESPACE___GET_EXTENSION; + + /** + * The operation id for the '<em>Get Excluded Members</em>' operation. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int STRUCTURED_CLASSIFIER___GET_EXCLUDED_MEMBERS = NAMESPACE___GET_EXCLUDED_MEMBERS; + + /** + * The number of operations of the '<em>Structured Classifier</em>' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int STRUCTURED_CLASSIFIER_OPERATION_COUNT = NAMESPACE_OPERATION_COUNT + 0; + + /** + * The feature id for the '<em><b>Extended Element</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ENCAPSULATED_CLASSIFIER__EXTENDED_ELEMENT = STRUCTURED_CLASSIFIER__EXTENDED_ELEMENT; + + /** + * The feature id for the '<em><b>Extension</b></em>' reference. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ENCAPSULATED_CLASSIFIER__EXTENSION = STRUCTURED_CLASSIFIER__EXTENSION; + + /** + * The feature id for the '<em><b>Implicit Member</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ENCAPSULATED_CLASSIFIER__IMPLICIT_MEMBER = STRUCTURED_CLASSIFIER__IMPLICIT_MEMBER; + + /** + * The feature id for the '<em><b>Excluded Member</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ENCAPSULATED_CLASSIFIER__EXCLUDED_MEMBER = STRUCTURED_CLASSIFIER__EXCLUDED_MEMBER; + + /** + * The feature id for the '<em><b>Implicit Attribute</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ENCAPSULATED_CLASSIFIER__IMPLICIT_ATTRIBUTE = STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE; + + /** + * The feature id for the '<em><b>Implicit Connector</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ENCAPSULATED_CLASSIFIER__IMPLICIT_CONNECTOR = STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR; + + /** + * The feature id for the '<em><b>Implicit Port</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT = STRUCTURED_CLASSIFIER_FEATURE_COUNT + 0; + + /** + * The number of structural features of the '<em>Encapsulated Classifier</em>' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ENCAPSULATED_CLASSIFIER_FEATURE_COUNT = STRUCTURED_CLASSIFIER_FEATURE_COUNT + 1; + + /** + * The operation id for the '<em>Get Extension</em>' operation. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ENCAPSULATED_CLASSIFIER___GET_EXTENSION = STRUCTURED_CLASSIFIER___GET_EXTENSION; + + /** + * The operation id for the '<em>Get Excluded Members</em>' operation. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ENCAPSULATED_CLASSIFIER___GET_EXCLUDED_MEMBERS = STRUCTURED_CLASSIFIER___GET_EXCLUDED_MEMBERS; + + /** + * The number of operations of the '<em>Encapsulated Classifier</em>' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ENCAPSULATED_CLASSIFIER_OPERATION_COUNT = STRUCTURED_CLASSIFIER_OPERATION_COUNT + 0; + + /** + * The feature id for the '<em><b>Extended Element</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int CLASS__EXTENDED_ELEMENT = ENCAPSULATED_CLASSIFIER__EXTENDED_ELEMENT; + + /** + * The feature id for the '<em><b>Extension</b></em>' reference. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int CLASS__EXTENSION = ENCAPSULATED_CLASSIFIER__EXTENSION; + + /** + * The feature id for the '<em><b>Implicit Member</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int CLASS__IMPLICIT_MEMBER = ENCAPSULATED_CLASSIFIER__IMPLICIT_MEMBER; + + /** + * The feature id for the '<em><b>Excluded Member</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int CLASS__EXCLUDED_MEMBER = ENCAPSULATED_CLASSIFIER__EXCLUDED_MEMBER; + + /** + * The feature id for the '<em><b>Implicit Attribute</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int CLASS__IMPLICIT_ATTRIBUTE = ENCAPSULATED_CLASSIFIER__IMPLICIT_ATTRIBUTE; + + /** + * The feature id for the '<em><b>Implicit Connector</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int CLASS__IMPLICIT_CONNECTOR = ENCAPSULATED_CLASSIFIER__IMPLICIT_CONNECTOR; + + /** + * The feature id for the '<em><b>Implicit Port</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int CLASS__IMPLICIT_PORT = ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT; + + /** + * The feature id for the '<em><b>Implicit Operation</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int CLASS__IMPLICIT_OPERATION = ENCAPSULATED_CLASSIFIER_FEATURE_COUNT + 0; + + /** + * The number of structural features of the '<em>Class</em>' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int CLASS_FEATURE_COUNT = ENCAPSULATED_CLASSIFIER_FEATURE_COUNT + 1; + + /** + * The operation id for the '<em>Get Extension</em>' operation. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int CLASS___GET_EXTENSION = ENCAPSULATED_CLASSIFIER___GET_EXTENSION; + + /** + * The operation id for the '<em>Get Excluded Members</em>' operation. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int CLASS___GET_EXCLUDED_MEMBERS = ENCAPSULATED_CLASSIFIER___GET_EXCLUDED_MEMBERS; + + /** + * The number of operations of the '<em>Class</em>' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int CLASS_OPERATION_COUNT = ENCAPSULATED_CLASSIFIER_OPERATION_COUNT + 0; + + + /** + * The meta object id for the '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtInterfaceImpl <em>Interface</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtInterfaceImpl + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtUMLExtPackageImpl#getInterface() + * @generated + */ + int INTERFACE = 5; + + /** + * The feature id for the '<em><b>Extended Element</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int INTERFACE__EXTENDED_ELEMENT = NAMESPACE__EXTENDED_ELEMENT; + + /** + * The feature id for the '<em><b>Extension</b></em>' reference. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int INTERFACE__EXTENSION = NAMESPACE__EXTENSION; + + /** + * The feature id for the '<em><b>Implicit Member</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int INTERFACE__IMPLICIT_MEMBER = NAMESPACE__IMPLICIT_MEMBER; + + /** + * The feature id for the '<em><b>Excluded Member</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int INTERFACE__EXCLUDED_MEMBER = NAMESPACE__EXCLUDED_MEMBER; + + /** + * The feature id for the '<em><b>Implicit Operation</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int INTERFACE__IMPLICIT_OPERATION = NAMESPACE_FEATURE_COUNT + 0; + + /** + * The number of structural features of the '<em>Interface</em>' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int INTERFACE_FEATURE_COUNT = NAMESPACE_FEATURE_COUNT + 1; + + /** + * The operation id for the '<em>Get Extension</em>' operation. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int INTERFACE___GET_EXTENSION = NAMESPACE___GET_EXTENSION; + + /** + * The operation id for the '<em>Get Excluded Members</em>' operation. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int INTERFACE___GET_EXCLUDED_MEMBERS = NAMESPACE___GET_EXCLUDED_MEMBERS; + + /** + * The number of operations of the '<em>Interface</em>' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int INTERFACE_OPERATION_COUNT = NAMESPACE_OPERATION_COUNT + 0; + + + /** + * Returns the meta object for class '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace <em>Namespace</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for class '<em>Namespace</em>'. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace + * @generated + */ + EClass getNamespace(); + + /** + * Returns the meta object for the reference list '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace#getImplicitMembers <em>Implicit Member</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the reference list '<em>Implicit Member</em>'. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace#getImplicitMembers() + * @see #getNamespace() + * @generated + */ + EReference getNamespace_ImplicitMember(); + + /** + * Returns the meta object for the reference list '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace#getExcludedMembers <em>Excluded Member</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the reference list '<em>Excluded Member</em>'. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace#getExcludedMembers() + * @see #getNamespace() + * @generated + */ + EReference getNamespace_ExcludedMember(); + + /** + * Returns the meta object for the '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace#getExcludedMembers() <em>Get Excluded Members</em>}' operation. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the '<em>Get Excluded Members</em>' operation. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace#getExcludedMembers() + * @generated + */ + EOperation getNamespace__GetExcludedMembers(); + + /** + * Returns the meta object for class '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtStructuredClassifier <em>Structured Classifier</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for class '<em>Structured Classifier</em>'. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtStructuredClassifier + * @generated + */ + EClass getStructuredClassifier(); + + /** + * Returns the meta object for the containment reference list '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtStructuredClassifier#getImplicitAttributes <em>Implicit Attribute</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the containment reference list '<em>Implicit Attribute</em>'. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtStructuredClassifier#getImplicitAttributes() + * @see #getStructuredClassifier() + * @generated + */ + EReference getStructuredClassifier_ImplicitAttribute(); + + /** + * Returns the meta object for the containment reference list '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtStructuredClassifier#getImplicitConnectors <em>Implicit Connector</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the containment reference list '<em>Implicit Connector</em>'. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtStructuredClassifier#getImplicitConnectors() + * @see #getStructuredClassifier() + * @generated + */ + EReference getStructuredClassifier_ImplicitConnector(); + + /** + * Returns the meta object for class '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtEncapsulatedClassifier <em>Encapsulated Classifier</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for class '<em>Encapsulated Classifier</em>'. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtEncapsulatedClassifier + * @generated + */ + EClass getEncapsulatedClassifier(); + + /** + * Returns the meta object for the reference list '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtEncapsulatedClassifier#getImplicitPorts <em>Implicit Port</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the reference list '<em>Implicit Port</em>'. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtEncapsulatedClassifier#getImplicitPorts() + * @see #getEncapsulatedClassifier() + * @generated + */ + EReference getEncapsulatedClassifier_ImplicitPort(); + + /** + * Returns the meta object for class '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtClass <em>Class</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for class '<em>Class</em>'. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtClass + * @generated + */ + EClass getClass_(); + + /** + * Returns the meta object for the containment reference list '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtClass#getImplicitOperations <em>Implicit Operation</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the containment reference list '<em>Implicit Operation</em>'. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtClass#getImplicitOperations() + * @see #getClass_() + * @generated + */ + EReference getClass_ImplicitOperation(); + + /** + * Returns the meta object for class '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtInterface <em>Interface</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for class '<em>Interface</em>'. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtInterface + * @generated + */ + EClass getInterface(); + + /** + * Returns the meta object for the containment reference list '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtInterface#getImplicitOperations <em>Implicit Operation</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the containment reference list '<em>Implicit Operation</em>'. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtInterface#getImplicitOperations() + * @see #getInterface() + * @generated + */ + EReference getInterface_ImplicitOperation(); + + /** + * Returns the meta object for data type '{@link org.eclipse.uml2.uml.Element <em>UML Element</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for data type '<em>UML Element</em>'. + * @see org.eclipse.uml2.uml.Element + * @model instanceClass="org.eclipse.uml2.uml.Element" + * @generated + */ + EDataType getUMLElement(); + + /** + * Returns the meta object for class '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement <em>Element</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for class '<em>Element</em>'. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement + * @generated + */ + EClass getElement(); + + /** + * Returns the meta object for the attribute '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement#getExtendedElement <em>Extended Element</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the attribute '<em>Extended Element</em>'. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement#getExtendedElement() + * @see #getElement() + * @generated + */ + EAttribute getElement_ExtendedElement(); + + /** + * Returns the meta object for the reference '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement#getExtension <em>Extension</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the reference '<em>Extension</em>'. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement#getExtension() + * @see #getElement() + * @generated + */ + EReference getElement_Extension(); + + /** + * Returns the meta object for the '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement#getExtension() <em>Get Extension</em>}' operation. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the '<em>Get Extension</em>' operation. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement#getExtension() + * @generated + */ + EOperation getElement__GetExtension(); + + /** + * Returns the factory that creates the instances of the model. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the factory that creates the instances of the model. + * @generated + */ + ExtUMLExtFactory getUMLExtFactory(); + + /** + * <!-- begin-user-doc --> + * Defines literals for the meta objects that represent + * <ul> + * <li>each class,</li> + * <li>each feature of each class,</li> + * <li>each operation of each class,</li> + * <li>each enum,</li> + * <li>and each data type</li> + * </ul> + * <!-- end-user-doc --> + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtNamespaceImpl <em>Namespace</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtNamespaceImpl + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtUMLExtPackageImpl#getNamespace() + * @generated + */ + EClass NAMESPACE = eINSTANCE.getNamespace(); + + /** + * The meta object literal for the '<em><b>Implicit Member</b></em>' reference list feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EReference NAMESPACE__IMPLICIT_MEMBER = eINSTANCE.getNamespace_ImplicitMember(); + + /** + * The meta object literal for the '<em><b>Excluded Member</b></em>' reference list feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EReference NAMESPACE__EXCLUDED_MEMBER = eINSTANCE.getNamespace_ExcludedMember(); + + /** + * The meta object literal for the '<em><b>Get Excluded Members</b></em>' operation. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EOperation NAMESPACE___GET_EXCLUDED_MEMBERS = eINSTANCE.getNamespace__GetExcludedMembers(); + + /** + * The meta object literal for the '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtStructuredClassifierImpl <em>Structured Classifier</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtStructuredClassifierImpl + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtUMLExtPackageImpl#getStructuredClassifier() + * @generated + */ + EClass STRUCTURED_CLASSIFIER = eINSTANCE.getStructuredClassifier(); + + /** + * The meta object literal for the '<em><b>Implicit Attribute</b></em>' containment reference list feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EReference STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE = eINSTANCE.getStructuredClassifier_ImplicitAttribute(); + + /** + * The meta object literal for the '<em><b>Implicit Connector</b></em>' containment reference list feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EReference STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR = eINSTANCE.getStructuredClassifier_ImplicitConnector(); + + /** + * The meta object literal for the '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtEncapsulatedClassifierImpl <em>Encapsulated Classifier</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtEncapsulatedClassifierImpl + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtUMLExtPackageImpl#getEncapsulatedClassifier() + * @generated + */ + EClass ENCAPSULATED_CLASSIFIER = eINSTANCE.getEncapsulatedClassifier(); + + /** + * The meta object literal for the '<em><b>Implicit Port</b></em>' reference list feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EReference ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT = eINSTANCE.getEncapsulatedClassifier_ImplicitPort(); + + /** + * The meta object literal for the '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtClassImpl <em>Class</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtClassImpl + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtUMLExtPackageImpl#getClass_() + * @generated + */ + EClass CLASS = eINSTANCE.getClass_(); + + /** + * The meta object literal for the '<em><b>Implicit Operation</b></em>' containment reference list feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EReference CLASS__IMPLICIT_OPERATION = eINSTANCE.getClass_ImplicitOperation(); + + /** + * The meta object literal for the '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtInterfaceImpl <em>Interface</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtInterfaceImpl + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtUMLExtPackageImpl#getInterface() + * @generated + */ + EClass INTERFACE = eINSTANCE.getInterface(); + + /** + * The meta object literal for the '<em><b>Implicit Operation</b></em>' containment reference list feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EReference INTERFACE__IMPLICIT_OPERATION = eINSTANCE.getInterface_ImplicitOperation(); + + /** + * The meta object literal for the '<em>UML Element</em>' data type. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.uml2.uml.Element + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtUMLExtPackageImpl#getUMLElement() + * @generated + */ + EDataType UML_ELEMENT = eINSTANCE.getUMLElement(); + + /** + * The meta object literal for the '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtElementImpl <em>Element</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtElementImpl + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtUMLExtPackageImpl#getElement() + * @generated + */ + EClass ELEMENT = eINSTANCE.getElement(); + + /** + * The meta object literal for the '<em><b>Extended Element</b></em>' attribute feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EAttribute ELEMENT__EXTENDED_ELEMENT = eINSTANCE.getElement_ExtendedElement(); + + /** + * The meta object literal for the '<em><b>Extension</b></em>' reference feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EReference ELEMENT__EXTENSION = eINSTANCE.getElement_Extension(); + + /** + * The meta object literal for the '<em><b>Get Extension</b></em>' operation. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EOperation ELEMENT___GET_EXTENSION = eINSTANCE.getElement__GetExtension(); + + } + +} //UMLExtPackage diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtClassImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtClassImpl.java new file mode 100644 index 000000000..c0e003a58 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtClassImpl.java @@ -0,0 +1,276 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl; + +import java.util.Collection; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EObjectContainmentEList; +import org.eclipse.emf.ecore.util.InternalEList; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtClass; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.uml2.common.util.CacheAdapter; +import org.eclipse.uml2.common.util.DerivedUnionEObjectEList; +import org.eclipse.uml2.uml.Operation; +import org.eclipse.uml2.uml.Parameter; +import org.eclipse.uml2.uml.RedefinableElement; +import org.eclipse.uml2.uml.Type; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * <!-- begin-user-doc --> + * An implementation of the model object '<em><b>Class</b></em>'. + * <!-- end-user-doc --> + * <p> + * The following features are implemented: + * </p> + * <ul> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtClassImpl#getImplicitMembers <em>Implicit Member</em>}</li> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtClassImpl#getImplicitOperations <em>Implicit Operation</em>}</li> + * </ul> + * + * @generated + */ +public class ExtClassImpl extends ExtEncapsulatedClassifierImpl implements ExtClass { + /** + * The cached value of the '{@link #getImplicitOperations() <em>Implicit Operation</em>}' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getImplicitOperations() + * @generated + * @ordered + */ + protected EList<Operation> implicitOperations; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected ExtClassImpl() { + super(); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected EClass eStaticClass() { + return ExtUMLExtPackage.Literals.CLASS; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EList<RedefinableElement> getImplicitMembers() { + CacheAdapter cache = getCacheAdapter(); + if (cache != null) { + Resource eResource = eResource(); + @SuppressWarnings("unchecked") + EList<RedefinableElement> implicitMembers = (EList<RedefinableElement>) cache.get(eResource, this, ExtUMLExtPackage.Literals.NAMESPACE__IMPLICIT_MEMBER); + if (implicitMembers == null) { + cache.put(eResource, this, ExtUMLExtPackage.Literals.NAMESPACE__IMPLICIT_MEMBER, + implicitMembers = new DerivedUnionEObjectEList<>(RedefinableElement.class, this, ExtUMLExtPackage.CLASS__IMPLICIT_MEMBER, IMPLICIT_MEMBER_ESUBSETS)); + } + return implicitMembers; + } + return new DerivedUnionEObjectEList<>(RedefinableElement.class, this, ExtUMLExtPackage.CLASS__IMPLICIT_MEMBER, IMPLICIT_MEMBER_ESUBSETS); + } + + /** + * The array of subset feature identifiers for the '{@link #getImplicitMembers() <em>Implicit Member</em>}' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getImplicitMembers() + * @generated + * @ordered + */ + protected static final int[] IMPLICIT_MEMBER_ESUBSETS = new int[] { ExtUMLExtPackage.CLASS__IMPLICIT_ATTRIBUTE, ExtUMLExtPackage.CLASS__IMPLICIT_CONNECTOR, ExtUMLExtPackage.CLASS__IMPLICIT_OPERATION }; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EList<Operation> getImplicitOperations() { + if (implicitOperations == null) { + implicitOperations = new EObjectContainmentEList<>(Operation.class, this, ExtUMLExtPackage.CLASS__IMPLICIT_OPERATION); + } + return implicitOperations; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Operation createImplicitOperation(String name, EList<String> ownedParameterNames, EList<Type> ownedParameterTypes) { + Operation newImplicitOperation = (Operation) create(UMLPackage.Literals.OPERATION); + getImplicitOperations().add(newImplicitOperation); + if (name != null) { + newImplicitOperation.setName(name); + } + int ownedParameterListSize = 0; + int ownedParameterNamesSize = ownedParameterNames == null ? 0 : ownedParameterNames.size(); + if (ownedParameterNamesSize > ownedParameterListSize) { + ownedParameterListSize = ownedParameterNamesSize; + } + int ownedParameterTypesSize = ownedParameterTypes == null ? 0 : ownedParameterTypes.size(); + if (ownedParameterTypesSize > ownedParameterListSize) { + ownedParameterListSize = ownedParameterTypesSize; + } + for (int i = 0; i < ownedParameterListSize; i++) { + newImplicitOperation.createOwnedParameter(i < ownedParameterNamesSize ? (String) ownedParameterNames.get(i) : null, i < ownedParameterTypesSize ? (Type) ownedParameterTypes.get(i) : null); + } + return newImplicitOperation; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Operation getImplicitOperation(String name, EList<String> ownedParameterNames, EList<Type> ownedParameterTypes) { + return getImplicitOperation(name, ownedParameterNames, ownedParameterTypes, false, false); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Operation getImplicitOperation(String name, EList<String> ownedParameterNames, EList<Type> ownedParameterTypes, boolean ignoreCase, boolean createOnDemand) { + implicitOperationLoop: for (Operation implicitOperation : getImplicitOperations()) { + if (name != null && !(ignoreCase ? name.equalsIgnoreCase(implicitOperation.getName()) : name.equals(implicitOperation.getName()))) { + continue implicitOperationLoop; + } + EList<Parameter> ownedParameterList = implicitOperation.getOwnedParameters(); + int ownedParameterListSize = ownedParameterList.size(); + if (ownedParameterNames != null && ownedParameterNames.size() != ownedParameterListSize || (ownedParameterTypes != null && ownedParameterTypes.size() != ownedParameterListSize)) { + continue implicitOperationLoop; + } + for (int j = 0; j < ownedParameterListSize; j++) { + Parameter ownedParameter = ownedParameterList.get(j); + if (ownedParameterNames != null && !(ignoreCase ? (ownedParameterNames.get(j)).equalsIgnoreCase(ownedParameter.getName()) : ownedParameterNames.get(j).equals(ownedParameter.getName()))) { + continue implicitOperationLoop; + } + if (ownedParameterTypes != null && !ownedParameterTypes.get(j).equals(ownedParameter.getType())) { + continue implicitOperationLoop; + } + } + return implicitOperation; + } + return createOnDemand ? createImplicitOperation(name, ownedParameterNames, ownedParameterTypes) : null; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { + switch (featureID) { + case ExtUMLExtPackage.CLASS__IMPLICIT_OPERATION: + return ((InternalEList<?>) getImplicitOperations()).basicRemove(otherEnd, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case ExtUMLExtPackage.CLASS__IMPLICIT_OPERATION: + return getImplicitOperations(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @SuppressWarnings("unchecked") + @Override + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case ExtUMLExtPackage.CLASS__IMPLICIT_OPERATION: + getImplicitOperations().clear(); + getImplicitOperations().addAll((Collection<? extends Operation>) newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public void eUnset(int featureID) { + switch (featureID) { + case ExtUMLExtPackage.CLASS__IMPLICIT_OPERATION: + getImplicitOperations().clear(); + return; + } + super.eUnset(featureID); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case ExtUMLExtPackage.CLASS__IMPLICIT_MEMBER: + return isSetImplicitMembers(); + case ExtUMLExtPackage.CLASS__IMPLICIT_OPERATION: + return implicitOperations != null && !implicitOperations.isEmpty(); + } + return super.eIsSet(featureID); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public boolean isSetImplicitMembers() { + return super.isSetImplicitMembers() + || eIsSet(ExtUMLExtPackage.CLASS__IMPLICIT_OPERATION); + } + +} //ClassImpl diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtElementImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtElementImpl.java new file mode 100644 index 000000000..cc409d977 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtElementImpl.java @@ -0,0 +1,222 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.MinimalEObjectImpl; + +import org.eclipse.emf.ecore.util.EcoreUtil; + +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; + +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.operations.ElementOperations; +import org.eclipse.uml2.common.util.CacheAdapter; +import org.eclipse.uml2.uml.Element; + +/** + * <!-- begin-user-doc --> + * An implementation of the model object '<em><b>Extension Element</b></em>'. + * <!-- end-user-doc --> + * <p> + * The following features are implemented: + * </p> + * <ul> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtElementImpl#getExtendedElement <em>Extended Element</em>}</li> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtElementImpl#getExtension <em>Extension</em>}</li> + * </ul> + * + * @generated + */ +public abstract class ExtElementImpl extends MinimalEObjectImpl.Container implements ExtElement { + /** + * The default value of the '{@link #getExtendedElement() <em>Extended Element</em>}' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getExtendedElement() + * @generated + * @ordered + */ + protected static final Element EXTENDED_ELEMENT_EDEFAULT = null; + + /** + * The cached value of the '{@link #getExtendedElement() <em>Extended Element</em>}' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getExtendedElement() + * @generated + * @ordered + */ + protected Element extendedElement = EXTENDED_ELEMENT_EDEFAULT; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected ExtElementImpl() { + super(); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected EClass eStaticClass() { + return ExtUMLExtPackage.Literals.ELEMENT; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Element getExtendedElement() { + return extendedElement; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public void setExtendedElement(Element newExtendedElement) { + Element oldExtendedElement = extendedElement; + extendedElement = newExtendedElement; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.SET, ExtUMLExtPackage.ELEMENT__EXTENDED_ELEMENT, oldExtendedElement, extendedElement)); + } + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public ExtElement getExtension() { + return ElementOperations.getExtension(this); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case ExtUMLExtPackage.ELEMENT__EXTENDED_ELEMENT: + return getExtendedElement(); + case ExtUMLExtPackage.ELEMENT__EXTENSION: + return getExtension(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case ExtUMLExtPackage.ELEMENT__EXTENDED_ELEMENT: + setExtendedElement((Element) newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public void eUnset(int featureID) { + switch (featureID) { + case ExtUMLExtPackage.ELEMENT__EXTENDED_ELEMENT: + setExtendedElement(EXTENDED_ELEMENT_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case ExtUMLExtPackage.ELEMENT__EXTENDED_ELEMENT: + return EXTENDED_ELEMENT_EDEFAULT == null ? extendedElement != null : !EXTENDED_ELEMENT_EDEFAULT.equals(extendedElement); + case ExtUMLExtPackage.ELEMENT__EXTENSION: + return getExtension() != null; + } + return super.eIsSet(featureID); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public String toString() { + if (eIsProxy()) { + return super.toString(); + } + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (extendedElement: "); //$NON-NLS-1$ + result.append(extendedElement); + result.append(')'); + return result.toString(); + } + + /** + * Creates a new instance of the specified Ecore class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param eClass The Ecore class of the instance to create. + * @return The new instance. + * @generated + */ + protected EObject create(EClass eClass) { + return EcoreUtil.create(eClass); + } + + /** + * Retrieves the cache adapter for this '<em><b>Element</b></em>'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return The cache adapter for this '<em><b>Element</b></em>'. + * @generated + */ + protected CacheAdapter getCacheAdapter() { + return CacheAdapter.getCacheAdapter(this); + } + +} //ExtensionElementImpl diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtEncapsulatedClassifierImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtEncapsulatedClassifierImpl.java new file mode 100644 index 000000000..5afc2569e --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtEncapsulatedClassifierImpl.java @@ -0,0 +1,242 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl; + +import java.util.Collection; + +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EObjectContainmentEList; +import org.eclipse.emf.ecore.util.InternalEList; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtEncapsulatedClassifier; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.uml2.common.util.CacheAdapter; +import org.eclipse.uml2.common.util.DerivedSubsetEObjectEList; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.Type; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * <!-- begin-user-doc --> + * An implementation of the model object '<em><b>Encapsulated Classifier</b></em>'. + * <!-- end-user-doc --> + * <p> + * The following features are implemented: + * </p> + * <ul> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtEncapsulatedClassifierImpl#getImplicitAttributes <em>Implicit Attribute</em>}</li> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtEncapsulatedClassifierImpl#getImplicitPorts <em>Implicit Port</em>}</li> + * </ul> + * + * @generated + */ +public abstract class ExtEncapsulatedClassifierImpl extends ExtStructuredClassifierImpl implements ExtEncapsulatedClassifier { + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected ExtEncapsulatedClassifierImpl() { + super(); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected EClass eStaticClass() { + return ExtUMLExtPackage.Literals.ENCAPSULATED_CLASSIFIER; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EList<Property> getImplicitAttributes() { + if (implicitAttributes == null) { + implicitAttributes = new EObjectContainmentEList<>(Property.class, this, ExtUMLExtPackage.ENCAPSULATED_CLASSIFIER__IMPLICIT_ATTRIBUTE); + } + return implicitAttributes; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * + * @generated NOT + */ + @Override + public EList<Port> getImplicitPorts() { + CacheAdapter cache = getCacheAdapter(); + if (cache != null) { + Resource eResource = eResource(); + @SuppressWarnings("unchecked") + EList<Port> implicitPorts = (EList<Port>) cache.get(eResource, this, ExtUMLExtPackage.Literals.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT); + if (implicitPorts == null) { + cache.put(eResource, this, + ExtUMLExtPackage.Literals.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT, + implicitPorts = new DerivedSubsetEObjectEList<>(Port.class, + this, + ExtUMLExtPackage.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT, + IMPLICIT_PORT_ESUPERSETS)); + } + return implicitPorts; + } + return new DerivedSubsetEObjectEList<>(Port.class, + this, + ExtUMLExtPackage.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT, + IMPLICIT_PORT_ESUPERSETS); + } + + /** + * The array of superset feature identifiers for the '{@link #getImplicitPorts() <em>Implicit Port</em>}' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getImplicitPorts() + * @generated + * @ordered + */ + protected static final int[] IMPLICIT_PORT_ESUPERSETS = new int[] { ExtUMLExtPackage.ENCAPSULATED_CLASSIFIER__IMPLICIT_ATTRIBUTE }; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Port createImplicitPort(String name, Type type) { + Port newImplicitPort = (Port) create(UMLPackage.Literals.PORT); + getImplicitPorts().add(newImplicitPort); + if (name != null) { + newImplicitPort.setName(name); + } + if (type != null) { + newImplicitPort.setType(type); + } + return newImplicitPort; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Port getImplicitPort(String name, Type type) { + return getImplicitPort(name, type, false, false); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Port getImplicitPort(String name, Type type, boolean ignoreCase, boolean createOnDemand) { + implicitPortLoop: for (Port implicitPort : getImplicitPorts()) { + if (name != null && !(ignoreCase ? name.equalsIgnoreCase(implicitPort.getName()) : name.equals(implicitPort.getName()))) { + continue implicitPortLoop; + } + if (type != null && !type.equals(implicitPort.getType())) { + continue implicitPortLoop; + } + return implicitPort; + } + return createOnDemand ? createImplicitPort(name, type) : null; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { + switch (featureID) { + case ExtUMLExtPackage.ENCAPSULATED_CLASSIFIER__IMPLICIT_ATTRIBUTE: + return ((InternalEList<?>) getImplicitAttributes()).basicRemove(otherEnd, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case ExtUMLExtPackage.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT: + return getImplicitPorts(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @SuppressWarnings("unchecked") + @Override + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case ExtUMLExtPackage.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT: + getImplicitPorts().clear(); + getImplicitPorts().addAll((Collection<? extends Port>) newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public void eUnset(int featureID) { + switch (featureID) { + case ExtUMLExtPackage.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT: + getImplicitPorts().clear(); + return; + } + super.eUnset(featureID); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case ExtUMLExtPackage.ENCAPSULATED_CLASSIFIER__IMPLICIT_ATTRIBUTE: + return implicitAttributes != null && !implicitAttributes.isEmpty(); + case ExtUMLExtPackage.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT: + return !getImplicitPorts().isEmpty(); + } + return super.eIsSet(featureID); + } + +} // EncapsulatedClassifierImpl diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtInterfaceImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtInterfaceImpl.java new file mode 100644 index 000000000..32102f2f6 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtInterfaceImpl.java @@ -0,0 +1,283 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl; + +import java.util.Collection; + +import org.eclipse.emf.common.notify.NotificationChain; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.resource.Resource; + +import org.eclipse.emf.ecore.util.EObjectContainmentEList; +import org.eclipse.emf.ecore.util.InternalEList; + +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtInterface; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; + +import org.eclipse.uml2.common.util.CacheAdapter; +import org.eclipse.uml2.common.util.DerivedUnionEObjectEList; + +import org.eclipse.uml2.uml.Operation; +import org.eclipse.uml2.uml.Parameter; +import org.eclipse.uml2.uml.RedefinableElement; +import org.eclipse.uml2.uml.Type; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * <!-- begin-user-doc --> + * An implementation of the model object '<em><b>Interface</b></em>'. + * <!-- end-user-doc --> + * <p> + * The following features are implemented: + * </p> + * <ul> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtInterfaceImpl#getImplicitMembers <em>Implicit Member</em>}</li> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtInterfaceImpl#getImplicitOperations <em>Implicit Operation</em>}</li> + * </ul> + * + * @generated + */ +public class ExtInterfaceImpl extends ExtNamespaceImpl implements ExtInterface { + /** + * The cached value of the '{@link #getImplicitOperations() <em>Implicit Operation</em>}' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getImplicitOperations() + * @generated + * @ordered + */ + protected EList<Operation> implicitOperations; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected ExtInterfaceImpl() { + super(); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected EClass eStaticClass() { + return ExtUMLExtPackage.Literals.INTERFACE; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EList<RedefinableElement> getImplicitMembers() { + CacheAdapter cache = getCacheAdapter(); + if (cache != null) { + Resource eResource = eResource(); + @SuppressWarnings("unchecked") + EList<RedefinableElement> implicitMembers = (EList<RedefinableElement>) cache.get(eResource, this, ExtUMLExtPackage.Literals.NAMESPACE__IMPLICIT_MEMBER); + if (implicitMembers == null) { + cache.put(eResource, this, ExtUMLExtPackage.Literals.NAMESPACE__IMPLICIT_MEMBER, + implicitMembers = new DerivedUnionEObjectEList<>(RedefinableElement.class, this, ExtUMLExtPackage.INTERFACE__IMPLICIT_MEMBER, IMPLICIT_MEMBER_ESUBSETS)); + } + return implicitMembers; + } + return new DerivedUnionEObjectEList<>(RedefinableElement.class, this, ExtUMLExtPackage.INTERFACE__IMPLICIT_MEMBER, IMPLICIT_MEMBER_ESUBSETS); + } + + /** + * The array of subset feature identifiers for the '{@link #getImplicitMembers() <em>Implicit Member</em>}' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getImplicitMembers() + * @generated + * @ordered + */ + protected static final int[] IMPLICIT_MEMBER_ESUBSETS = new int[] { ExtUMLExtPackage.INTERFACE__IMPLICIT_OPERATION }; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EList<Operation> getImplicitOperations() { + if (implicitOperations == null) { + implicitOperations = new EObjectContainmentEList<>(Operation.class, this, ExtUMLExtPackage.INTERFACE__IMPLICIT_OPERATION); + } + return implicitOperations; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Operation createImplicitOperation(String name, EList<String> ownedParameterNames, EList<Type> ownedParameterTypes) { + Operation newImplicitOperation = (Operation) create(UMLPackage.Literals.OPERATION); + getImplicitOperations().add(newImplicitOperation); + if (name != null) { + newImplicitOperation.setName(name); + } + int ownedParameterListSize = 0; + int ownedParameterNamesSize = ownedParameterNames == null ? 0 : ownedParameterNames.size(); + if (ownedParameterNamesSize > ownedParameterListSize) { + ownedParameterListSize = ownedParameterNamesSize; + } + int ownedParameterTypesSize = ownedParameterTypes == null ? 0 : ownedParameterTypes.size(); + if (ownedParameterTypesSize > ownedParameterListSize) { + ownedParameterListSize = ownedParameterTypesSize; + } + for (int i = 0; i < ownedParameterListSize; i++) { + newImplicitOperation.createOwnedParameter(i < ownedParameterNamesSize ? (String) ownedParameterNames.get(i) : null, i < ownedParameterTypesSize ? (Type) ownedParameterTypes.get(i) : null); + } + return newImplicitOperation; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Operation getImplicitOperation(String name, EList<String> ownedParameterNames, EList<Type> ownedParameterTypes) { + return getImplicitOperation(name, ownedParameterNames, ownedParameterTypes, false, false); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Operation getImplicitOperation(String name, EList<String> ownedParameterNames, EList<Type> ownedParameterTypes, boolean ignoreCase, boolean createOnDemand) { + implicitOperationLoop: for (Operation implicitOperation : getImplicitOperations()) { + if (name != null && !(ignoreCase ? name.equalsIgnoreCase(implicitOperation.getName()) : name.equals(implicitOperation.getName()))) { + continue implicitOperationLoop; + } + EList<Parameter> ownedParameterList = implicitOperation.getOwnedParameters(); + int ownedParameterListSize = ownedParameterList.size(); + if (ownedParameterNames != null && ownedParameterNames.size() != ownedParameterListSize || (ownedParameterTypes != null && ownedParameterTypes.size() != ownedParameterListSize)) { + continue implicitOperationLoop; + } + for (int j = 0; j < ownedParameterListSize; j++) { + Parameter ownedParameter = ownedParameterList.get(j); + if (ownedParameterNames != null && !(ignoreCase ? (ownedParameterNames.get(j)).equalsIgnoreCase(ownedParameter.getName()) : ownedParameterNames.get(j).equals(ownedParameter.getName()))) { + continue implicitOperationLoop; + } + if (ownedParameterTypes != null && !ownedParameterTypes.get(j).equals(ownedParameter.getType())) { + continue implicitOperationLoop; + } + } + return implicitOperation; + } + return createOnDemand ? createImplicitOperation(name, ownedParameterNames, ownedParameterTypes) : null; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { + switch (featureID) { + case ExtUMLExtPackage.INTERFACE__IMPLICIT_OPERATION: + return ((InternalEList<?>) getImplicitOperations()).basicRemove(otherEnd, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case ExtUMLExtPackage.INTERFACE__IMPLICIT_OPERATION: + return getImplicitOperations(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @SuppressWarnings("unchecked") + @Override + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case ExtUMLExtPackage.INTERFACE__IMPLICIT_OPERATION: + getImplicitOperations().clear(); + getImplicitOperations().addAll((Collection<? extends Operation>) newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public void eUnset(int featureID) { + switch (featureID) { + case ExtUMLExtPackage.INTERFACE__IMPLICIT_OPERATION: + getImplicitOperations().clear(); + return; + } + super.eUnset(featureID); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case ExtUMLExtPackage.INTERFACE__IMPLICIT_MEMBER: + return isSetImplicitMembers(); + case ExtUMLExtPackage.INTERFACE__IMPLICIT_OPERATION: + return implicitOperations != null && !implicitOperations.isEmpty(); + } + return super.eIsSet(featureID); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public boolean isSetImplicitMembers() { + return super.isSetImplicitMembers() + || eIsSet(ExtUMLExtPackage.INTERFACE__IMPLICIT_OPERATION); + } + +} //ExtInterfaceImpl diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtNamespaceImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtNamespaceImpl.java new file mode 100644 index 000000000..c367426d9 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtNamespaceImpl.java @@ -0,0 +1,201 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; + +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.operations.NamespaceOperations; +import org.eclipse.uml2.common.util.CacheAdapter; + +import org.eclipse.uml2.common.util.DerivedUnionEObjectEList; +import org.eclipse.uml2.uml.NamedElement; +import org.eclipse.uml2.uml.RedefinableElement; + +/** + * <!-- begin-user-doc --> + * An implementation of the model object '<em><b>Namespace</b></em>'. + * <!-- end-user-doc --> + * <p> + * The following features are implemented: + * </p> + * <ul> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtNamespaceImpl#getImplicitMembers <em>Implicit Member</em>}</li> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtNamespaceImpl#getExcludedMembers <em>Excluded Member</em>}</li> + * </ul> + * + * @generated + */ +public abstract class ExtNamespaceImpl extends ExtElementImpl implements ExtNamespace { + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected ExtNamespaceImpl() { + super(); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected EClass eStaticClass() { + return ExtUMLExtPackage.Literals.NAMESPACE; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EList<RedefinableElement> getImplicitMembers() { + CacheAdapter cache = getCacheAdapter(); + if (cache != null) { + Resource eResource = eResource(); + @SuppressWarnings("unchecked") + EList<RedefinableElement> implicitMembers = (EList<RedefinableElement>) cache.get(eResource, this, ExtUMLExtPackage.Literals.NAMESPACE__IMPLICIT_MEMBER); + if (implicitMembers == null) { + cache.put(eResource, this, ExtUMLExtPackage.Literals.NAMESPACE__IMPLICIT_MEMBER, implicitMembers = new DerivedUnionEObjectEList<>(RedefinableElement.class, this, ExtUMLExtPackage.NAMESPACE__IMPLICIT_MEMBER, null)); + } + return implicitMembers; + } + return new DerivedUnionEObjectEList<>(RedefinableElement.class, this, ExtUMLExtPackage.NAMESPACE__IMPLICIT_MEMBER, null); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public RedefinableElement getImplicitMember(String name) { + return getImplicitMember(name, false, null); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public RedefinableElement getImplicitMember(String name, boolean ignoreCase, EClass eClass) { + implicitMemberLoop: for (RedefinableElement implicitMember : getImplicitMembers()) { + if (eClass != null && !eClass.isInstance(implicitMember)) { + continue implicitMemberLoop; + } + if (name != null && !(ignoreCase ? name.equalsIgnoreCase(implicitMember.getName()) : name.equals(implicitMember.getName()))) { + continue implicitMemberLoop; + } + return implicitMember; + } + return null; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EList<NamedElement> getExcludedMembers() { + CacheAdapter cache = getCacheAdapter(); + if (cache != null) { + @SuppressWarnings("unchecked") + EList<NamedElement> result = (EList<NamedElement>) cache.get(this, ExtUMLExtPackage.Literals.NAMESPACE__EXCLUDED_MEMBER); + if (result == null) { + cache.put(this, ExtUMLExtPackage.Literals.NAMESPACE__EXCLUDED_MEMBER, result = NamespaceOperations.getExcludedMembers(this)); + } + return result; + } + return NamespaceOperations.getExcludedMembers(this); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public NamedElement getExcludedMember(String name) { + return getExcludedMember(name, false, null); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public NamedElement getExcludedMember(String name, boolean ignoreCase, EClass eClass) { + excludedMemberLoop: for (NamedElement excludedMember : getExcludedMembers()) { + if (eClass != null && !eClass.isInstance(excludedMember)) { + continue excludedMemberLoop; + } + if (name != null && !(ignoreCase ? name.equalsIgnoreCase(excludedMember.getName()) : name.equals(excludedMember.getName()))) { + continue excludedMemberLoop; + } + return excludedMember; + } + return null; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case ExtUMLExtPackage.NAMESPACE__IMPLICIT_MEMBER: + return getImplicitMembers(); + case ExtUMLExtPackage.NAMESPACE__EXCLUDED_MEMBER: + return getExcludedMembers(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case ExtUMLExtPackage.NAMESPACE__IMPLICIT_MEMBER: + return isSetImplicitMembers(); + case ExtUMLExtPackage.NAMESPACE__EXCLUDED_MEMBER: + return !getExcludedMembers().isEmpty(); + } + return super.eIsSet(featureID); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public boolean isSetImplicitMembers() { + return false; + } + +} //NamespaceImpl diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtStructuredClassifierImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtStructuredClassifierImpl.java new file mode 100644 index 000000000..686b545d9 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtStructuredClassifierImpl.java @@ -0,0 +1,355 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl; + +import java.util.Collection; + +import org.eclipse.emf.common.notify.NotificationChain; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.resource.Resource; + +import org.eclipse.emf.ecore.util.EObjectContainmentEList; +import org.eclipse.emf.ecore.util.InternalEList; + +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtStructuredClassifier; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; + +import org.eclipse.uml2.common.util.CacheAdapter; +import org.eclipse.uml2.common.util.DerivedUnionEObjectEList; + +import org.eclipse.uml2.uml.Connector; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.RedefinableElement; +import org.eclipse.uml2.uml.Type; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * <!-- begin-user-doc --> + * An implementation of the model object '<em><b>Structured Classifier</b></em>'. + * <!-- end-user-doc --> + * <p> + * The following features are implemented: + * </p> + * <ul> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtStructuredClassifierImpl#getImplicitMembers <em>Implicit Member</em>}</li> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtStructuredClassifierImpl#getImplicitAttributes <em>Implicit Attribute</em>}</li> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl.ExtStructuredClassifierImpl#getImplicitConnectors <em>Implicit Connector</em>}</li> + * </ul> + * + * @generated + */ +public abstract class ExtStructuredClassifierImpl extends ExtNamespaceImpl implements ExtStructuredClassifier { + /** + * The cached value of the '{@link #getImplicitAttributes() <em>Implicit Attribute</em>}' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getImplicitAttributes() + * @generated + * @ordered + */ + protected EList<Property> implicitAttributes; + + /** + * The cached value of the '{@link #getImplicitConnectors() <em>Implicit Connector</em>}' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getImplicitConnectors() + * @generated + * @ordered + */ + protected EList<Connector> implicitConnectors; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected ExtStructuredClassifierImpl() { + super(); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected EClass eStaticClass() { + return ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EList<RedefinableElement> getImplicitMembers() { + CacheAdapter cache = getCacheAdapter(); + if (cache != null) { + Resource eResource = eResource(); + @SuppressWarnings("unchecked") + EList<RedefinableElement> implicitMembers = (EList<RedefinableElement>) cache.get(eResource, this, ExtUMLExtPackage.Literals.NAMESPACE__IMPLICIT_MEMBER); + if (implicitMembers == null) { + cache.put(eResource, this, ExtUMLExtPackage.Literals.NAMESPACE__IMPLICIT_MEMBER, + implicitMembers = new DerivedUnionEObjectEList<>(RedefinableElement.class, this, ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_MEMBER, IMPLICIT_MEMBER_ESUBSETS)); + } + return implicitMembers; + } + return new DerivedUnionEObjectEList<>(RedefinableElement.class, this, ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_MEMBER, IMPLICIT_MEMBER_ESUBSETS); + } + + /** + * The array of subset feature identifiers for the '{@link #getImplicitMembers() <em>Implicit Member</em>}' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getImplicitMembers() + * @generated + * @ordered + */ + protected static final int[] IMPLICIT_MEMBER_ESUBSETS = new int[] { ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE, ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR }; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EList<Property> getImplicitAttributes() { + if (implicitAttributes == null) { + implicitAttributes = new EObjectContainmentEList<>(Property.class, this, ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE); + } + return implicitAttributes; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Property createImplicitAttribute(String name, Type type, EClass eClass) { + Property newImplicitAttribute = (Property) create(eClass); + getImplicitAttributes().add(newImplicitAttribute); + if (name != null) { + newImplicitAttribute.setName(name); + } + if (type != null) { + newImplicitAttribute.setType(type); + } + return newImplicitAttribute; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Property createImplicitAttribute(String name, Type type) { + return createImplicitAttribute(name, type, UMLPackage.Literals.PROPERTY); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Property getImplicitAttribute(String name, Type type) { + return getImplicitAttribute(name, type, false, null, false); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Property getImplicitAttribute(String name, Type type, boolean ignoreCase, EClass eClass, boolean createOnDemand) { + implicitAttributeLoop: for (Property implicitAttribute : getImplicitAttributes()) { + if (eClass != null && !eClass.isInstance(implicitAttribute)) { + continue implicitAttributeLoop; + } + if (name != null && !(ignoreCase ? name.equalsIgnoreCase(implicitAttribute.getName()) : name.equals(implicitAttribute.getName()))) { + continue implicitAttributeLoop; + } + if (type != null && !type.equals(implicitAttribute.getType())) { + continue implicitAttributeLoop; + } + return implicitAttribute; + } + return createOnDemand && eClass != null ? createImplicitAttribute(name, type, eClass) : null; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EList<Connector> getImplicitConnectors() { + if (implicitConnectors == null) { + implicitConnectors = new EObjectContainmentEList<>(Connector.class, this, ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR); + } + return implicitConnectors; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Connector createImplicitConnector(String name) { + Connector newImplicitConnector = (Connector) create(UMLPackage.Literals.CONNECTOR); + getImplicitConnectors().add(newImplicitConnector); + if (name != null) { + newImplicitConnector.setName(name); + } + return newImplicitConnector; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Connector getImplicitConnector(String name) { + return getImplicitConnector(name, false, false); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Connector getImplicitConnector(String name, boolean ignoreCase, boolean createOnDemand) { + implicitConnectorLoop: for (Connector implicitConnector : getImplicitConnectors()) { + if (name != null && !(ignoreCase ? name.equalsIgnoreCase(implicitConnector.getName()) : name.equals(implicitConnector.getName()))) { + continue implicitConnectorLoop; + } + return implicitConnector; + } + return createOnDemand ? createImplicitConnector(name) : null; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { + switch (featureID) { + case ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE: + return ((InternalEList<?>) getImplicitAttributes()).basicRemove(otherEnd, msgs); + case ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR: + return ((InternalEList<?>) getImplicitConnectors()).basicRemove(otherEnd, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE: + return getImplicitAttributes(); + case ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR: + return getImplicitConnectors(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @SuppressWarnings("unchecked") + @Override + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE: + getImplicitAttributes().clear(); + getImplicitAttributes().addAll((Collection<? extends Property>) newValue); + return; + case ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR: + getImplicitConnectors().clear(); + getImplicitConnectors().addAll((Collection<? extends Connector>) newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public void eUnset(int featureID) { + switch (featureID) { + case ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE: + getImplicitAttributes().clear(); + return; + case ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR: + getImplicitConnectors().clear(); + return; + } + super.eUnset(featureID); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_MEMBER: + return isSetImplicitMembers(); + case ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE: + return implicitAttributes != null && !implicitAttributes.isEmpty(); + case ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR: + return implicitConnectors != null && !implicitConnectors.isEmpty(); + } + return super.eIsSet(featureID); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public boolean isSetImplicitMembers() { + return super.isSetImplicitMembers() + || eIsSet(ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE) + || eIsSet(ExtUMLExtPackage.STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR); + } + +} //StructuredClassifierImpl diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtUMLExtFactoryImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtUMLExtFactoryImpl.java new file mode 100644 index 000000000..ee740f7c3 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtUMLExtFactoryImpl.java @@ -0,0 +1,173 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtClass; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtInterface; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtFactory; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.uml2.uml.Element; + +/** + * <!-- begin-user-doc --> + * An implementation of the model <b>Factory</b>. + * <!-- end-user-doc --> + * @generated + */ +public class ExtUMLExtFactoryImpl extends EFactoryImpl implements ExtUMLExtFactory { + /** + * Creates the default factory implementation. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public static ExtUMLExtFactory init() { + try { + ExtUMLExtFactory theUMLExtFactory = (ExtUMLExtFactory) EPackage.Registry.INSTANCE.getEFactory(ExtUMLExtPackage.eNS_URI); + if (theUMLExtFactory != null) { + return theUMLExtFactory; + } + } catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new ExtUMLExtFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public ExtUMLExtFactoryImpl() { + super(); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case ExtUMLExtPackage.CLASS: + return createClass(); + case ExtUMLExtPackage.INTERFACE: + return createInterface(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Object createFromString(EDataType eDataType, String initialValue) { + switch (eDataType.getClassifierID()) { + case ExtUMLExtPackage.UML_ELEMENT: + return createUMLElementFromString(eDataType, initialValue); + default: + throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier"); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public String convertToString(EDataType eDataType, Object instanceValue) { + switch (eDataType.getClassifierID()) { + case ExtUMLExtPackage.UML_ELEMENT: + return convertUMLElementToString(eDataType, instanceValue); + default: + throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier"); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public ExtClass createClass() { + ExtClassImpl class_ = new ExtClassImpl(); + return class_; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public ExtInterface createInterface() { + ExtInterfaceImpl interface_ = new ExtInterfaceImpl(); + return interface_; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public Element createUMLElementFromString(EDataType eDataType, String initialValue) { + return (Element) super.createFromString(eDataType, initialValue); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public String convertUMLElementToString(EDataType eDataType, Object instanceValue) { + return super.convertToString(eDataType, instanceValue); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public ExtUMLExtPackage getUMLExtPackage() { + return (ExtUMLExtPackage) getEPackage(); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @deprecated + * @generated + */ + @Deprecated + public static ExtUMLExtPackage getPackage() { + return ExtUMLExtPackage.eINSTANCE; + } + +} //UMLExtFactoryImpl diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtUMLExtPackageImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtUMLExtPackageImpl.java new file mode 100644 index 000000000..ee050bef4 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/impl/ExtUMLExtPackageImpl.java @@ -0,0 +1,539 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext.impl; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EOperation; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtClass; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtEncapsulatedClassifier; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtInterface; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtStructuredClassifier; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtFactory; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * <!-- begin-user-doc --> + * An implementation of the model <b>Package</b>. + * <!-- end-user-doc --> + * @generated + */ +public class ExtUMLExtPackageImpl extends EPackageImpl implements ExtUMLExtPackage { + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private EClass elementEClass = null; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private EClass namespaceEClass = null; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private EClass structuredClassifierEClass = null; + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private EClass encapsulatedClassifierEClass = null; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private EClass classEClass = null; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private EClass interfaceEClass = null; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private EDataType umlElementEDataType = null; + + /** + * Creates an instance of the model <b>Package</b>, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + * <p>Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage#eNS_URI + * @see #init() + * @generated + */ + private ExtUMLExtPackageImpl() { + super(eNS_URI, ExtUMLExtFactory.eINSTANCE); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the <b>Package</b> for this model, and for any others upon which it depends. + * + * <p>This method is used to initialize {@link ExtUMLExtPackage#eINSTANCE} when that field is accessed. + * Clients should not invoke it directly. Instead, they should simply access that field to obtain the package. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static ExtUMLExtPackage init() { + if (isInited) { + return (ExtUMLExtPackage) EPackage.Registry.INSTANCE.getEPackage(ExtUMLExtPackage.eNS_URI); + } + + // Obtain or create and register package + ExtUMLExtPackageImpl theUMLExtPackage = (ExtUMLExtPackageImpl) (EPackage.Registry.INSTANCE.get(eNS_URI) instanceof ExtUMLExtPackageImpl ? EPackage.Registry.INSTANCE.get(eNS_URI) : new ExtUMLExtPackageImpl()); + + isInited = true; + + // Initialize simple dependencies + UMLPackage.eINSTANCE.eClass(); + + // Create package meta-data objects + theUMLExtPackage.createPackageContents(); + + // Initialize created meta-data + theUMLExtPackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + theUMLExtPackage.freeze(); + + + // Update the registry and return the package + EPackage.Registry.INSTANCE.put(ExtUMLExtPackage.eNS_URI, theUMLExtPackage); + return theUMLExtPackage; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EClass getNamespace() { + return namespaceEClass; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EReference getNamespace_ImplicitMember() { + return (EReference) namespaceEClass.getEStructuralFeatures().get(0); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EReference getNamespace_ExcludedMember() { + return (EReference) namespaceEClass.getEStructuralFeatures().get(1); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EOperation getNamespace__GetExcludedMembers() { + return namespaceEClass.getEOperations().get(0); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EClass getStructuredClassifier() { + return structuredClassifierEClass; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EReference getStructuredClassifier_ImplicitAttribute() { + return (EReference) structuredClassifierEClass.getEStructuralFeatures().get(0); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EReference getStructuredClassifier_ImplicitConnector() { + return (EReference) structuredClassifierEClass.getEStructuralFeatures().get(1); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EClass getEncapsulatedClassifier() { + return encapsulatedClassifierEClass; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EReference getEncapsulatedClassifier_ImplicitPort() { + return (EReference) encapsulatedClassifierEClass.getEStructuralFeatures().get(0); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EClass getClass_() { + return classEClass; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EReference getClass_ImplicitOperation() { + return (EReference) classEClass.getEStructuralFeatures().get(0); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EClass getInterface() { + return interfaceEClass; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EReference getInterface_ImplicitOperation() { + return (EReference) interfaceEClass.getEStructuralFeatures().get(0); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EDataType getUMLElement() { + return umlElementEDataType; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EClass getElement() { + return elementEClass; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EAttribute getElement_ExtendedElement() { + return (EAttribute) elementEClass.getEStructuralFeatures().get(0); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EReference getElement_Extension() { + return (EReference) elementEClass.getEStructuralFeatures().get(1); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public EOperation getElement__GetExtension() { + return elementEClass.getEOperations().get(0); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public ExtUMLExtFactory getUMLExtFactory() { + return (ExtUMLExtFactory) getEFactoryInstance(); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public void createPackageContents() { + if (isCreated) { + return; + } + isCreated = true; + + // Create classes and their features + elementEClass = createEClass(ELEMENT); + createEAttribute(elementEClass, ELEMENT__EXTENDED_ELEMENT); + createEReference(elementEClass, ELEMENT__EXTENSION); + createEOperation(elementEClass, ELEMENT___GET_EXTENSION); + + namespaceEClass = createEClass(NAMESPACE); + createEReference(namespaceEClass, NAMESPACE__IMPLICIT_MEMBER); + createEReference(namespaceEClass, NAMESPACE__EXCLUDED_MEMBER); + createEOperation(namespaceEClass, NAMESPACE___GET_EXCLUDED_MEMBERS); + + structuredClassifierEClass = createEClass(STRUCTURED_CLASSIFIER); + createEReference(structuredClassifierEClass, STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE); + createEReference(structuredClassifierEClass, STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR); + + encapsulatedClassifierEClass = createEClass(ENCAPSULATED_CLASSIFIER); + createEReference(encapsulatedClassifierEClass, ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT); + + classEClass = createEClass(CLASS); + createEReference(classEClass, CLASS__IMPLICIT_OPERATION); + + interfaceEClass = createEClass(INTERFACE); + createEReference(interfaceEClass, INTERFACE__IMPLICIT_OPERATION); + + // Create data types + umlElementEDataType = createEDataType(UML_ELEMENT); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public void initializePackageContents() { + if (isInitialized) { + return; + } + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Obtain other dependent packages + UMLPackage theUMLPackage = (UMLPackage) EPackage.Registry.INSTANCE.getEPackage(UMLPackage.eNS_URI); + + // Create type parameters + + // Set bounds for type parameters + + // Add supertypes to classes + namespaceEClass.getESuperTypes().add(this.getElement()); + structuredClassifierEClass.getESuperTypes().add(this.getNamespace()); + encapsulatedClassifierEClass.getESuperTypes().add(this.getStructuredClassifier()); + classEClass.getESuperTypes().add(this.getEncapsulatedClassifier()); + interfaceEClass.getESuperTypes().add(this.getNamespace()); + + // Initialize classes, features, and operations; add parameters + initEClass(elementEClass, ExtElement.class, "Element", IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$ + initEAttribute(getElement_ExtendedElement(), this.getUMLElement(), "extendedElement", null, 1, 1, ExtElement.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, !IS_ORDERED); //$NON-NLS-1$ + initEReference(getElement_Extension(), this.getElement(), null, "extension", null, 1, 1, ExtElement.class, IS_TRANSIENT, IS_VOLATILE, !IS_CHANGEABLE, !IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, IS_DERIVED, !IS_ORDERED); //$NON-NLS-1$ + + initEOperation(getElement__GetExtension(), this.getElement(), "getExtension", 1, 1, IS_UNIQUE, !IS_ORDERED); //$NON-NLS-1$ + + initEClass(namespaceEClass, ExtNamespace.class, "Namespace", IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$ + initEReference(getNamespace_ImplicitMember(), theUMLPackage.getRedefinableElement(), null, "implicitMember", null, 0, -1, ExtNamespace.class, IS_TRANSIENT, IS_VOLATILE, !IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, //$NON-NLS-1$ + IS_DERIVED, !IS_ORDERED); + initEReference(getNamespace_ExcludedMember(), theUMLPackage.getNamedElement(), null, "excludedMember", null, 0, -1, ExtNamespace.class, IS_TRANSIENT, IS_VOLATILE, !IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, IS_DERIVED, //$NON-NLS-1$ + !IS_ORDERED); + + initEOperation(getNamespace__GetExcludedMembers(), theUMLPackage.getNamedElement(), "getExcludedMembers", 0, -1, IS_UNIQUE, !IS_ORDERED); //$NON-NLS-1$ + + initEClass(structuredClassifierEClass, ExtStructuredClassifier.class, "StructuredClassifier", IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$ + initEReference(getStructuredClassifier_ImplicitAttribute(), theUMLPackage.getProperty(), null, "implicitAttribute", null, 0, -1, ExtStructuredClassifier.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, //$NON-NLS-1$ + !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, !IS_ORDERED); + initEReference(getStructuredClassifier_ImplicitConnector(), theUMLPackage.getConnector(), null, "implicitConnector", null, 0, -1, ExtStructuredClassifier.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, //$NON-NLS-1$ + !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, !IS_ORDERED); + + initEClass(encapsulatedClassifierEClass, ExtEncapsulatedClassifier.class, "EncapsulatedClassifier", IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$ + initEReference(getEncapsulatedClassifier_ImplicitPort(), theUMLPackage.getPort(), null, "implicitPort", null, 0, -1, ExtEncapsulatedClassifier.class, IS_TRANSIENT, IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, //$NON-NLS-1$ + IS_UNIQUE, IS_DERIVED, !IS_ORDERED); + + initEClass(classEClass, ExtClass.class, "Class", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$ + initEReference(getClass_ImplicitOperation(), theUMLPackage.getOperation(), null, "implicitOperation", null, 0, -1, ExtClass.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, //$NON-NLS-1$ + !IS_ORDERED); + + initEClass(interfaceEClass, ExtInterface.class, "Interface", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$ + initEReference(getInterface_ImplicitOperation(), theUMLPackage.getOperation(), null, "implicitOperation", null, 0, -1, ExtInterface.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, //$NON-NLS-1$ + !IS_DERIVED, !IS_ORDERED); + + // Initialize data types + initEDataType(umlElementEDataType, Element.class, "UMLElement", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$ + + // Create resource + createResource(eNS_URI); + + // Create annotations + // union + createUnionAnnotations(); + // subsets + createSubsetsAnnotations(); + } + + /** + * Initializes the annotations for <b>union</b>. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected void createUnionAnnotations() { + String source = "union"; //$NON-NLS-1$ + addAnnotation(getNamespace_ImplicitMember(), + source, + new String[] { + }); + } + + /** + * Initializes the annotations for <b>subsets</b>. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected void createSubsetsAnnotations() { + String source = "subsets"; //$NON-NLS-1$ + addAnnotation(getStructuredClassifier_ImplicitAttribute(), + source, + new String[] { + }, + new URI[] { + URI.createURI(eNS_URI).appendFragment("//Namespace/implicitMember") //$NON-NLS-1$ + }); + addAnnotation(getStructuredClassifier_ImplicitConnector(), + source, + new String[] { + }, + new URI[] { + URI.createURI(eNS_URI).appendFragment("//Namespace/implicitMember") //$NON-NLS-1$ + }); + addAnnotation(getEncapsulatedClassifier_ImplicitPort(), + source, + new String[] { + }, + new URI[] { + URI.createURI(eNS_URI).appendFragment("//StructuredClassifier/implicitAttribute") //$NON-NLS-1$ + }); + addAnnotation(getClass_ImplicitOperation(), + source, + new String[] { + }, + new URI[] { + URI.createURI(eNS_URI).appendFragment("//Namespace/implicitMember") //$NON-NLS-1$ + }); + addAnnotation(getInterface_ImplicitOperation(), + source, + new String[] { + }, + new URI[] { + URI.createURI(eNS_URI).appendFragment("//Namespace/implicitMember") //$NON-NLS-1$ + }); + } + +} //UMLExtPackageImpl diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/operations/ElementOperations.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/operations/ElementOperations.java new file mode 100644 index 000000000..69379dc64 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/operations/ElementOperations.java @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext.operations; + +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement; + +/** + * <!-- begin-user-doc --> + * A static utility class that provides operations related to '<em><b>Element</b></em>' model objects. + * <!-- end-user-doc --> + * + * <p> + * The following operations are supported: + * </p> + * <ul> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement#getExtension() <em>Get Extension</em>}</li> + * </ul> + * + * @generated + */ +public class ElementOperations { + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected ElementOperations() { + super(); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * + * @generated NOT + */ + public static ExtElement getExtension(ExtElement element) { + return element; + } + +} // ElementOperations diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/operations/NamespaceOperations.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/operations/NamespaceOperations.java new file mode 100644 index 000000000..46da93e02 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/operations/NamespaceOperations.java @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext.operations; + +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace; +import org.eclipse.uml2.uml.NamedElement; +import org.eclipse.uml2.uml.Namespace; + +/** + * <!-- begin-user-doc --> + * A static utility class that provides operations related to '<em><b>Namespace</b></em>' model objects. + * <!-- end-user-doc --> + * + * <p> + * The following operations are supported: + * </p> + * <ul> + * <li>{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace#getExcludedMembers() <em>Get Excluded Members</em>}</li> + * </ul> + * + * @generated + */ +public class NamespaceOperations extends ElementOperations { + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected NamespaceOperations() { + super(); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * + * @generated NOT + */ + public static EList<NamedElement> getExcludedMembers(ExtNamespace namespace) { + Namespace uml = (Namespace) namespace.getExtendedElement(); + return getExcludedMembers(uml); + } + + /** + * Computes the excluded members of a {@code namespace}. + * + * @param namespace + * an UML namespace + * @return its members that would otherwise be inherited but are actually excluded + */ + public static EList<NamedElement> getExcludedMembers(Namespace namespace) { + NamedElement[] result = namespace.getOwnedMembers().stream() + .filter(m -> (m instanceof InternalUMLRTElement) && ((InternalUMLRTElement) m).rtIsExcluded()) + .toArray(NamedElement[]::new); + return new BasicEList.UnmodifiableEList<>(result.length, result); + } + +} // NamespaceOperations diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/util/ExtensionHolder.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/util/ExtensionHolder.java new file mode 100644 index 000000000..2eff39094 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/util/ExtensionHolder.java @@ -0,0 +1,745 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util; + +import static org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionResource.EXTENSION_EXTENT_URI; + +import java.lang.reflect.Array; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.notify.impl.AdapterImpl; +import org.eclipse.emf.common.util.DelegatingEList; +import org.eclipse.emf.common.util.ECollections; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.EClassImpl; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.util.EContentsEList; +import org.eclipse.emf.ecore.util.InternalEList; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtFactory; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.operations.NamespaceOperations; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.NotificationForwarder; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.Namespace; +import org.eclipse.uml2.uml.util.UMLUtil; + +/** + * A holder to be composed into any {@link Element} that needs to be + * able to contain transient redefinable elements in any of the UML Extension + * features intended for that purpose. Various {@link InternalEObject} APIs + * are delegated to the holder. + */ +public class ExtensionHolder extends UMLUtil { + + public static final int UML_EXTENSION_FEATURE_BASE = -2048; + + private final InternalEObject owner; + private InternalEObject extension; + + private boolean suppressForwarding; + + /** + * Initializes me with the object that I extend. + * + * @param my + * extended object + */ + public ExtensionHolder(InternalEObject owner) { + super(); + + this.owner = owner; + } + + /** + * Obtains the UML extension metaclass corresponding to the + * specified UML metaclass. + * + * @param umlMetaclass + * the core UML metaclass that is extended + * + * @return the corresponding extension metaclass + */ + protected static EClass getExtensionEClass(EClass umlMetaclass) { + return (EClass) ExtUMLExtPackage.eINSTANCE.getEClassifier(umlMetaclass.getName()); + } + + /** + * Obtains the UML extension metaclass for my owner. + * + * @return my UML extension metaclass + */ + protected final EClass getExtensionEClass() { + return getExtensionEClass(owner.eClass()); + } + + /** + * Obtains the Java interface type of the extension metaclass + * for my owner. + * + * @return my Java extension type + */ + protected final Class<?> getExtensionClass() { + return getExtensionEClass().getInstanceClass(); + } + + /** + * Obtains the extension object for my owner, creating it on + * demand, if necessary. + * + * @return my extension instance (never {@code null}) + */ + protected final InternalEObject demandExtension() { + if (extension == null) { + extension = (InternalEObject) ExtUMLExtFactory.eINSTANCE.create(getExtensionEClass()); + ((ExtElement) extension).setExtendedElement((Element) owner); + + // Add it to the extension extent + getExtensionExtent(owner).getContents().add(extension); + + // Forward notifications + extension.eAdapters().add(new AdapterImpl() { + @Override + public void notifyChanged(Notification msg) { + if (!suppressForwarding) { + NotificationForwarder.forward(owner, msg); + } + } + }); + } + + return extension; + } + + /** + * Creates my extension instance, if it does not already exist. + */ + public void createExtension() { + demandExtension(); + } + + /** + * Destroys my extension instance, if it exists. + */ + public void destroyExtension() { + if (extension != null) { + destroy(extension); + extension = null; + } + } + + /** + * Suppresses all forwarding of notifications from extension features + * via my extended UML model element for the duration of the given + * {@code action}. + * + * @param action + * an action to execute without notification forwarding + */ + public void suppressForwardingWhile(Runnable action) { + boolean wasSuppressingForwarding = suppressForwarding; + suppressForwarding = true; + try { + action.run(); + } finally { + suppressForwarding = wasSuppressingForwarding; + } + } + + /** + * Obtains the extent in which the UML extension of an {@code object} is + * kept. If the {@code object} is in a resource set that does not yet + * have an extension extent, it will be created. + * + * @param object + * a model element + * @return its extension extent, which is never {@code null} + */ + public static Resource getExtensionExtent(Object object) { + Resource result = null; + ResourceSet rset = null; + + if (object instanceof ResourceSet) { + rset = (ResourceSet) object; + } else if (object instanceof Resource) { + rset = ((Resource) object).getResourceSet(); + } else if (object instanceof EObject) { + Resource resource = ((EObject) object).eResource(); + if (resource != null) { + rset = resource.getResourceSet(); + } + } + + if (rset != null) { + result = rset.getResource(EXTENSION_EXTENT_URI, false); + if (result == null) { + result = new ExtensionResource(); + rset.getResources().add(result); + } + } + + if (result == null) { + result = ExtensionResource.SHARED_EXTENT; + } + + return result; + } + + /** + * Obtains the extension feature identified by the specified ID for + * the given UML metaclass. + * + * @param eClass + * an extended UML metaclass (not the extension metaclass) + * @param featureID + * the ID of an extension feature, in terms of the extended + * UML metaclass (not the extension metaclass) + * + * @return the extension feature + */ + public static EStructuralFeature getExtensionFeature(EClass eClass, int featureID) { + if (featureID <= UML_EXTENSION_FEATURE_BASE) { + featureID = UML_EXTENSION_FEATURE_BASE - featureID; + } + + return getExtensionEClass(eClass).getEStructuralFeature(featureID); + } + + /** + * Obtains the contents of the given {@code object}, including any extension + * features that are containments. + * + * @param object + * an extended UML model element + * + * @return its contents, including extension containments + */ + public <T> EList<T> getContents(InternalEObject object) { + EStructuralFeature[] realContainments = ((EClassImpl.FeatureSubsetSupplier) object.eClass().getEAllStructuralFeatures()).containments(); + EStructuralFeature[] extContainments = (extension == null) + ? null + : ((EClassImpl.FeatureSubsetSupplier) extension.eClass().getEAllStructuralFeatures()).containments(); + + EStructuralFeature[] allContainments = ((extContainments == null) || (extContainments.length == 0)) + ? realContainments + : ((realContainments == null) || (realContainments.length == 0)) + ? extContainments + : concat(realContainments, extContainments); + + return (allContainments == null) ? EContentsEList.<T> emptyContentsEList() : new EContentsEList<>(object, allContainments); + } + + <T> T[] concat(T[] first, T[] second) { + @SuppressWarnings("unchecked") + T[] result = (T[]) Array.newInstance(first.getClass().getComponentType(), first.length + second.length); + System.arraycopy(first, 0, result, 0, first.length); + System.arraycopy(second, 0, result, first.length, second.length); + return result; + } + + /** + * Computes the derived structural feature ID for a feature of my extended + * element, which feature may be a core UML feature or an extension. + * + * @param eStructuralFeature + * an UML feature or extension feature + * @return its derived feature ID for my owner + */ + public int getDerivedStructuralFeatureID(EStructuralFeature eStructuralFeature) { + int result; + + Class<?> containerClass = eStructuralFeature.getContainerClass(); + if (containerClass == null) { + result = owner.eClass().getFeatureID(eStructuralFeature); + } else if (containerClass.isAssignableFrom(getExtensionClass())) { + int featureID = (extension == null) + ? getExtensionEClass().getFeatureID(eStructuralFeature) + : extension.eDerivedStructuralFeatureID(eStructuralFeature.getFeatureID(), containerClass); + result = UML_EXTENSION_FEATURE_BASE - featureID; + } else { + assert owner.eClass().getEAllStructuralFeatures().contains(eStructuralFeature) : "The feature '" + eStructuralFeature.getName() + "' is not a valid feature"; + result = owner.eDerivedStructuralFeatureID(eStructuralFeature.getFeatureID(), containerClass); + } + + return result; + } + + /** + * Queries whether the given feature is set for my owner. + * + * @param eFeature + * a feature, which may be a core UML feature or an extension + * + * @return whether the feature is set in my owner + */ + public boolean isSet(EStructuralFeature eFeature) { + boolean result; + + Class<?> containerClass = eFeature.getContainerClass(); + if (containerClass.isAssignableFrom(getExtensionClass())) { + result = (extension != null) && extension.eIsSet(extension.eDerivedStructuralFeatureID(eFeature.getFeatureID(), containerClass)); + } else { + throw new IllegalArgumentException(String.format("The feature '%s' is not a valid feature", eFeature.getName())); + } + + return result; + } + + /** + * Queries whether the given feature ID is set for my owner. + * + * @param featureID + * the derived (for my owner) ID of a feature, which + * may be a core UML feature or an extension + * + * @return whether the feature is set in my owner + */ + public boolean isSet(int featureID) { + featureID = UML_EXTENSION_FEATURE_BASE - featureID; + return (extension != null) && extension.eIsSet(featureID); + } + + /** + * Obtains the value of the given feature for my owner. + * + * @param eFeature + * a feature, which may be a core UML feature or an extension + * @param resolve + * whether to resolve any proxies + * + * @return the value of the feature for my owner + */ + public Object get(EStructuralFeature eFeature, boolean resolve) { + Object result; + + Class<?> containerClass = eFeature.getContainerClass(); + if (containerClass.isAssignableFrom(getExtensionClass())) { + if (extension != null) { + result = extension.eGet(eFeature, resolve); + } else if (eFeature.isMany()) { + result = (eFeature == ExtUMLExtPackage.Literals.NAMESPACE__EXCLUDED_MEMBER) + // Special case for this, which is computed and does not require the extension + ? NamespaceOperations.getExcludedMembers((Namespace) owner) + : new DeferredEList<>(owner, eFeature); + } else { + result = (eFeature == ExtUMLExtPackage.Literals.ELEMENT__EXTENDED_ELEMENT) + // Special case for this, which is computed and does not require the extension + ? owner + : null; + } + } else { + throw new IllegalArgumentException(String.format("The feature '%s' is not a valid feature", eFeature.getName())); + } + + return result; + } + + /** + * Obtains the value of the given feature for my owner. + * + * @param featureID + * the derived (for my owner) ID of a feature, which + * may be a core UML feature or an extension + * @param resolve + * whether to resolve any proxies + * + * @return the value of the feature for my owner + */ + public Object get(int featureID, boolean resolve) { + featureID = UML_EXTENSION_FEATURE_BASE - featureID; + return extension.eGet(featureID, resolve, true); + } + + /** + * Sets the value of the given feature for my owner. + * + * @param eFeature + * a feature, which may be a core UML feature or an extension + * @param newValue + * the new value to set in the feature + */ + public void set(EStructuralFeature eFeature, Object newValue) { + Class<?> containerClass = eFeature.getContainerClass(); + if (containerClass.isAssignableFrom(getExtensionClass())) { + int featureID = demandExtension().eDerivedStructuralFeatureID(eFeature.getFeatureID(), containerClass); + extension.eSet(featureID, newValue); + } else { + throw new IllegalArgumentException(String.format("The feature '%s' is not a valid changeable feature", eFeature.getName())); + } + } + + /** + * Sets the value of the given feature for my owner. + * + * @param featureID + * the derived (for my owner) ID of a feature, which + * may be a core UML feature or an extension + * @param newValue + * the new value to set in the feature + */ + public void set(int featureID, Object newValue) { + featureID = UML_EXTENSION_FEATURE_BASE - featureID; + demandExtension().eSet(featureID, newValue); + } + + /** + * Unsets the value of the given feature for my owner. + * + * @param eFeature + * a feature, which may be a core UML feature or an extension + */ + public void unset(EStructuralFeature eFeature) { + Class<?> containerClass = eFeature.getContainerClass(); + if (containerClass.isAssignableFrom(getExtensionClass())) { + if (extension != null) { + extension.eUnset(extension.eDerivedStructuralFeatureID(eFeature.getFeatureID(), containerClass)); + } + } else { + throw new IllegalArgumentException(String.format("The feature '%s' is not a valid changeable feature", eFeature.getName())); + } + } + + /** + * Unsets the value of the given feature for my owner. + * + * @param featureID + * the derived (for my owner) ID of a feature, which + * may be a core UML feature or an extension + */ + public void unset(int featureID) { + featureID = UML_EXTENSION_FEATURE_BASE - featureID; + if (extension != null) { + extension.eUnset(featureID); + } + } + + /** + * Obtains the setting of the given feature for my owner. + * + * @param eFeature + * a feature, which may be a core UML feature or an extension + */ + public EStructuralFeature.Setting setting(EStructuralFeature eFeature) { + EStructuralFeature.Setting result; + + Class<?> containerClass = eFeature.getContainerClass(); + if (containerClass.isAssignableFrom(getExtensionClass())) { + if (extension != null) { + EStructuralFeature.Setting setting = extension.eSetting(eFeature); + result = new EStructuralFeature.Setting() { + + @Override + public EObject getEObject() { + return owner; + } + + @Override + public EStructuralFeature getEStructuralFeature() { + return setting.getEStructuralFeature(); + } + + @Override + public Object get(boolean resolve) { + return setting.get(resolve); + } + + @Override + public boolean isSet() { + return setting.isSet(); + } + + @Override + public void set(Object newValue) { + setting.set(newValue); + } + + @Override + public void unset() { + setting.unset(); + } + }; + } else if (eFeature.isMany()) { + result = new DeferredEList<>(owner, eFeature); + } else { + result = new DeferredSetting(owner, eFeature); + } + } else { + throw new IllegalArgumentException(String.format("The feature '%s' is not a valid feature", eFeature.getName())); + } + + return result; + } + + // + // Nested types + // + + /** + * A deferred list implementing the feature setting of a multi-valued extension + * feature for an object that does not yet have the extension created. Any + * operation that would modify the feature will cause the extension to be created + * and this setting then to delegate to the extension's actual feature setting. + */ + private final class DeferredEList<E> extends DelegatingEList<E> + implements InternalEList.Unsettable<E>, EStructuralFeature.Setting { + + private static final long serialVersionUID = 1L; + + private InternalEObject owner; + private final EStructuralFeature feature; + private List<E> delegate = ECollections.emptyEList(); + + DeferredEList(InternalEObject owner, EStructuralFeature feature) { + super(); + + this.owner = owner; + this.feature = feature; + } + + @Override + public EObject getEObject() { + return owner; + } + + @Override + public EStructuralFeature getEStructuralFeature() { + return feature; + } + + // + // Delegation + // + + @Override + protected List<E> delegateList() { + return delegate; + } + + @SuppressWarnings("unchecked") + void demandList() { + if (owner == ExtensionHolder.this.owner) { + owner = demandExtension(); + delegate = (EList<E>) owner.eGet(getEStructuralFeature()); + } + } + + @Override + protected void delegateAdd(E object) { + demandList(); + super.delegateAdd(object); + } + + @Override + protected void delegateAdd(int index, E object) { + demandList(); + super.delegateAdd(index, object); + } + + @Override + protected void delegateClear() { + demandList(); + super.delegateClear(); + } + + @Override + protected E delegateRemove(int index) { + demandList(); + return super.delegateRemove(index); + } + + @Override + protected E delegateSet(int index, E object) { + demandList(); + return super.delegateSet(index, object); + } + + @Override + protected E delegateMove(int targetIndex, int sourceIndex) { + demandList(); + return super.delegateMove(targetIndex, sourceIndex); + } + + // + // Internals + // + + @Override + public List<E> basicList() { + return super.basicList(); + } + + @Override + public Iterator<E> basicIterator() { + return super.basicIterator(); + } + + @Override + public ListIterator<E> basicListIterator() { + return super.basicListIterator(); + } + + @Override + public ListIterator<E> basicListIterator(int index) { + return super.basicListIterator(index); + } + + @Override + public E basicGet(int index) { + return super.basicGet(index); + } + + @Override + public Object[] basicToArray() { + return (delegate instanceof InternalEList<?>) + ? ((InternalEList<E>) delegate).basicToArray() + : delegate.toArray(); + } + + @Override + public <T> T[] basicToArray(T[] array) { + return (delegate instanceof InternalEList<?>) + ? ((InternalEList<E>) delegate).basicToArray(array) + : delegate.toArray(array); + } + + @Override + public int basicIndexOf(Object object) { + return (delegate instanceof InternalEList<?>) + ? ((InternalEList<E>) delegate).basicIndexOf(object) + : delegate.indexOf(object); + } + + @Override + public int basicLastIndexOf(Object object) { + return (delegate instanceof InternalEList<?>) + ? ((InternalEList<E>) delegate).basicLastIndexOf(object) + : delegate.lastIndexOf(object); + } + + @Override + public boolean basicContains(Object object) { + return (delegate instanceof InternalEList<?>) + ? ((InternalEList<E>) delegate).basicContains(object) + : delegate.contains(object); + } + + @Override + public boolean basicContainsAll(Collection<?> collection) { + return (delegate instanceof InternalEList<?>) + ? ((InternalEList<E>) delegate).basicContainsAll(collection) + : delegate.containsAll(collection); + } + + @Override + public NotificationChain basicRemove(Object object, NotificationChain notifications) { + demandList(); + return ((InternalEList<E>) delegate).basicRemove(object, notifications); + } + + @Override + public NotificationChain basicAdd(E object, NotificationChain notifications) { + demandList(); + return ((InternalEList<E>) delegate).basicAdd(object, notifications); + } + + @Override + public Object get(boolean resolve) { + return (delegate instanceof EStructuralFeature.Setting) + ? ((EStructuralFeature.Setting) delegate).get(resolve) + : this; + } + + @Override + public void set(Object newValue) { + demandList(); + ((EStructuralFeature.Setting) delegate).set(newValue); + } + + @Override + public boolean isSet() { + return (delegate instanceof EStructuralFeature.Setting) + ? ((EStructuralFeature.Setting) delegate).isSet() + : false; + } + + @Override + public void unset() { + demandList(); + ((EStructuralFeature.Setting) delegate).unset(); + } + } + + /** + * A deferred setting implementing the feature setting of a single-valued extension + * feature for an object that does not yet have the extension created. Any + * operation that would modify the feature will cause the extension to be created + * and this setting then to delegate to the extension's actual feature setting. + */ + private final class DeferredSetting implements EStructuralFeature.Setting { + private InternalEObject owner; + private final EStructuralFeature feature; + + DeferredSetting(InternalEObject owner, EStructuralFeature feature) { + super(); + + this.owner = owner; + this.feature = feature; + } + + @Override + public EObject getEObject() { + return owner; + } + + @Override + public EStructuralFeature getEStructuralFeature() { + return feature; + } + + @Override + public Object get(boolean resolve) { + return (extension == null) + ? feature.getDefaultValue() + : extension.eGet(feature, resolve); + } + + @Override + public void set(Object newValue) { + demandExtension().eSet(feature, newValue); + } + + @Override + public boolean isSet() { + return (extension != null) && extension.eIsSet(feature); + } + + @Override + public void unset() { + if (extension != null) { + extension.eUnset(feature); + } + } + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/util/ExtensionResource.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/util/ExtensionResource.java new file mode 100644 index 000000000..9ffa2e1db --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/util/ExtensionResource.java @@ -0,0 +1,250 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.Method; + +import org.eclipse.emf.common.CommonPlugin; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.notify.impl.NotificationImpl; +import org.eclipse.emf.common.util.EList; +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.resource.ResourceSet; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.ReificationAdapter; +import org.eclipse.uml2.common.util.CacheAdapter; +import org.eclipse.uml2.uml.internal.resource.UMLResourceImpl; + +/** + * A specialized resource implementation that serves as the extent of + * UML-RT extension objects for UML. + */ +public class ExtensionResource extends UMLResourceImpl { + public static final URI EXTENSION_EXTENT_URI = URI.createURI("umlrt://extensions"); //$NON-NLS-1$ + + // TODO: This may be prone to leaks + public static final Resource SHARED_EXTENT = new ExtensionResource(); + + private static final Object RESOURCE_SET_MANAGER; + private static final MethodHandle RESOURCE_SET_MANAGER__OBSERVE; + + private ReificationAdapter reificationAdapter; + + static { + Object resourceSetManager = null; + MethodHandle observe = null; + + try { + Class<?> resourceSetManagerClass = CommonPlugin.loadClass( + "org.eclipse.emf.transaction", //$NON-NLS-1$ + "org.eclipse.emf.transaction.impl.ResourceSetManager"); //$NON-NLS-1$ + Method getInstance = resourceSetManagerClass.getDeclaredMethod("getInstance"); + resourceSetManager = getInstance.invoke(null); + observe = MethodHandles.lookup().findVirtual( + resourceSetManagerClass, + "observe", + MethodType.methodType(void.class, Resource.class, Notification.class)); + } catch (Exception __) { + // Okay, the class isn't available in this installation, so we don't have to + // worry about transaction change recorders + } + + RESOURCE_SET_MANAGER = resourceSetManager; + RESOURCE_SET_MANAGER__OBSERVE = observe; + } + + public ExtensionResource() { + this(EXTENSION_EXTENT_URI); + } + + public ExtensionResource(URI uri) { + super(uri); + + // I implicitly begin in the loaded state. In particular, I must not + // appear to become loaded on the first addition of an extension + isLoaded = true; + + // Preemptively add the CacheAdapter so that there will be an ECrossReferenceAdapter + // for Papyrus's EMFHelper.getUsages(...) API to find, shortcutting the creation of + // a new one. And also because UML elements will be attached eventually anyways + CacheAdapter.getInstance().adapt(this); + } + + @Override + public EList<EObject> getContents() { + if (contents == null) { + if (RESOURCE_SET_MANAGER__OBSERVE == null) { + super.getContents(); + } else { + contents = new ExtensionContentsEList(); + } + } + + return contents; + } + + /** + * Obtains the extension resource that either contains the given + * {@code context} object or that is the extension resource for the + * {@link ResourceSet} containing the {@code context} element. + * + * @param context + * a model element + * + * @return its extension resource, or {@code null} if the {@code context} + * is not in a resource set that has one + */ + public static ExtensionResource getExtensionExtent(EObject context) { + ExtensionResource result = null; + + Resource resource = context.eResource(); + if (resource instanceof ExtensionResource) { + result = (ExtensionResource) resource; + } else if (resource != null) { + ResourceSet rset = resource.getResourceSet(); + if (rset != null) { + resource = rset.getResource(EXTENSION_EXTENT_URI, false); + if (resource instanceof ExtensionResource) { + result = (ExtensionResource) resource; + } + } + } + + return result; + } + + /** + * Obtains my reification adapter. + * + * @return my reificationAdapter + */ + public ReificationAdapter getReificationAdapter() { + if (reificationAdapter == null) { + ResourceSet rset = getResourceSet(); + reificationAdapter = (rset != null) + ? ReificationAdapter.getInstance(rset) + : new ReificationAdapter(); + } + + return reificationAdapter; + } + + @Override + protected boolean isAttachedDetachedHelperRequired() { + // We use the helper to ensure attachment of the reification adapter + return true; + } + + @Override + protected void attachedHelper(EObject eObject) { + super.attachedHelper(eObject); + + // Ensure that it has the reification adapter attached + getReificationAdapter().addAdapter(eObject); + } + + @Override + public NotificationChain basicSetResourceSet(ResourceSet resourceSet, NotificationChain notifications) { + NotificationChain result = super.basicSetResourceSet(resourceSet, notifications); + + // Recompute this, next time + reificationAdapter = null; + + return result; + } + + // + // Nested types + // + + /** + * A notification that we inject into the EMF Transaction framework's + * resource-set manager to make it think that an {@link ExtensionResource} + * is in the process of being loaded. + */ + private final class LoadNotification extends NotificationImpl { + LoadNotification(boolean loaded) { + super(Notification.SET, !loaded, loaded); + } + + @Override + public Object getNotifier() { + return ExtensionResource.this; + } + + @Override + public int getFeatureID(Class<?> expectedClass) { + return RESOURCE__IS_LOADED; + } + } + + /** + * A specialized contents list that lets the EMF Transaction framework's + * resource-set manager think an {@link ExtensionResource} is perpetually + * in a state of being loaded, to exempt manipulations of its contents + * from the transaction assertion. + */ + private class ExtensionContentsEList extends ContentsEList<EObject> { + private static final long serialVersionUID = 1L; + + private final Notification UNLOAD = new LoadNotification(false); + + @Override + public void addUnique(EObject object) { + // Let the editing domain think we are in a perpetual state of loading + ExtensionResource.this.isLoaded = false; + try { + observe(UNLOAD); + } finally { + ExtensionResource.this.isLoaded = true; + } + + super.addUnique(object); + } + + @Override + public void addUnique(int index, EObject object) { + // Let the editing domain think we are in a perpetual state of loading + ExtensionResource.this.isLoaded = false; + try { + observe(UNLOAD); + } finally { + ExtensionResource.this.isLoaded = true; + } + + super.addUnique(index, object); + } + + @Override + protected void loaded() { + // My resource is implicitly always loaded + } + + private void observe(Notification notification) { + try { + RESOURCE_SET_MANAGER__OBSERVE.invoke(RESOURCE_SET_MANAGER, + ExtensionResource.this, notification); + } catch (Exception e) { + // We tried + } catch (Throwable t) { + throw (Error) t; + } + } + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/util/UMLExtAdapterFactory.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/util/UMLExtAdapterFactory.java new file mode 100644 index 000000000..a67d152d8 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/util/UMLExtAdapterFactory.java @@ -0,0 +1,231 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtClass; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtEncapsulatedClassifier; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtInterface; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtStructuredClassifier; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; + +/** + * <!-- begin-user-doc --> + * The <b>Adapter Factory</b> for the model. + * It provides an adapter <code>createXXX</code> method for each class of the model. + * <!-- end-user-doc --> + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage + * @generated + */ +public class UMLExtAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected static ExtUMLExtPackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public UMLExtAdapterFactory() { + if (modelPackage == null) { + modelPackage = ExtUMLExtPackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * <!-- begin-user-doc --> + * This implementation returns <code>true</code> if the object is either the model's package or is an instance object of the model. + * <!-- end-user-doc --> + * @return whether this factory is applicable for the type of the object. + * @generated + */ + @Override + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject) object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch that delegates to the <code>createXXX</code> methods. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected UMLExtSwitch<Adapter> modelSwitch = new UMLExtSwitch<Adapter>() { + @Override + public Adapter caseElement(ExtElement object) { + return createElementAdapter(); + } + + @Override + public Adapter caseNamespace(ExtNamespace object) { + return createNamespaceAdapter(); + } + + @Override + public Adapter caseStructuredClassifier(ExtStructuredClassifier object) { + return createStructuredClassifierAdapter(); + } + + @Override + public Adapter caseEncapsulatedClassifier(ExtEncapsulatedClassifier object) { + return createEncapsulatedClassifierAdapter(); + } + + @Override + public Adapter caseClass(ExtClass object) { + return createClassAdapter(); + } + + @Override + public Adapter caseInterface(ExtInterface object) { + return createInterfaceAdapter(); + } + + @Override + public Adapter defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the <code>target</code>. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param target the object to adapt. + * @return the adapter for the <code>target</code>. + * @generated + */ + @Override + public Adapter createAdapter(Notifier target) { + return modelSwitch.doSwitch((EObject) target); + } + + + /** + * Creates a new adapter for an object of class '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement <em>Element</em>}'. + * <!-- begin-user-doc --> + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * <!-- end-user-doc --> + * @return the new adapter. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement + * @generated + */ + public Adapter createElementAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace <em>Namespace</em>}'. + * <!-- begin-user-doc --> + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * <!-- end-user-doc --> + * @return the new adapter. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace + * @generated + */ + public Adapter createNamespaceAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtStructuredClassifier <em>Structured Classifier</em>}'. + * <!-- begin-user-doc --> + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * <!-- end-user-doc --> + * @return the new adapter. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtStructuredClassifier + * @generated + */ + public Adapter createStructuredClassifierAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtEncapsulatedClassifier <em>Encapsulated Classifier</em>}'. + * <!-- begin-user-doc --> + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * <!-- end-user-doc --> + * @return the new adapter. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtEncapsulatedClassifier + * @generated + */ + public Adapter createEncapsulatedClassifierAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtClass <em>Class</em>}'. + * <!-- begin-user-doc --> + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * <!-- end-user-doc --> + * @return the new adapter. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtClass + * @generated + */ + public Adapter createClassAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtInterface <em>Interface</em>}'. + * <!-- begin-user-doc --> + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * <!-- end-user-doc --> + * @return the new adapter. + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtInterface + * @generated + */ + public Adapter createInterfaceAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * <!-- begin-user-doc --> + * This default implementation returns null. + * <!-- end-user-doc --> + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //UMLExtAdapterFactory diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/util/UMLExtDerivedUnionAdapter.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/util/UMLExtDerivedUnionAdapter.java new file mode 100644 index 000000000..ef696690a --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/util/UMLExtDerivedUnionAdapter.java @@ -0,0 +1,146 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.common.notify.impl.AdapterImpl; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; + +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtClass; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtInterface; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; + +/** + * <!-- begin-user-doc --> + * An adapter that propagates notifications for derived unions. + * <!-- end-user-doc --> + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage + * @generated + */ +public class UMLExtDerivedUnionAdapter extends AdapterImpl { + /** + * The cached model package. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected static ExtUMLExtPackage modelPackage; + + /** + * Creates an instance of the adapter. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public UMLExtDerivedUnionAdapter() { + if (modelPackage == null) { + modelPackage = ExtUMLExtPackage.eINSTANCE; + } + } + + /** + * Calls <code>notifyChanged</code> with the appropriate model class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param notification a description of the change. + * @generated + */ + @Override + public void notifyChanged(Notification notification) { + Object notifier = notification.getNotifier(); + if (notifier instanceof EObject) { + EClass eClass = ((EObject) notifier).eClass(); + if (eClass.eContainer() == modelPackage) { + notifyChanged(notification, eClass); + } + } + } + + /** + * Calls <code>notifyXXXChanged</code> for the corresponding class of the model. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param notification a description of the change. + * @param eClass the Ecore class of the notifier. + * @generated + */ + protected void notifyChanged(Notification notification, EClass eClass) { + switch (eClass.getClassifierID()) { + case ExtUMLExtPackage.CLASS: + notifyClassChanged(notification, eClass); + break; + case ExtUMLExtPackage.INTERFACE: + notifyInterfaceChanged(notification, eClass); + break; + } + } + + /** + * Does nothing; clients may override so that it does something. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param notification a description of the change. + * @param eClass the Ecore class of the notifier. + * @param derivedUnion the derived union affected by the change. + * @generated + */ + public void notifyChanged(Notification notification, EClass eClass, EStructuralFeature derivedUnion) { + // Do nothing. + } + + /** + * Calls <code>notifyChanged</code> for each affected derived union. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param notification a description of the change. + * @param eClass the Ecore class of the notifier. + * @generated + */ + protected void notifyClassChanged(Notification notification, EClass eClass) { + switch (notification.getFeatureID(ExtClass.class)) { + case ExtUMLExtPackage.CLASS__IMPLICIT_ATTRIBUTE: + notifyChanged(notification, eClass, ExtUMLExtPackage.Literals.NAMESPACE__IMPLICIT_MEMBER); + break; + case ExtUMLExtPackage.CLASS__IMPLICIT_CONNECTOR: + notifyChanged(notification, eClass, ExtUMLExtPackage.Literals.NAMESPACE__IMPLICIT_MEMBER); + break; + case ExtUMLExtPackage.CLASS__IMPLICIT_PORT: + notifyChanged(notification, eClass, ExtUMLExtPackage.Literals.NAMESPACE__IMPLICIT_MEMBER); + break; + case ExtUMLExtPackage.CLASS__IMPLICIT_OPERATION: + notifyChanged(notification, eClass, ExtUMLExtPackage.Literals.NAMESPACE__IMPLICIT_MEMBER); + break; + } + } + + /** + * Calls <code>notifyChanged</code> for each affected derived union. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param notification a description of the change. + * @param eClass the Ecore class of the notifier. + * @generated + */ + protected void notifyInterfaceChanged(Notification notification, EClass eClass) { + switch (notification.getFeatureID(ExtInterface.class)) { + case ExtUMLExtPackage.INTERFACE__IMPLICIT_OPERATION: + notifyChanged(notification, eClass, ExtUMLExtPackage.Literals.NAMESPACE__IMPLICIT_MEMBER); + break; + } + } + +} //UMLExtDerivedUnionAdapter diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/util/UMLExtSwitch.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/util/UMLExtSwitch.java new file mode 100644 index 000000000..3a87ddca0 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-gen/org/eclipse/papyrusrt/umlrt/uml/internal/umlext/util/UMLExtSwitch.java @@ -0,0 +1,280 @@ +/** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - initial API and implementation + * + */ +package org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.util.Switch; + +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtClass; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtEncapsulatedClassifier; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtInterface; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtNamespace; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtStructuredClassifier; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; + +/** + * <!-- begin-user-doc --> + * The <b>Switch</b> for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the <code>caseXXX</code> method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * <!-- end-user-doc --> + * @see org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage + * @generated + */ +public class UMLExtSwitch<T> extends Switch<T> { + /** + * The cached model package + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected static ExtUMLExtPackage modelPackage; + + /** + * Creates an instance of the switch. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public UMLExtSwitch() { + if (modelPackage == null) { + modelPackage = ExtUMLExtPackage.eINSTANCE; + } + } + + /** + * Checks whether this is a switch for the given package. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param ePackage the package in question. + * @return whether this is a switch for the given package. + * @generated + */ + @Override + protected boolean isSwitchFor(EPackage ePackage) { + return ePackage == modelPackage; + } + + /** + * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the first non-null result returned by a <code>caseXXX</code> call. + * @generated + */ + @Override + protected T doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case ExtUMLExtPackage.ELEMENT: { + ExtElement element = (ExtElement) theEObject; + T result = caseElement(element); + if (result == null) { + result = defaultCase(theEObject); + } + return result; + } + case ExtUMLExtPackage.NAMESPACE: { + ExtNamespace namespace = (ExtNamespace) theEObject; + T result = caseNamespace(namespace); + if (result == null) { + result = caseElement(namespace); + } + if (result == null) { + result = defaultCase(theEObject); + } + return result; + } + case ExtUMLExtPackage.STRUCTURED_CLASSIFIER: { + ExtStructuredClassifier structuredClassifier = (ExtStructuredClassifier) theEObject; + T result = caseStructuredClassifier(structuredClassifier); + if (result == null) { + result = caseNamespace(structuredClassifier); + } + if (result == null) { + result = caseElement(structuredClassifier); + } + if (result == null) { + result = defaultCase(theEObject); + } + return result; + } + case ExtUMLExtPackage.ENCAPSULATED_CLASSIFIER: { + ExtEncapsulatedClassifier encapsulatedClassifier = (ExtEncapsulatedClassifier) theEObject; + T result = caseEncapsulatedClassifier(encapsulatedClassifier); + if (result == null) { + result = caseStructuredClassifier(encapsulatedClassifier); + } + if (result == null) { + result = caseNamespace(encapsulatedClassifier); + } + if (result == null) { + result = caseElement(encapsulatedClassifier); + } + if (result == null) { + result = defaultCase(theEObject); + } + return result; + } + case ExtUMLExtPackage.CLASS: { + ExtClass class_ = (ExtClass) theEObject; + T result = caseClass(class_); + if (result == null) { + result = caseEncapsulatedClassifier(class_); + } + if (result == null) { + result = caseStructuredClassifier(class_); + } + if (result == null) { + result = caseNamespace(class_); + } + if (result == null) { + result = caseElement(class_); + } + if (result == null) { + result = defaultCase(theEObject); + } + return result; + } + case ExtUMLExtPackage.INTERFACE: { + ExtInterface interface_ = (ExtInterface) theEObject; + T result = caseInterface(interface_); + if (result == null) { + result = caseNamespace(interface_); + } + if (result == null) { + result = caseElement(interface_); + } + if (result == null) { + result = defaultCase(theEObject); + } + return result; + } + default: + return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpreting the object as an instance of '<em>Element</em>'. + * <!-- begin-user-doc --> + * This implementation returns null; + * returning a non-null result will terminate the switch. + * <!-- end-user-doc --> + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of '<em>Element</em>'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseElement(ExtElement object) { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of '<em>Namespace</em>'. + * <!-- begin-user-doc --> + * This implementation returns null; + * returning a non-null result will terminate the switch. + * <!-- end-user-doc --> + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of '<em>Namespace</em>'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseNamespace(ExtNamespace object) { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of '<em>Structured Classifier</em>'. + * <!-- begin-user-doc --> + * This implementation returns null; + * returning a non-null result will terminate the switch. + * <!-- end-user-doc --> + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of '<em>Structured Classifier</em>'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseStructuredClassifier(ExtStructuredClassifier object) { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of '<em>Encapsulated Classifier</em>'. + * <!-- begin-user-doc --> + * This implementation returns null; + * returning a non-null result will terminate the switch. + * <!-- end-user-doc --> + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of '<em>Encapsulated Classifier</em>'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseEncapsulatedClassifier(ExtEncapsulatedClassifier object) { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of '<em>Class</em>'. + * <!-- begin-user-doc --> + * This implementation returns null; + * returning a non-null result will terminate the switch. + * <!-- end-user-doc --> + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of '<em>Class</em>'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseClass(ExtClass object) { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of '<em>Interface</em>'. + * <!-- begin-user-doc --> + * This implementation returns null; + * returning a non-null result will terminate the switch. + * <!-- end-user-doc --> + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of '<em>Interface</em>'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseInterface(ExtInterface object) { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of '<em>EObject</em>'. + * <!-- begin-user-doc --> + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * <!-- end-user-doc --> + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of '<em>EObject</em>'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + @Override + public T defaultCase(EObject object) { + return null; + } + +} //UMLExtSwitch diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/FacadeObject.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/FacadeObject.java new file mode 100644 index 000000000..737f6b1e6 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/FacadeObject.java @@ -0,0 +1,197 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml; + +import java.util.List; +import java.util.Optional; +import java.util.function.UnaryOperator; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.common.notify.impl.AdapterImpl; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.UMLRTUMLFactoryImpl; +import org.eclipse.papyrusrt.umlrt.uml.util.UMLRTExtensionUtil; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.NamedElement; + +/** + * A façade for UML {@link Element}s that represent UML-RT concepts, + * providing a view of the element more in keeping with the UML-RT semantics. + */ +abstract class FacadeObject { + + private final Element element; + private final EObject stereotype; + + FacadeObject(Element element, EObject stereotype) { + super(); + + this.element = element; + this.stereotype = stereotype; + } + + static <T extends Element, U extends EObject, F extends FacadeObject> // + F getFacade(T element, FacadeType<T, U, F> type) { + FacadeObject.BasicFacadeAdapter<F> adapter = null; + + if (element instanceof InternalUMLRTElement) { + adapter = type.getAdapter(element); + if (adapter == null) { + U stereotype = type.getStereotypeApplication(element); + if (stereotype != null) { + adapter = type.createAdapter(stereotype); + adapter.addAdapter(element); + } + } + } + + return (adapter == null) ? null : type.getFacade(adapter); + } + + Element toUML() { + return element; + } + + EObject toRT() { + return stereotype; + } + + boolean isExcluded() { + return false; + } + + void destroy() { + // The destroy() API tears down cross-references, so + // don't let that auto-reify anything + Optional.ofNullable(toUML()).ifPresent( + uml -> UMLRTExtensionUtil.run(uml, uml::destroy)); + } + + <T extends Element, U extends EObject, F extends FacadeObject> // + List<F> getFacades(FacadeReference<T, U, F> reference) { + return reference.getFacades(element); + } + + <T extends Element, U extends EObject, F extends FacadeObject> // + List<F> getFacades(FacadeReference<T, U, F> reference, boolean withExclusions) { + return reference.getFacades(element, withExclusions); + } + + <T extends Element, U extends EObject, F extends FacadeObject> // + List<F> getFacades(FacadeReference<T, U, F> reference, boolean withExclusions, UnaryOperator<F> andThen) { + return reference.getFacades(element, withExclusions, andThen); + } + + <T extends Element, U extends EObject, F extends FacadeObject> // + List<F> getFacades(FacadeReference<T, U, F> reference, UnaryOperator<F> andThen) { + return reference.getFacades(element, andThen); + } + + <T extends NamedElement, U extends EObject, F extends FacadeObject> // + F get(FacadeReference<T, U, F> reference, String name) { + return reference.getAll(toUML()) + .filter(e -> name.equals(e.getName())) + .findAny() + .map(reference.getType()::getFacade) + .orElse(null); + } + + <T extends Element, U extends EObject, F extends FacadeObject> // + F getRedefinitionOf(F inherited, FacadeReference<T, U, F> reference) { + return reference.getRedefinitionOf(inherited, element); + } + + <T extends NamedElement, U extends EObject, F extends FacadeObject> // + F create(FacadeReference<T, U, F> reference, String name) { + @SuppressWarnings("unchecked") + T result = (T) UMLRTUMLFactoryImpl.eINSTANCE.create(reference.getEReferenceType()); + + if ((name != null) && (result != null)) { + result.setName(name); + } + + reference.getUML(toUML()).add(result); + reference.getType().applyStereotype(result); + + return reference.getType().getFacade(result); + } + + @Override + public String toString() { + return String.format("%s()", getClass().getSimpleName()); //$NON-NLS-1$ + } + + // + // Nested types + // + + /** + * An adapter that attaches the façade object to its underlying UML + * element (providing canonicalization of the mapping) and allows it to + * react to changes in the UML (for example, to invalidate cached information + * or to send change events). + */ + protected class BasicFacadeAdapter<F extends FacadeObject> extends AdapterImpl { + BasicFacadeAdapter() { + super(); + } + + @SuppressWarnings("unchecked") + final F getFacade() { + return (F) FacadeObject.this; + } + + @Override + public final boolean isAdapterForType(Object type) { + return type == FacadeObject.this.getClass(); + } + + protected boolean addAdapter(Notifier notifier) { + EList<Adapter> eAdapters = notifier.eAdapters(); + return !eAdapters.contains(this) && eAdapters.add(this); + } + + protected boolean removeAdapter(Notifier notifier) { + return notifier.eAdapters().remove(this); + } + + @Override + public void setTarget(Notifier newTarget) { + super.setTarget(newTarget); + + if (newTarget != null) { + // Ensure that we get stereotype application changes + UMLRTModel.getInstance(((EObject) newTarget).eResource()); + } + } + + protected void handleNotification(Notification msg) { + // Pass + } + + @Override + final public void notifyChanged(Notification msg) { + if (msg.isTouch()) { + return; + } + + handleNotification(msg); + } + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/FacadeReference.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/FacadeReference.java new file mode 100644 index 000000000..ba771b6e2 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/FacadeReference.java @@ -0,0 +1,184 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml; + +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.toList; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.UnaryOperator; +import java.util.stream.Stream; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.uml2.uml.Element; + +/** + * Metadata object describing a reference between façade objects. + */ +class FacadeReference<T extends Element, S extends EObject, F extends FacadeObject> { + + private final FacadeType<T, S, F> type; + private final EReference feature; + private final EReference extension; + private final EClass metaclass; + + FacadeReference(FacadeType<T, S, F> type, EReference feature, EReference extension, EClass metaclass) { + super(); + + this.type = type; + this.feature = feature; + this.extension = extension; + this.metaclass = metaclass; + } + + FacadeType<T, S, F> getType() { + return type; + } + + EClass getEReferenceType() { + return metaclass; + } + + /** + * Obtains the subset of the reference values that are "real", stored + * in the UML model in the appropriate UML metaclass property. + * + * @param element + * the element from which to obtain the reference values + * + * @return the real (locally-defined, redefined, or excluded) values + */ + @SuppressWarnings("unchecked") + List<T> getUML(Element element) { + return (List<T>) element.eGet(feature); + } + + /** + * Obtains the subset of the reference values that are "virtual", stored + * in the extension of the UML model in the appropriate UML extension + * metaclass property. + * + * @param element + * the element from which to obtain the reference values + * + * @return the virtual (purely inherited) values + */ + @SuppressWarnings("unchecked") + List<T> getExtension(Element element) { + return (element == null) + ? Collections.emptyList() + : (List<T>) element.eGet(extension); + } + + /** + * Obtains the union of "real" and "virtual" values of the reference, + * including all local, inherited, and redefined definitions. + * + * @param element + * the element from which to obtain the reference values + * @return the union of {@linkplain #getUML(Element) real UML} values + * and {@linkplain #getExtension(Element) virtual extension} values + */ + Stream<T> getAll(Element element) { + return (extension == null) + ? getUML(element).stream().filter(metaclass::isInstance) + : Stream.concat( + getUML(element).stream(), + getExtension(element).stream()) + .filter(metaclass::isInstance); + } + + Stream<F> facades(Element element, boolean withExclusions) { + Stream<F> result = getAll(element) + .map(type::getFacade) + .filter(Objects::nonNull); + + if (!withExclusions) { + Predicate<F> isExcluded = FacadeObject::isExcluded; + Predicate<F> notExcluded = isExcluded.negate(); + result = result.filter(notExcluded); + } + + return result; + } + + List<F> getFacades(Element element, boolean withExclusions) { + return facades(element, withExclusions).collect( + collectingAndThen(toList(), Collections::unmodifiableList)); + } + + List<F> getFacades(Element element, boolean withExclusions, UnaryOperator<F> andThen) { + return facades(element, withExclusions) + .map(andThen) + .collect(collectingAndThen(toList(), Collections::unmodifiableList)); + } + + List<F> getFacades(Element element) { + return getFacades(element, false); + } + + List<F> getFacades(Element element, UnaryOperator<F> andThen) { + return getFacades(element, false, andThen); + } + + List<F> getFacades(FacadeObject owner) { + return getFacades(owner.toUML()); + } + + F getRedefinitionOf(F facade, Element element) { + return facades(element, false) + .filter(f -> type.redefines(f, facade)) + .findAny() + .orElse(null); + } + + @Override + public String toString() { + return String.format("FacadeReference(name=%s, type=%s)", feature.getName(), type); //$NON-NLS-1$ + } + + // + // Nested types + // + + static class Indirect<T extends Element, S extends EObject, F extends FacadeObject> extends FacadeReference<T, S, F> { + private final Function<? super Element, ? extends Element> indirection; + + Indirect(FacadeType<T, S, F> type, EReference feature, EReference extension, EClass metaclass, + Function<? super Element, ? extends Element> indirection) { + + super(type, feature, extension, metaclass); + + this.indirection = indirection; + } + + @Override + List<T> getUML(Element element) { + return super.getUML(indirection.apply(element)); + } + + @Override + List<T> getExtension(Element element) { + return (element == null) + ? Collections.emptyList() + : super.getExtension(indirection.apply(element)); + } + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/FacadeType.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/FacadeType.java new file mode 100644 index 000000000..79dce7acd --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/FacadeType.java @@ -0,0 +1,131 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml; + +import java.util.function.Function; +import java.util.function.UnaryOperator; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.papyrusrt.umlrt.uml.FacadeObject.BasicFacadeAdapter; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.util.UMLUtil; +import org.eclipse.uml2.uml.util.UMLUtil.StereotypeApplicationHelper; + +/** + * Metadata object describing the type of a façade object. + */ +final class FacadeType<T extends Element, S extends EObject, F extends FacadeObject> { + + private final Class<F> instanceClass; + private final EClass umlMetaclass; + private final EClass stereotype; + private final Function<T, F> facadeFunction; + private final UnaryOperator<F> redefinitionOperator; + private final Class<? extends FacadeObject.BasicFacadeAdapter<F>> adapterType; + private final Function<? super S, ? extends FacadeObject.BasicFacadeAdapter<F>> adapterFactory; + + <A extends FacadeObject.BasicFacadeAdapter<F>> FacadeType(Class<F> instanceClass, + EClass umlMetaclass, EClass stereotype, + Function<T, F> facadeFunction, + UnaryOperator<F> redefinitionOperator, + Class<A> adapterType, Function<? super S, A> adapterFactory) { + + super(); + + this.instanceClass = instanceClass; + this.umlMetaclass = umlMetaclass; + this.stereotype = stereotype; + this.facadeFunction = facadeFunction; + this.redefinitionOperator = redefinitionOperator; + this.adapterType = adapterType; + this.adapterFactory = adapterFactory; + } + + @SuppressWarnings("unchecked") + FacadeType(Class<F> instanceClass, + EClass umlMetaclass, EClass stereotype, + Function<T, F> facadeFunction, + UnaryOperator<F> redefinitionOperator, + Function<? super S, F> facadeFactory) { + + this(instanceClass, umlMetaclass, stereotype, facadeFunction, redefinitionOperator, + BasicFacadeAdapter.class, + s -> facadeFactory.apply(s).new BasicFacadeAdapter<>()); + } + + F getFacade(T element) { + return umlMetaclass.isInstance(element) ? facadeFunction.apply(element) : null; + } + + /** + * Obtains my redefinition of the given {@code facade}, even if it + * is an {@linkplain FacadeObject#isExcluded() exclusion}. + * + * @param facade + * an inherited facade element + * @return the element that the {@code facade} redefines, implicit, excluded, or otherwise + * + * @see FacadeObject#isExcluded() + */ + F getRedefinition(F facade) { + return redefinitionOperator.apply(facade); + } + + boolean redefines(F self, F other) { + boolean result = false; + + for (; !result && (self != null); self = getRedefinition(self)) { + result = self == other; + } + + return result; + } + + @SuppressWarnings("unchecked") + <A extends FacadeObject.BasicFacadeAdapter<F>> // + A getAdapter(T element) { + return (A) adapterType.cast(EcoreUtil.getExistingAdapter(element, instanceClass)); + } + + FacadeObject.BasicFacadeAdapter<F> createAdapter(S stereotype) { + return adapterFactory.apply(stereotype); + } + + F getFacade(Adapter adapter) { + return adapterType.cast(adapter).getFacade(); + } + + @SuppressWarnings("unchecked") + S applyStereotype(T element) { + return (stereotype == null) + ? null + : (S) StereotypeApplicationHelper.getInstance(element) + .applyStereotype(element, stereotype); + } + + @SuppressWarnings("unchecked") + S getStereotypeApplication(T element) { + return (stereotype == null) + ? null + : (S) UMLUtil.getStereotypeApplication(element, (Class<S>) stereotype.getInstanceClass()); + } + + @Override + public String toString() { + return String.format("FacadeType(name=%s)", instanceClass.getSimpleName()); //$NON-NLS-1$ + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTCapsule.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTCapsule.java new file mode 100644 index 000000000..94adf6db1 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTCapsule.java @@ -0,0 +1,411 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml; + +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.toList; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Stream; + +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.Capsule; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.CapsulePart; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTConnector; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTPort; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Connector; +import org.eclipse.uml2.uml.ConnectorEnd; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.util.UMLUtil; + +/** + * A façade for UML {@link Class} elements that represent UML-RT {@link Capsule Capsule}s, + * providing a view of the element more in keeping with the UML-RT semantics. + */ +public final class UMLRTCapsule extends UMLRTClassifier { + + static final FacadeType<Class, Capsule, UMLRTCapsule> TYPE = new FacadeType<>( + UMLRTCapsule.class, + UMLPackage.Literals.CLASS, + UMLRealTimePackage.Literals.CAPSULE, + UMLRTCapsule::getInstance, + UMLRTCapsule::getSuperclass, + UMLRTCapsule::new); + + private static final FacadeReference<Port, RTPort, UMLRTPort> PORT_REFERENCE = new FacadeReference<>( + UMLRTPort.TYPE, + UMLPackage.Literals.ENCAPSULATED_CLASSIFIER__OWNED_PORT, + ExtUMLExtPackage.Literals.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT, + UMLPackage.Literals.PORT); + + private static final FacadeReference<Property, CapsulePart, UMLRTCapsulePart> CAPSULE_PART_REFERENCE = new FacadeReference<>( + UMLRTCapsulePart.TYPE, + UMLPackage.Literals.STRUCTURED_CLASSIFIER__OWNED_ATTRIBUTE, + ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE, + UMLPackage.Literals.PROPERTY); + + private static final FacadeReference<Connector, RTConnector, UMLRTConnector> CONNECTOR_REFERENCE = new FacadeReference<>( + UMLRTConnector.TYPE, + UMLPackage.Literals.STRUCTURED_CLASSIFIER__OWNED_CONNECTOR, + ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR, + UMLPackage.Literals.CONNECTOR); + + UMLRTCapsule(Capsule capsule) { + super(capsule.getBase_Class(), capsule); + } + + /** + * Obtains the canonical instance of the capsule façade for a class. + * + * @param class_ + * a class in the UML model + * + * @return its capsule façade, or {@code null} if the class is not a valid capsule + */ + public static UMLRTCapsule getInstance(Class class_) { + return getFacade(class_, TYPE); + } + + /** + * Obtains the UML representation of the capsule. + * + * @return the UML representation + */ + @Override + public Class toUML() { + return (Class) super.toUML(); + } + + @Override + Capsule toRT() { + return (Capsule) super.toRT(); + } + + /** + * Obtains the capsule that is my supertype, if any. + * + * @return my supertype, or {@code null} if I am a root capsule type + */ + public UMLRTCapsule getSuperclass() { + return (UMLRTCapsule) getGeneral(); + } + + /** + * Assigns the capsule that is my supertype. UML-RT recognizes + * only single inheritance, so if the UML model has any other + * generalizations, they are destroyed. + * + * @param capsule + * my new supertype, or {@code null} if I am to be a root type + */ + public void setSuperclass(UMLRTCapsule capsule) { + setGeneral(capsule); + } + + /** + * Obtains the currently loaded capsules that are my direct subtypes. + * Note that there may be other sub-types in resources that are not + * currently loaded. + * + * @return my known subtypes + */ + public List<UMLRTCapsule> getSubclasses() { + return getSpecifics(false) + .filter(UMLRTCapsule.class::isInstance) + .map(UMLRTCapsule.class::cast) + .collect(collectingAndThen(toList(), Collections::unmodifiableList)); + } + + /** + * Gets the entire capsule specialization hierarchy, rooted at myself, + * as a stream. Note that there may be other types in the hierarchy in + * resources that are not currently loaded; these will not be included + * in the result. + * + * @return my capsule class hierarchy + */ + @Override + public Stream<UMLRTCapsule> getHierarchy() { + return super.getHierarchy() + .filter(UMLRTCapsule.class::isInstance) + .map(UMLRTCapsule.class::cast); + } + + static boolean isCapsule(Class class_) { + return getCapsule(class_) != null; + } + + static Capsule getCapsule(Class class_) { + return UMLUtil.getStereotypeApplication(class_, Capsule.class); + } + + /** + * Obtains my ports, including any that are inherited from my supercapsule + * if I have one but not any that I {@linkplain #exclude() exclude}. + * + * @return all of my effective ports + */ + public List<UMLRTPort> getPorts() { + return getFacades(PORT_REFERENCE); + } + + /** + * Obtains my ports, including any that are inherited from my supercapsule + * if I have one but also optionally any that I {@linkplain #exclude() exclude}. + * + * @param withExcluded + * whether to return also excluded ports + * @return all of my ports, optionally also with exclusions + */ + public List<UMLRTPort> getPorts(boolean withExcluded) { + return getFacades(PORT_REFERENCE, withExcluded); + } + + /** + * Obtains the {@code name}d port, possibly inherited from my supercapsule, + * even if I have {@linkplain #exclude() excluded} it. + * + * @param name + * the port name to find + * @return the named port, or {@code null} if I have no port of that {@code name} + */ + public UMLRTPort getPort(String name) { + return get(PORT_REFERENCE, name); + } + + /** + * Creates a new external behavior port of the given protocol type. + * It is named automatically according to the protocol name. If the protocol + * is a {@link UMLRTProtocol#isConjugate() conjugate}, then the resulting + * port will be {@link UMLRTPort#isConjugated() conjugated}. + * + * @param protocol + * the port type + * + * @return the port + * + * @see #createPort(UMLRTProtocol, UMLRTPortKind) + */ + public UMLRTPort createPort(UMLRTProtocol protocol) { + return createPort(protocol, UMLRTPortKind.EXTERNAL_BEHAVIOR); + } + + /** + * Creates a new port of the given protocol type. It is named automatically + * according to the protocol name. If the protocol is a + * {@link UMLRTProtocol#isConjugate() conjugate}, then the resulting port + * will be {@link UMLRTPort#isConjugated() conjugated}. + * + * @param protocol + * the port type + * @param kind + * its kind + * + * @return the port + * + * @see #createPort(UMLRTProtocol) + */ + public UMLRTPort createPort(UMLRTProtocol protocol, UMLRTPortKind kind) { + String baseProtocolName = protocol.isConjugate() + ? protocol.getConjugate().getName() // want the base protocol name + : protocol.getName(); + String portName = initialLower(baseProtocolName); + UMLRTPort result = create(PORT_REFERENCE, portName); + result.setType(protocol); + result.setKind(kind); + return result; + } + + /** + * Obtains my parts, including any that are inherited from my supercapsule + * if I have one but not any that I {@linkplain #exclude() exclude}. + * + * @return all of my effective capsule-parts + */ + public List<UMLRTCapsulePart> getCapsuleParts() { + return getFacades(CAPSULE_PART_REFERENCE); + } + + /** + * Obtains my parts, including any that are inherited from my supercapsule + * if I have one but also optionally any that I {@linkplain #exclude() exclude}. + * + * @param withExcluded + * whether to return also excluded capsule-parts + * @return all of my capsule-parts, optionally also with exclusions + */ + public List<UMLRTCapsulePart> getCapsuleParts(boolean withExcluded) { + return getFacades(CAPSULE_PART_REFERENCE, withExcluded); + } + + /** + * Obtains the {@code name}d part, possibly inherited from my supercapsule, + * even if I have {@linkplain #exclude() excluded} it. + * + * @param name + * the part name to find + * @return the named capsule-part, or {@code null} if I have no part of that {@code name} + */ + public UMLRTCapsulePart getCapsulePart(String name) { + return get(CAPSULE_PART_REFERENCE, name); + } + + /** + * Creates a new part of the given capsule type. It is named automatically + * according to the capsule name. + * + * @param capsule + * the part type + * + * @return the capsule-part + * + * @see #createPort(UMLRTCapsule) + */ + public UMLRTCapsulePart createCapsulePart(UMLRTCapsule capsule) { + String partName = initialLower(capsule.getName()); + UMLRTCapsulePart result = create(CAPSULE_PART_REFERENCE, partName); + result.setType(capsule); + return result; + } + + /** + * Obtains my connectors, including any that are inherited from my supercapsule + * if I have one but not any that I {@linkplain #exclude() exclude}. + * + * @return all of my effective connectors + */ + public List<UMLRTConnector> getConnectors() { + return getFacades(CONNECTOR_REFERENCE); + } + + /** + * Obtains my connectors, including any that are inherited from my supercapsule + * if I have one but also optionally any that I {@linkplain #exclude() exclude}. + * + * @param withExcluded + * whether to return also excluded connectors + * @return all of my connectors, optionally also with exclusions + */ + public List<UMLRTConnector> getConnectors(boolean withExcluded) { + return getFacades(CONNECTOR_REFERENCE, withExcluded); + } + + /** + * Obtains the {@code name}d connector, possibly inherited from my supercapsule, + * even if I have {@linkplain #exclude() excluded} it. + * + * @param name + * the connector name to find + * @return the named connector, or {@code null} if I have no connector of that {@code name} + */ + public UMLRTConnector getConnector(String name) { + return get(CONNECTOR_REFERENCE, name); + } + + /** + * Creates a new connector between two ports, with parts as appropriate. + * + * @param name + * the connector name + * @param source + * the port to connect + * @param sourcePartWithPort + * the part that has the {@code source} port, or {@code null} + * if the {@code source} is a port of this capsule + * @param target + * the port to which to connect the {@code source} + * @param targetPartWithPort + * the part that has the {@code target} port, or {@code null} + * if the {@code target} is a port of this capsule + * + * @return the new connector + */ + public UMLRTConnector createConnector(String name, UMLRTPort source, UMLRTCapsulePart sourcePartWithPort, + UMLRTPort target, UMLRTCapsulePart targetPartWithPort) { + + UMLRTConnector result = create(CONNECTOR_REFERENCE, name); + ConnectorEnd sourceEnd = result.toUML().createEnd(); + sourceEnd.setRole(source.toUML()); + if (sourcePartWithPort != null) { + sourceEnd.setPartWithPort(sourcePartWithPort.toUML()); + } + + ConnectorEnd targetEnd = result.toUML().createEnd(); + targetEnd.setRole(target.toUML()); + if (targetPartWithPort != null) { + targetEnd.setPartWithPort(targetPartWithPort.toUML()); + } + + return result; + } + + /** + * Obtains all of the ports, parts, and connectors that I have excluded + * from inheritance. + * + * @return my excluded features + */ + @Override + public List<UMLRTNamedElement> getExcludedElements() { + return super.getExcludedElements(); + } + + /** + * Obtains the named excluded element. + * + * @param name + * the name of the element to find + * @param facadeType + * the kind of excluded element to find + * + * @return the excluded element, or {@code null} if none + */ + @Override + public <T extends UMLRTNamedElement> T getExcludedElement(String name, java.lang.Class<T> facadeType) { + return super.getExcludedElement(name, facadeType); + } + + /** + * Obtains my local redefinition of the given inherited element, even if it + * just the local façade representation of that element inherited as is. + * If the element is a local definition, then it is returned as is. + * + * @param inheritedElement + * an element that I (would) inherit from my supertype + * + * @return my local redefinition or purely inherited view of the element, + * or {@code null} if either I do not inherit the element or I + * {@linkplain #exclude() exclude} it + */ + @SuppressWarnings("unchecked") + public <T extends UMLRTNamedElement> T getRedefinitionOf(T inheritedElement) { + T result = null; + + if (inheritedElement instanceof UMLRTPort) { + result = (T) getRedefinitionOf((UMLRTPort) inheritedElement, PORT_REFERENCE); + } else if (inheritedElement instanceof UMLRTCapsulePart) { + result = (T) getRedefinitionOf((UMLRTCapsulePart) inheritedElement, CAPSULE_PART_REFERENCE); + } else if (inheritedElement instanceof UMLRTConnector) { + result = (T) getRedefinitionOf((UMLRTConnector) inheritedElement, CONNECTOR_REFERENCE); + } + + return result; + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTCapsulePart.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTCapsulePart.java new file mode 100644 index 000000000..b668ea8f9 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTCapsulePart.java @@ -0,0 +1,279 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml; + +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.toList; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.function.Predicate; +import java.util.stream.Stream; + +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.CapsulePart; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.uml2.common.util.CacheAdapter; +import org.eclipse.uml2.uml.AggregationKind; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.ConnectableElement; +import org.eclipse.uml2.uml.Connector; +import org.eclipse.uml2.uml.ConnectorEnd; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.LiteralUnlimitedNatural; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.Type; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * A façade for UML {@link Property} elements that represent UML-RT {@link CapsulePart}s, + * providing a view of the element more in keeping with the UML-RT semantics. + */ +public class UMLRTCapsulePart extends UMLRTReplicatedElement { + static final FacadeType<Property, CapsulePart, UMLRTCapsulePart> TYPE = new FacadeType<>( + UMLRTCapsulePart.class, + UMLPackage.Literals.PROPERTY, + UMLRealTimePackage.Literals.CAPSULE_PART, + UMLRTCapsulePart::getInstance, + UMLRTCapsulePart::getRedefinedPart, + UMLRTCapsulePart::new); + + UMLRTCapsulePart(CapsulePart capsulePart) { + super(capsulePart.getBase_Property(), capsulePart); + } + + /** + * Obtains the canonical instance of the capsule-part façade for a property. + * + * @param part + * a property in the UML model + * + * @return its capsule-part façade, or {@code null} if the property is not a valid capsule-part + */ + public static UMLRTCapsulePart getInstance(Property part) { + return getFacade(part, TYPE); + } + + /** + * Obtains the capsule that is my type, if any. + * + * @return my capsule type, or {@code null} if I have none + */ + public UMLRTCapsule getType() { + Type result = toUML().getType(); + return (result instanceof Class) ? UMLRTCapsule.getInstance((Class) result) + : null; + } + + /** + * Assigns my capsule type. + * + * @param type + * my new type, or {@code null} if I have none + */ + public void setType(UMLRTCapsule type) { + if (type == null) { + toUML().setType(null); + } else { + toUML().setType(type.toUML()); + } + } + + /** + * Obtains all of the connectors that connect ports that I expose to the + * capsule that contains me, apart from any that are {@linkplain #exclude() excluded}. + * + * @return the connectors of my ports in the context of my + * {@linkplain #getCapsule() containing capsule} + */ + public List<UMLRTConnector> getConnectorsOfPorts() { + UMLRTCapsule capsule = getCapsule(); + Predicate<UMLRTConnector> excluded = UMLRTConnector::isExcluded; + + // Get the connectors that are defined within my capsule + return allConnectorsOfPorts() + .map(capsule::getRedefinitionOf) + .filter(Objects::nonNull) + .filter(excluded.negate()) + .distinct() + .collect(collectingAndThen(toList(), Collections::unmodifiableList)); + } + + Stream<UMLRTConnector> allConnectorsOfPorts() { + return redefinitionChain().stream() + .map(UMLRTCapsulePart.class::cast) + .flatMap(UMLRTCapsulePart::getEnds) + .map(Element::getOwner) + .map(Connector.class::cast) + .map(UMLRTConnector::getInstance) + .filter(Objects::nonNull); + } + + Stream<ConnectorEnd> getEnds() { + CacheAdapter cache = CacheAdapter.getCacheAdapter(toUML()); + return cache.getNonNavigableInverseReferences(toUML()).stream() + .filter(s -> s.getEStructuralFeature() == UMLPackage.Literals.CONNECTOR_END__PART_WITH_PORT) + .map(EStructuralFeature.Setting::getEObject) + .map(ConnectorEnd.class::cast); + } + + /** + * Obtains all of the connectors that connect the given port that I expose to the + * capsule that contains me, apart from any that are {@linkplain #exclude() excluded}. + * + * @param portOnPart + * tbe port for which to find connectors + * @return the connectors of the port in the context of my + * {@linkplain #getCapsule() containing capsule} + */ + public List<UMLRTConnector> getConnectorsOf(UMLRTPort portOnPart) { + UMLRTCapsule capsule = getCapsule(); + Predicate<UMLRTConnector> excluded = UMLRTConnector::isExcluded; + + // Get the connectors that are defined within my capsule + return allConnectorsOf(portOnPart) + .map(capsule::getRedefinitionOf) + .filter(Objects::nonNull) + .filter(excluded.negate()) + .distinct() + .collect(collectingAndThen(toList(), Collections::unmodifiableList)); + } + + Stream<UMLRTConnector> allConnectorsOf(UMLRTPort portOnPart) { + CacheAdapter cache = CacheAdapter.getCacheAdapter(toUML()); + + return redefinitionChain().stream() + .map(UMLRTNamedElement::toUML) + .flatMap(e -> cache.getNonNavigableInverseReferences(e).stream()) + .filter(s -> s.getEStructuralFeature() == UMLPackage.Literals.CONNECTOR_END__PART_WITH_PORT) + .map(EStructuralFeature.Setting::getEObject) + .map(ConnectorEnd.class::cast) + .filter(end -> redefines(end.getRole(), portOnPart)) + .map(Element::getOwner) + .map(Connector.class::cast) + .map(UMLRTConnector::getInstance) + .filter(Objects::nonNull); + } + + private static boolean redefines(ConnectableElement role, UMLRTPort port) { + UMLRTPort rtRole = (role instanceof Port) ? UMLRTPort.getInstance((Port) role) : null; + return (rtRole != null) && rtRole.redefines(port); + } + + Stream<UMLRTCapsulePart> allRedefinitions() { + Predicate<UMLRTCapsulePart> excluded = UMLRTCapsulePart::isExcluded; + UMLRTCapsule capsule = getCapsule(); + return (capsule == null) ? Stream.empty() : capsule.getHierarchy() + .map(c -> c.getRedefinitionOf(this)) + .filter(excluded.negate()); + } + + /** + * Queries the kind of capsule-part that I am. + * + * @return my kind + */ + public UMLRTCapsulePartKind getKind() { + UMLRTCapsulePartKind result = UMLRTCapsulePartKind.NULL; + Property uml = toUML(); + + if ((uml.getLower()) > 0 && (uml.getUpper() > 0)) { + result = UMLRTCapsulePartKind.FIXED; + } else if ((uml.getLower() == 0) || (uml.getUpper() == LiteralUnlimitedNatural.UNLIMITED)) { + if (uml.getAggregation() == AggregationKind.COMPOSITE_LITERAL) { + result = UMLRTCapsulePartKind.OPTIONAL; + } else if (uml.getAggregation() == AggregationKind.SHARED_LITERAL) { + result = UMLRTCapsulePartKind.PLUG_IN; + } + } + + return result; + } + + /** + * Sets the kind of capsule-part that I am. + * + * @param kind + * my new kind + * @throws NullPointerException + * if the {@code kind} is {@code null} + * @throws IllegalArgumentException + * if the {@code kind} is {@link UMLRTCapsulePartKind#isNull() isNull} + */ + public void setKind(UMLRTCapsulePartKind kind) { + if (Objects.requireNonNull(kind, "kind").isNull()) { //$NON-NLS-1$ + throw new IllegalArgumentException(kind.label()); + } + + setOptional(!kind.isRequired()); + if ((toUML().getAggregation() == AggregationKind.COMPOSITE_LITERAL) != kind.isComposite()) { + if (kind.isComposite()) { + toUML().setAggregation(AggregationKind.COMPOSITE_LITERAL); + } else { + toUML().setAggregation(AggregationKind.SHARED_LITERAL); + } + } + } + + /** + * Queries whether I am an optional (or plug-in) part. + * + * @return whether I am optional + */ + public boolean isOptional() { + return toUML().getLower() == 0; + } + + /** + * Sets whether I am an optional part. This does not make me + * a plug-in part if it makes me optional, but does make me + * not a plug-in if it makes me non-optional. + * + * @param optional + * whether I am optional + */ + public void setOptional(boolean optional) { + if (optional != isOptional()) { + if (optional) { + toUML().setLower(0); + } else { + toUML().setLower(getReplicationFactor()); + if (toUML().getAggregation() != AggregationKind.COMPOSITE_LITERAL) { + toUML().setAggregation(AggregationKind.COMPOSITE_LITERAL); + } + } + } + } + + /** + * Queries the inherited capsule-part that I redefine, if any and even if + * I am {@link #isExcluded() excluded} or am the local representation of + * a capsule-part that is inherited as is. + * + * @return the capsule-part that I redefine/inherit, or {@code null} if + * I am a root definition + */ + public UMLRTCapsulePart getRedefinedPart() { + Property superPart = (Property) ((InternalUMLRTElement) toUML()).rtGetRedefinedElement(); + return UMLRTCapsulePart.getInstance(superPart); + } + + @Override + public UMLRTCapsulePart getRedefinedElement() { + return getRedefinedPart(); + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTCapsulePartKind.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTCapsulePartKind.java new file mode 100644 index 000000000..77a52be8a --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTCapsulePartKind.java @@ -0,0 +1,70 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml; + +/** + * Enumeration of UML-RT capsule-part kinds. + */ +public enum UMLRTCapsulePartKind { + FIXED("Fixed", true, true), // + OPTIONAL("Optional", false, true), // + PLUG_IN("Plug-in", false, false), // + NULL("<invalid>", false, false); // + + private final String label; + private final boolean required; + private final boolean composite; + + UMLRTCapsulePartKind(String label, boolean required, boolean composite) { + this.label = label; + this.required = required; + this.composite = composite; + } + + /** + * Obtains my user-presentable label. + * + * @return my label + */ + public String label() { + return label; + } + + /** + * Queries whether I am the {@link #NULL} object. + * + * @return whether I am the null value + */ + public boolean isNull() { + return this == NULL; + } + + /** + * Queries whether I am a kind of required capsule-part. + * + * @return whether capsule-parts of my kind are required + */ + public boolean isRequired() { + return required; + } + + /** + * Queries whether I am a kind of composite capsule-part. + * + * @return whether capsule-parts of my kind are composite + */ + public boolean isComposite() { + return composite; + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTClassifier.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTClassifier.java new file mode 100644 index 000000000..27727f2c6 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTClassifier.java @@ -0,0 +1,161 @@ +/***************************************************************************** + * Copyright (c) 2016, 2017 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml; + +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.toList; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.uml2.uml.Classifier; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.Generalization; + +/** + * A façade for UML {@link Classifier}s that represent UML-RT concepts such as + * capsules and protocols, providing a view of the element more in keeping with + * the UML-RT semantics. + */ +public abstract class UMLRTClassifier extends UMLRTNamedElement { + + UMLRTClassifier(Classifier element, EObject stereotype) { + super(element, stereotype); + } + + static UMLRTClassifier getInstance(Classifier classifier) { + UMLRTNamedElement result = (classifier == null) + ? null + : UMLRTFactory.create(classifier); + return (result instanceof UMLRTClassifier) + ? (UMLRTClassifier) result + : null; + } + + /** + * Obtains the UML classifier that represents me in the UML model. + * + * @return my UML representation + */ + @Override + public Classifier toUML() { + return (Classifier) super.toUML(); + } + + /** + * Obtains the package that logically contains me. Note that for + * protocols, this is not the protocol-container package but that + * container's nesting package. + * + * @return my package + */ + public UMLRTPackage getPackage() { + return UMLRTPackage.getInstance(toUML().getPackage()); + } + + UMLRTClassifier getGeneral() { + EList<Classifier> generals = toUML().getGenerals(); + Classifier result = generals.isEmpty() ? null : generals.get(0); + return UMLRTClassifier.getInstance(result); + } + + void setGeneral(UMLRTClassifier general) { + if (getGeneral() != general) { + setGeneral(toUML(), (general == null) ? null : general.toUML()); + } + } + + static <C extends Classifier> void setGeneral(C specific, C general) { + EList<Classifier> generals = specific.getGenerals(); + if (general == null) { + new ArrayList<>(specific.getGeneralizations()).forEach(Element::destroy); + } else if (generals.isEmpty()) { + generals.add(general); + } else if (generals.get(0) != general) { + generals.set(0, general); + } + } + + /** + * Queries whether I am a supertype of the given {@code classifier}, + * either directly or indirectly. As a special case, I am a supertype + * of myself. + * + * @param classifier + * a classifier + * @return whether it is a subtype of me + */ + public boolean isSuperTypeOf(UMLRTClassifier classifier) { + return (classifier == this) + || Optional.ofNullable(classifier.getGeneral()) + .map(sc -> isSuperTypeOf(sc)).orElse(false); + } + + List<? extends UMLRTClassifier> getSpecifics() { + return getSpecifics(false).collect( + collectingAndThen(toList(), Collections::unmodifiableList)); + } + + Stream<? extends UMLRTClassifier> getSpecifics(boolean recursive) { + Stream<Classifier> specifics = specifics(toUML()); + + if (!recursive) { + // Simple case + return specifics + .map(UMLRTClassifier::getInstance) + .filter(Objects::nonNull); + } else { + // Get the recursive closure + Set<Classifier> allSpecifics = collectSpecificClosure(specifics, new LinkedHashSet<>()); + return allSpecifics.stream() + .map(UMLRTClassifier::getInstance) + .filter(Objects::nonNull); + } + } + + private static Stream<Classifier> specifics(Classifier class_) { + Stream<Generalization> generalizations = class_.getTargetDirectedRelationships().stream() + .filter(Generalization.class::isInstance).map(Generalization.class::cast); + Stream<Classifier> result = generalizations.map(Generalization::getSpecific); + return result; + } + + private static Set<Classifier> collectSpecificClosure(Stream<Classifier> classes, Set<Classifier> result) { + classes.forEach(classifier -> { + if (result.add(classifier)) { + collectSpecificClosure(specifics(classifier), result); + } + }); + return result; + } + + /** + * Gets the entire classifier specialization hierarchy, rooted at myself, + * as a stream. + * + * @return my classifier hierarchy + */ + public Stream<? extends UMLRTClassifier> getHierarchy() { + return Stream.concat(Stream.of(this), getSpecifics(true)); + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTConnector.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTConnector.java new file mode 100644 index 000000000..c021edbcb --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTConnector.java @@ -0,0 +1,278 @@ +/***************************************************************************** + * Copyright (c) 2016, 2017 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTConnector; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.uml2.uml.Connector; +import org.eclipse.uml2.uml.ConnectorEnd; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * A façade for UML {@link Connector} elements that represent UML-RT {@link RTConnector Connector}s, + * providing a view of the element more in keeping with the UML-RT semantics. + */ +public final class UMLRTConnector extends UMLRTNamedElement { + static final FacadeType<Connector, RTConnector, UMLRTConnector> TYPE = new FacadeType<>( + UMLRTConnector.class, + UMLPackage.Literals.CONNECTOR, + UMLRealTimePackage.Literals.RT_CONNECTOR, + UMLRTConnector::getInstance, + UMLRTConnector::getRedefinedConnector, + UMLRTConnector::new); + + UMLRTConnector(RTConnector rtConnector) { + super(rtConnector.getBase_Connector(), rtConnector); + } + + /** + * Obtains the canonical instance of the connector façade for a connector. + * + * @param connector + * a connector in the UML model + * + * @return its connector façade, or {@code null} if the connector is not a valid UML-RT connector + */ + public static UMLRTConnector getInstance(Connector connector) { + return getFacade(connector, TYPE); + } + + /** + * Obtains the UML representation of the connector. + * + * @return the UML representation + */ + @Override + public Connector toUML() { + return (Connector) super.toUML(); + } + + @Override + RTConnector toRT() { + return (RTConnector) super.toRT(); + } + + /** + * Obtains the port that is the connector source (by convention, the first of its + * two connected ports). + * + * @return my source port + */ + public UMLRTPort getSource() { + ConnectorEnd sourceEnd = umlEnd(0); + return resolvePort(sourceEnd); + } + + private UMLRTPort resolvePort(ConnectorEnd end) { + Port uml = (end == null) + ? null + : (end.getRole() instanceof Port) + ? (Port) end.getRole() + : null; + UMLRTPort result = (uml == null) ? null : UMLRTPort.getInstance(uml); + + if ((result != null) && (result.getCapsule() != getCapsule())) { + // Resolve the inherited port in my capsule + UMLRTPort inherited = result; + result = getCapsule().getPorts(true).stream() + .filter(p -> p.redefines(inherited)) + .findAny() + .orElse(result); + } + + return result; + } + + /** + * Obtains the part that has the connector {@link #getSource() source}, if it is + * a port on a part. + * + * @return my source part-with-port, or {@code null} if the source port is a port + * of my {@linkplain #getCapsule() containing capsule} + */ + public UMLRTCapsulePart getSourcePartWithPort() { + ConnectorEnd sourceEnd = umlEnd(0); + return resolvePartWithPort(sourceEnd); + } + + ConnectorEnd umlEnd(int index) { + ConnectorEnd result = null; + EList<ConnectorEnd> ends = toUML().getEnds(); + + if (ends.size() > index) { + result = ends.get(index); + } + + return result; + } + + private UMLRTCapsulePart resolvePartWithPort(ConnectorEnd end) { + UMLRTCapsulePart result = null; + + if ((end != null) && (end.getPartWithPort() != null)) { + result = UMLRTCapsulePart.getInstance(end.getPartWithPort()); + + if ((result != null) && (result.getCapsule() != getCapsule())) { + // Resolve the inherited port in my capsule + UMLRTCapsulePart inherited = result; + result = getCapsule().getCapsuleParts(true).stream() + .filter(p -> p.redefines(inherited)) + .findAny() + .orElse(result); + } + } + + return result; + } + + /** + * Queries whether the replication factor of the connector on the {@link #getSource() source} + * end is symbolic (not a numeric literal). + * + * @return whether my replication factor at the source end is symbolic + */ + public boolean isSourceSymbolicReplicationFactor() { + ConnectorEnd sourceEnd = umlEnd(0); + return UMLRTReplicatedElement.isSymbolicReplicationFactor( + (sourceEnd == null) ? null : sourceEnd.getUpperValue()); + } + + /** + * Queries the replication factor of the connector on the {@link #getSource() source} end. + * + * @return my source-end replication factor, or {@code 1} if my replication + * factor at that end is symbolic + * + * @see #isSourceSymbolicReplicationFactor() + */ + public int getSourceReplicationFactor() { + ConnectorEnd sourceEnd = umlEnd(0); + return UMLRTReplicatedElement.getReplicationFactor( + (sourceEnd == null) ? null : sourceEnd.getUpperValue()); + } + + /** + * Sets the replication factor of the connector on the {@link #getSource() source} end. + * + * @param replication + * the replication factor to set at my source end + */ + public void setSourceReplicationFactor(int replication) { + ConnectorEnd sourceEnd = umlEnd(0); + if (sourceEnd == null) { + throw new IllegalStateException("no source end"); //$NON-NLS-1$ + } + UMLRTReplicatedElement.setReplicationFactor(sourceEnd, replication); + } + + /** + * Obtains the port that is the connector target (by convention, the second of its + * two connected ports). + * + * @return my target port + */ + public UMLRTPort getTarget() { + ConnectorEnd targetEnd = umlEnd(1); + return resolvePort(targetEnd); + } + + /** + * Obtains the part that has the connector {@link #getTarget() target}, if it is + * a port on a part. + * + * @return my target part-with-port, or {@code null} if the target port is a port + * of my {@linkplain #getCapsule() containing capsule} + */ + public UMLRTCapsulePart getTargetPartWithPort() { + ConnectorEnd targetEnd = umlEnd(1); + return resolvePartWithPort(targetEnd); + } + + /** + * Queries whether the replication factor of the connector on the {@link #getTarget() target} + * end is symbolic (not a numeric literal). + * + * @return whether my replication factor at the target end is symbolic + */ + public boolean isTargetSymbolicReplicationFactor() { + ConnectorEnd targetEnd = umlEnd(1); + return UMLRTReplicatedElement.isSymbolicReplicationFactor( + (targetEnd == null) ? null : targetEnd.getUpperValue()); + } + + /** + * Queries the replication factor of the connector on the {@link #getTarget() target} end. + * + * @return my target-end replication factor, or {@code 1} if my replication + * factor at that end is symbolic + * + * @see #isTargetSymbolicReplicationFactor() + */ + public int getTargetReplicationFactor() { + ConnectorEnd targetEnd = umlEnd(1); + return UMLRTReplicatedElement.getReplicationFactor( + (targetEnd == null) ? null : targetEnd.getUpperValue()); + } + + /** + * Sets the replication factor of the connector on the {@link #getTarget() target} end. + * + * @param replication + * the replication factor to set at my target end + */ + public void setTargetReplicationFactor(int replication) { + ConnectorEnd targetEnd = umlEnd(1); + if (targetEnd == null) { + throw new IllegalStateException("no target end"); //$NON-NLS-1$ + } + UMLRTReplicatedElement.setReplicationFactor(targetEnd, replication); + } + + /** + * Obtains the capsule that defines me or inherits me, if I am the façade + * for an inherited connector. + * + * @return my context capsule + */ + public UMLRTCapsule getCapsule() { + return UMLRTCapsule.getInstance((org.eclipse.uml2.uml.Class) toUML().getNamespace()); + } + + /** + * Queries the inherited connector that I redefine, if any and even if + * I am {@link #isExcluded() excluded} or am the local representation of + * a connector that is inherited as is. + * + * @return the connector that I redefine/inherit, or {@code null} if + * I am a root definition + */ + public UMLRTConnector getRedefinedConnector() { + Connector superConnector = (Connector) ((InternalUMLRTElement) toUML()).rtGetRedefinedElement(); + return UMLRTConnector.getInstance(superConnector); + } + + @Override + public UMLRTConnector getRedefinedElement() { + return getRedefinedConnector(); + } + + @Override + public UMLRTNamedElement getRedefinitionContext() { + return getCapsule(); + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTFactory.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTFactory.java new file mode 100644 index 000000000..b206c103c --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTFactory.java @@ -0,0 +1,291 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml; + +import org.eclipse.emf.ecore.util.Switch; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Collaboration; +import org.eclipse.uml2.uml.Connector; +import org.eclipse.uml2.uml.NamedElement; +import org.eclipse.uml2.uml.Operation; +import org.eclipse.uml2.uml.Package; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.util.UMLSwitch; + +/** + * Generic factory for UML-RT façade objects on the UML model representation. + */ +public class UMLRTFactory { + + private static final Switch<? extends UMLRTNamedElement> FACTORY_SWITCH = createFactorySwitch(); + + /** + * Not instantiable by clients. + */ + private UMLRTFactory() { + super(); + } + + /** + * Obtains the façade object for a given {@code element} in the UML + * model. Note that this does not necessarily always create an + * unique instance; façades are cached. + * + * @param element + * an element in the model + * + * @return the {@code element}'s façade, if it has one, otherwise + * {@code null}, in which case it does not have special semantics + * in UML-RT + */ + public static UMLRTNamedElement create(NamedElement element) { + return FACTORY_SWITCH.doSwitch(element); + } + + /** + * Creates a capsule façade. + * + * @param class_ + * a capsule + * @return its façade, or {@code null} if the {@code class_} is not a valid capsule + */ + public static UMLRTCapsule createCapsule(Class class_) { + return UMLRTCapsule.getInstance(class_); + } + + /** + * Creates a protocol façade. + * + * @param collaboration + * a protocol + * @return its façade, or {@code null} if the {@code collaboration} is not a valid protocol + */ + public static UMLRTProtocol createProtocol(Collaboration collaboration) { + return UMLRTProtocol.getInstance(collaboration); + } + + /** + * Creates a port façade. + * + * @param port + * a port + * @return its façade, or {@code null} if the {@code port} is not a valid UML-RT port + */ + public static UMLRTPort createPort(Port port) { + return UMLRTPort.getInstance(port); + } + + /** + * Creates a capsule-part façade. + * + * @param property + * a capsule-part + * @return its façade, or {@code null} if the {@code property} is not a valid capsule-part + */ + public static UMLRTCapsulePart createCapsulePart(Property property) { + return UMLRTCapsulePart.getInstance(property); + } + + /** + * Creates a connector façade. + * + * @param connector + * a connector + * @return its façade, or {@code null} if the {@code connector} is not a valid UML-RT connector + */ + public static UMLRTConnector createConnector(Connector connector) { + return UMLRTConnector.getInstance(connector); + } + + /** + * Creates a protocol message façade. + * + * @param operation + * an operation + * @return its façade, or {@code null} if the {@code operation} is not a valid protocol message + */ + public static UMLRTProtocolMessage createProtocolMessage(Operation operation) { + return UMLRTProtocolMessage.getInstance(operation); + } + + /** + * Creates a package façade. + * + * @param package_ + * a package + * @return its façade, or {@code null} if the {@code package_} is not a valid package, + * for example if it is a protocol container or does not have or inherit an application + * of the UML-RT profile + */ + public static UMLRTPackage createPackage(Package package_) { + return UMLRTPackage.getInstance(package_); + } + + private static Switch<? extends UMLRTNamedElement> createFactorySwitch() { + return new UMLSwitch<UMLRTNamedElement>() { + @Override + public UMLRTNamedElement caseClass(Class object) { + return UMLRTFactory.createCapsule(object); + } + + @Override + public UMLRTNamedElement caseCollaboration(Collaboration object) { + return UMLRTFactory.createProtocol(object); + } + + @Override + public UMLRTNamedElement caseConnector(Connector object) { + return UMLRTFactory.createConnector(object); + } + + @Override + public UMLRTNamedElement casePort(Port object) { + return UMLRTFactory.createPort(object); + } + + @Override + public UMLRTNamedElement caseProperty(Property object) { + return UMLRTFactory.createCapsulePart(object); + } + + @Override + public UMLRTNamedElement caseOperation(Operation object) { + return UMLRTFactory.createProtocolMessage(object); + } + + @Override + public UMLRTNamedElement casePackage(Package object) { + return UMLRTFactory.createPackage(object); + } + }; + } + + // + // Nested types + // + + /** + * A specific factory for creation only of elements of Capsule Structure. That is, + * <ul> + * <li>{@link UMLRTFactory#createCapsule(Class) UMLRTCapsule}</li> + * <li>{@link UMLRTFactory#createPort(Port) UMLRTPort}</li> + * <li>{@link UMLRTFactory#createCapsulePart(Property) UMLRTCapsulePart}</li> + * <li>{@link UMLRTFactory#createConnector(Connector) UMLRTConnector}</li> + * </ul> + */ + public static class CapsuleFactory { + + private static final Switch<? extends UMLRTNamedElement> FACTORY_SWITCH = createFactorySwitch(); + + /** + * Not instantiable by clients. + */ + private CapsuleFactory() { + super(); + } + + /** + * Obtains the façade object for a given {@code element} in the UML + * model. Note that this does not necessarily always create an + * unique instance; façades are cached. + * + * @param element + * an element in the model + * + * @return the {@code element}'s façade, if it has one, otherwise + * {@code null}, in which case it does not have special semantics + * in UML-RT + */ + public static UMLRTNamedElement create(NamedElement element) { + return FACTORY_SWITCH.doSwitch(element); + } + + private static Switch<? extends UMLRTNamedElement> createFactorySwitch() { + return new UMLSwitch<UMLRTNamedElement>() { + @Override + public UMLRTNamedElement caseClass(Class object) { + return UMLRTFactory.createCapsule(object); + } + + @Override + public UMLRTNamedElement caseConnector(Connector object) { + return UMLRTFactory.createConnector(object); + } + + @Override + public UMLRTNamedElement casePort(Port object) { + return UMLRTFactory.createPort(object); + } + + @Override + public UMLRTNamedElement caseProperty(Property object) { + return UMLRTFactory.createCapsulePart(object); + } + }; + } + + } + + /** + * A specific factory for creation only of elements of Protocol Structure. That is, + * <ul> + * <li>{@link UMLRTFactory#createProtocol(Collaboration) UMLRTProtocol}</li> + * <li>{@link UMLRTFactory#createProtocolMessage(Operation) UMLRTProtocolMessage}</li> + * </ul> + */ + public static class ProtocolFactory { + + private static final Switch<? extends UMLRTNamedElement> FACTORY_SWITCH = createFactorySwitch(); + + /** + * Not instantiable by clients. + */ + private ProtocolFactory() { + super(); + } + + /** + * Obtains the façade object for a given {@code element} in the UML + * model. Note that this does not necessarily always create an + * unique instance; façades are cached. + * + * @param element + * an element in the model + * + * @return the {@code element}'s façade, if it has one, otherwise + * {@code null}, in which case it does not have special semantics + * in UML-RT + */ + public static UMLRTNamedElement create(NamedElement element) { + return FACTORY_SWITCH.doSwitch(element); + } + + private static Switch<? extends UMLRTNamedElement> createFactorySwitch() { + return new UMLSwitch<UMLRTNamedElement>() { + @Override + public UMLRTNamedElement caseCollaboration(Collaboration object) { + return UMLRTFactory.createProtocol(object); + } + + @Override + public UMLRTNamedElement caseOperation(Operation object) { + return UMLRTFactory.createProtocolMessage(object); + } + }; + } + + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTModel.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTModel.java new file mode 100644 index 000000000..278ccc00d --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTModel.java @@ -0,0 +1,139 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml; + +import java.util.ArrayList; + +import org.eclipse.emf.common.notify.impl.AdapterImpl; +import org.eclipse.emf.common.util.EList; +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.util.EcoreUtil; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionHolder; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionResource; +import org.eclipse.uml2.uml.Package; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.resource.UMLResource; + +/** + * A façade for UML {@link Package} elements that represent UML-RT packages, + * providing a view of the element more in keeping with the UML-RT semantics. + */ +public class UMLRTModel { + + private final Resource resource; + + UMLRTModel(Resource resource) { + super(); + + this.resource = resource; + + initExtensionExtent(); + } + + /** + * Obtains the canonical instance of the model façade for a resource. + * + * @param resource + * an UML resource containing an UML-RT model + * + * @return its model façade, or {@code null} if the reosurce is not a valid UML-RT resource + */ + public static UMLRTModel getInstance(Resource resource) { + FacadeAdapter adapter = null; + + if (resource instanceof UMLResource) { + adapter = (FacadeAdapter) EcoreUtil.getExistingAdapter(resource, UMLRTModel.class); + if (adapter == null) { + adapter = new UMLRTModel(resource).new FacadeAdapter(); + resource.eAdapters().add(adapter); + } + } + + return (adapter == null) ? null : adapter.getModel(); + } + + private void initExtensionExtent() { + // Ensure that extensions are moved into the the resource set's extension extent + Resource extensionResource = ExtensionHolder.getExtensionExtent(resource); + if (extensionResource != ExtensionResource.SHARED_EXTENT) { + EList<EObject> extensionExtent = extensionResource.getContents(); + // We will be removing objects from this extent + for (EObject next : new ArrayList<>(ExtensionResource.SHARED_EXTENT.getContents())) { + if (next instanceof ExtElement) { + ExtElement extension = (ExtElement) next; + if (extension.getExtendedElement().eResource() == resource) { + // And add it to its proper extent + extensionExtent.add(extension); + } + } + } + } + } + + /** + * Obtains the UML representation of the model. + * + * @return the UML representation + */ + public Resource toUML() { + return resource; + } + + /** + * Obtains the URI of the resource that I represent. + * + * @return my URI + */ + public URI getURI() { + return resource.getURI(); + } + + /** + * Obtains the root package of the model (or sub-model, as the case may be). + * + * @return the root package + */ + public UMLRTPackage getRoot() { + Package result = (Package) EcoreUtil.getObjectByType(resource.getContents(), UMLPackage.Literals.PACKAGE); + return UMLRTPackage.getInstance(result); + } + + @Override + public String toString() { + return String.format("UMLRTModel(uri=%s)", getURI()); //$NON-NLS-1$ + } + + // + // Nested types + // + + private class FacadeAdapter extends AdapterImpl { + FacadeAdapter() { + super(); + } + + UMLRTModel getModel() { + return UMLRTModel.this; + } + + @Override + public boolean isAdapterForType(Object type) { + return type == UMLRTModel.class; + } + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTNamedElement.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTNamedElement.java new file mode 100644 index 000000000..4343ee0df --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTNamedElement.java @@ -0,0 +1,436 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml; + +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.toList; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Stream; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.ReificationAdapter; +import org.eclipse.papyrusrt.umlrt.uml.util.ReificationListener; +import org.eclipse.uml2.common.util.CacheAdapter; +import org.eclipse.uml2.common.util.UML2Util; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.NamedElement; +import org.eclipse.uml2.uml.Namespace; + +/** + * A façade for UML {@link Element}s that represent UML-RT concepts, + * providing a view of the element more in keeping with the UML-RT semantics. + */ +public abstract class UMLRTNamedElement extends FacadeObject { + + UMLRTNamedElement(NamedElement element, EObject stereotype) { + super(element, stereotype); + } + + /** + * Obtains the UML representation of the façade element. + * + * @return the UML representation + */ + @Override + public NamedElement toUML() { + return (NamedElement) super.toUML(); + } + + CacheAdapter getCacheAdapter() { + return CacheAdapter.getCacheAdapter(toUML()); + } + + static Object cacheKey(String key) { + class CacheKey { + private final String name; + + CacheKey(String name) { + this.name = name; + } + + @Override + public boolean equals(Object obj) { + return (obj instanceof CacheKey) + && ((CacheKey) obj).name.equals(name); + } + + @Override + public int hashCode() { + return 37 * name.hashCode(); + } + + @Override + public String toString() { + return String.format("CacheKey(%s)", name); //$NON-NLS-1$ + } + } + + return new CacheKey(key); + } + + /** + * Obtains my name. + * + * @return my name + */ + public String getName() { + return toUML().getName(); + } + + /** + * Sets my name. + * + * @param newName + * my name + */ + public void setName(String newName) { + if (!Objects.equals(getName(), newName)) { + toUML().setName(newName); + } + } + + static String initialLower(String name) { + String result; + + if (UML2Util.isEmpty(name)) { + result = name; + } else { + StringBuilder buf = new StringBuilder(name.length()); + buf.append(Character.toLowerCase(name.charAt(0))); + buf.append(name, 1, name.length()); + result = buf.toString(); + } + + return result; + } + + Optional<InternalUMLRTElement> internal() { + return Optional.of(toUML()) + .filter(InternalUMLRTElement.class::isInstance) + .map(InternalUMLRTElement.class::cast); + } + + /** + * Obtains the model that (recursively) contains me. + * + * @return my maodel + */ + public UMLRTModel getModel() { + return UMLRTModel.getInstance(toUML().eResource()); + } + + /** + * Queries whether I am a redefinition of some inherited element + * in my context namespace, even if I am {@linkplain #isVirtualRedefinition() virtual} + * or {@linkplain #isExcluded() excluded}. + * + * @return whether I am a redefinition of an inherited element + * + * @see #isVirtualRedefinition() + * @see #isExcluded() + */ + public boolean isRedefinition() { + return internal().map(InternalUMLRTElement::rtIsRedefinition).orElse(false); + } + + /** + * Queries whether I am a <em>virtual redefintion</em>, representing + * a local proxy in my context namespace for an element inherited by that + * namespace. A virtual element does not actually exist in the UML(-RT) + * model and therefore cannot be an {@linkplain #isExcluded() exclusion} + * but is necessarily a {@linkplain #isRedefinition() redefinition}. + * Any change made to a virtual definition causes it to be + * {@linkplain #reify() reified}, which changes it into a real redefinition + * that exists in the model. + * + * @return whether I am a virtual redefinition of an inherited element + * + * @see #isRedefinition() + * @see #isExcluded() + * @see #reify() + */ + public boolean isVirtualRedefinition() { + return internal().map(InternalUMLRTElement::rtIsVirtual).orElse(false); + } + + /** + * Queries whether I am a {@linkplain #isRedefinition() redefinition} that + * exists solely to exclude the inherited element from my context namespace. + * + * @return whether I am an exclusion of an inherited element + * + * @see #isRedefinition() + * @see #exclude() + * @see #reinherit() + */ + @Override + public boolean isExcluded() { + boolean result = false; + + NamedElement uml = toUML(); + if (uml instanceof InternalUMLRTElement) { + result = ((InternalUMLRTElement) uml).rtIsExcluded(); + } + + return result; + } + + /** + * Excludes me from my namespace, if I am a + * {@linkplain #isRedefinition() redefinition} + * of an inherited element. + * + * @return {@code true} if I was not excluded before but am after; + * {@code false}, otherwise + * + * @see #isExcluded() + * @see #isRedefinition() + * @see #reinherit() + */ + public boolean exclude() { + boolean result = false; + + NamedElement uml = toUML(); + if (uml instanceof InternalUMLRTElement) { + result = ((InternalUMLRTElement) uml).rtExclude(); + } + + return result; + } + + /** + * Reverses an exclusion, reinstating me in my namespace, if I am + * an {@linkplain #isExcluded() exclusion} of an inherited element. + * + * @return {@code true} if I was excluded before but am not after; + * {@code false}, otherwise + * + * @see #isExcluded() + * @see #isRedefinition() + * @see #exclude() + */ + public boolean reinherit() { + boolean result = false; + + NamedElement uml = toUML(); + if (uml instanceof InternalUMLRTElement) { + result = ((InternalUMLRTElement) uml).rtReinherit(); + } + + return result; + } + + public void reify() { + internal().filter(InternalUMLRTElement::rtIsVirtual) + .ifPresent(InternalUMLRTElement::rtReify); + } + + /** + * Destroys my {@linkplain #toUML() UML representation} and, by + * implication, me. + */ + @Override + public void destroy() { + super.destroy(); + } + + /** + * Queries the element that I redefine, whether that be + * {@linkplain #isVirtualRedefinition() virtual redefinition} or a real element. + * + * @return my immediate redefined element, or {@code null} if I am not a + * {@link #isRedefinition() redefinition} of some element + * + * @see #isRedefinition() + * @see #isVirtualRedefinition() + * @see #getInheritedElement() + */ + public UMLRTNamedElement getRedefinedElement() { + return null; + } + + /** + * Obtains my redefinition context, which is the namespace containing me + * that supports generalization or redefinition, in which context I may + * redefine some inherited element. + * + * @return my redefinition context, or {@code null} if I am not a redefinable + * element or I my owner is not suitable for redefinition + */ + public UMLRTNamedElement getRedefinitionContext() { + return null; + } + + /** + * Queries the element whose attributes I inherit for redefinition. + * In contrast to the {@linkplain #getRedefinedElement() redefined element}, + * this is a real element, either the {@linkplain #getRootDefinition() root} + * of my redefinition chain or else a real redefinition of some further + * inherited element. + * + * @return the real inherited element that I redefined, or {@code null} + * if I am not a {@link #isRedefinition() redefinition} of some element + * + * @see #isRedefinition() + * @see #getRedefinedElement() + */ + public UMLRTNamedElement getInheritedElement() { + UMLRTNamedElement result = getRedefinedElement(); + + if ((result != null) && result.isVirtualRedefinition()) { + result = result.getInheritedElement(); + } + + return result; + } + + /** + * Queries the root of my redefinition chain, which in the simples case is + * myself if I am a root definition, otherwise the root definition of my + * {@link #getRedefinedElement() redefined element, recursively. + * + * @return the real inherited element that I redefined, or {@code null} + * if I am not a {@link #isRedefinition() redefinition} of some element + * + * @see #isRedefinition() + * @see #getRedefinedElement() + * @see #getInheritedElement() + */ + public UMLRTNamedElement getRootDefinition() { + // Start with the assumption that I am the root + UMLRTNamedElement result = this; + + for (UMLRTNamedElement inh = result.getInheritedElement(); (inh != null); inh = result.getInheritedElement()) { + result = inh; + } + + return result; + } + + /** + * Queries whether I redefine the given {@code element} or some + * other element that, recursively, redefines it. As a trivial + * case, I redefine myself. + * + * @param element + * an element + * @return whether I am a redefinition of the {@code element} + */ + public boolean redefines(UMLRTNamedElement element) { + boolean result = false; + + for (UMLRTNamedElement redefined = this; !result && (redefined != null); redefined = redefined.getRedefinedElement()) { + result = redefined == element; + } + + return result; + } + + /** + * Obtains the chain of redefinitions from myself to the root definition. + * Note that this always includes at least myself, even if I am a root definition. + * + * @return my redefinition chain + */ + List<UMLRTNamedElement> redefinitionChain() { + List<UMLRTNamedElement> result; + + UMLRTNamedElement redef = getRedefinedElement(); + + if (redef == null) { + result = Collections.singletonList(this); + } else { + result = new ArrayList<>(3); + result.add(this); + for (; redef != null; redef = redef.getRedefinedElement()) { + result.add(redef); + } + } + + return result; + } + + Stream<UMLRTNamedElement> excludedElements() { + Stream<UMLRTNamedElement> result = Stream.empty(); + + NamedElement uml = toUML(); + if ((uml instanceof Namespace) && (uml instanceof InternalUMLRTElement)) { + @SuppressWarnings("unchecked") + List<NamedElement> exclusions = (List<NamedElement>) uml.eGet(ExtUMLExtPackage.Literals.NAMESPACE__EXCLUDED_MEMBER); + result = exclusions.stream() + .map(UMLRTFactory::create) + .filter(Objects::nonNull); + } + + return result; + } + + List<UMLRTNamedElement> getExcludedElements() { + return excludedElements().collect( + collectingAndThen(toList(), Collections::unmodifiableList)); + } + + <T extends UMLRTNamedElement> T getExcludedElement(String name, Class<T> facadeType) { + return excludedElements() + .filter(facadeType::isInstance) + .filter(e -> Objects.equals(e.getName(), name)) + .map(facadeType::cast) + .findAny().orElse(null); + } + + + /** + * Adds a reification {@code listener}. Has no effect if this listener + * was already added previously. + * + * @param listener + * the listener to receive notifications when I am reified + * or virtualized + */ + public void addReificationListener(ReificationListener listener) { + NamedElement element = toUML(); + ReificationAdapter adapter = ReificationAdapter.getInstance(element); + if (adapter != null) { + adapter.addListener(element, listener); + } + } + + /** + * Removes a reification {@code listener}. Has no effect if this listener + * was not added previously. + * + * @param listener + * the listener to remove + */ + public void removeReificationListener(ReificationListener listener) { + NamedElement element = toUML(); + ReificationAdapter adapter = ReificationAdapter.getInstance(element); + if (adapter != null) { + adapter.removeListener(element, listener); + } + } + + @Override + public String toString() { + return String.format("%s(name=%s)", getClass().getSimpleName(), getName()); //$NON-NLS-1$ + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTPackage.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTPackage.java new file mode 100644 index 000000000..7bce31922 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTPackage.java @@ -0,0 +1,240 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.Capsule; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.ProtocolContainer; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Collaboration; +import org.eclipse.uml2.uml.Package; +import org.eclipse.uml2.uml.Profile; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.util.UMLUtil; +import org.eclipse.uml2.uml.util.UMLUtil.StereotypeApplicationHelper; + +/** + * A façade for UML {@link Package} elements that represent UML-RT packages, + * providing a view of the element more in keeping with the UML-RT semantics. + */ +public class UMLRTPackage extends UMLRTNamedElement { + static final FacadeType<Package, EObject, UMLRTPackage> TYPE = new FacadeType<>( + UMLRTPackage.class, + UMLPackage.Literals.PACKAGE, + null, + UMLRTPackage::getInstance, + null, + BasicFacadeAdapter.class, + null); + + private static final FacadeReference<Class, Capsule, UMLRTCapsule> CAPSULE_REFERENCE = new FacadeReference<>( + UMLRTCapsule.TYPE, + UMLPackage.Literals.PACKAGE__OWNED_TYPE, + null, + UMLPackage.Literals.CLASS); + + private static final FacadeReference<Package, EObject, UMLRTPackage> NESTED_PACKAGE_REFERENCE = new FacadeReference<>( + UMLRTPackage.TYPE, + UMLPackage.Literals.PACKAGE__NESTED_PACKAGE, + null, + UMLPackage.Literals.PACKAGE); + + UMLRTPackage(Package package_) { + super(package_, null); + } + + /** + * Obtains the canonical instance of the package façade for a package. + * + * @param package_ + * a package in the UML model + * + * @return its package façade, or {@code null} if the package is not a valid UML-RT package + * (for example, if it is a protocol-container package or does not + * have or inherit an application of the UML-RT profile) + */ + public static UMLRTPackage getInstance(Package package_) { + BasicFacadeAdapter<UMLRTPackage> adapter = null; + + if ((package_ instanceof InternalUMLRTElement) && isRTPackage(package_)) { + adapter = TYPE.getAdapter(package_); + if ((adapter == null) && !isProtocolContainer(package_)) { + adapter = new UMLRTPackage(package_).new BasicFacadeAdapter<>(); + package_.eAdapters().add(adapter); + } + } + + return (adapter == null) ? null : adapter.getFacade(); + } + + static boolean isRTPackage(Package package_) { + return !(package_ instanceof Profile) + && (package_.getAppliedProfile("UMLRealTime", true) != null); + } + + static boolean isProtocolContainer(Package package_) { + return getProtocolContainer(package_) != null; + } + + static ProtocolContainer getProtocolContainer(Package package_) { + return UMLUtil.getStereotypeApplication(package_, ProtocolContainer.class); + } + + static Collaboration getProtocol(Package protocolContainer) { + return (Collaboration) protocolContainer.getMember( + protocolContainer.getName(), false, UMLPackage.Literals.COLLABORATION); + } + + /** + * Obtains the UML representation of the connector. + * + * @return the UML representation + */ + @Override + public Package toUML() { + return (Package) super.toUML(); + } + + /** + * Queries the capsules that are defined in my namespace. + * + * @return the capsules that I contain + */ + public List<UMLRTCapsule> getCapsules() { + return getFacades(CAPSULE_REFERENCE); + } + + /** + * Creates a new capsule in my namespace. + * + * @param name + * the new capsule name + * @return the new capsule + */ + public UMLRTCapsule createCapsule(String name) { + UMLRTCapsule result = create(CAPSULE_REFERENCE, name); + result.toUML().setIsActive(true); + return result; + } + + /** + * Obtains the {@code name}d capsule within my namespace. + * + * @param name + * the capsule name to find + * @return the capsule, or {@code null} if I have none of that name + */ + public UMLRTCapsule getCapsule(String name) { + return get(CAPSULE_REFERENCE, name); + } + + /** + * Queries the nested packages that are defined in my namespace. + * These do not include protocol-container packages, which exist + * only to group the disparate constructs that comprise a logical + * protocol. + * + * @return the packages that I contain + */ + public List<UMLRTPackage> getNestedPackages() { + return getFacades(NESTED_PACKAGE_REFERENCE); + } + + /** + * Creates a new package in my namespace. + * + * @param name + * the new package name + * @return the new package + */ + public UMLRTPackage createNestedPackage(String name) { + return create(NESTED_PACKAGE_REFERENCE, name); + } + + /** + * Obtains the {@code name}d package within my namespace. + * + * @param name + * the package name to find + * @return the package, or {@code null} if I have none of that name + */ + public UMLRTPackage getNestedPackage(String name) { + return get(NESTED_PACKAGE_REFERENCE, name); + } + + /** + * Queries the protocols that are defined in my namespace. + * This accounts for the UML structure that defines protocol-container + * packages to contain the protocols. + * + * @return the protocols that I contain + */ + public List<UMLRTProtocol> getProtocols() { + return toUML().getNestedPackages().stream() + .filter(UMLRTPackage::isProtocolContainer) + .map(UMLRTPackage::getProtocol) + .map(UMLRTProtocol::getInstance) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + + /** + * Obtains the {@code name}d protocol within my namespace. + * + * @param name + * the protocol name to find + * @return the protocol, or {@code null} if I have none of that name + */ + public UMLRTProtocol getProtocol(String name) { + Package container = toUML().getNestedPackage(name); + Collaboration result = ((container != null) && isProtocolContainer(container)) + ? getProtocol(container) + : null; + return UMLRTProtocol.getInstance(result); + } + + /** + * Creates a new protocol in my namespace. This ensures creation of the + * entire protocol structure in the UML representation, including the + * protocol-container package, the protocol collaboration, the message-set + * interfaces, their relationships to the protocol collaboration, and the + * any-receive-event. + * + * @param name + * the new protocol name + * @return the new protocol + */ + public UMLRTProtocol createProtocol(String name) { + // Protocol container + Package protocolContainer = toUML().createNestedPackage(name); + StereotypeApplicationHelper.getInstance(protocolContainer).applyStereotype(protocolContainer, UMLRealTimePackage.Literals.PROTOCOL_CONTAINER); + + // Protocol collaboration + Collaboration result = (Collaboration) protocolContainer.createOwnedType(name, UMLPackage.Literals.COLLABORATION); + result.setName(name); + UMLRTProtocol.TYPE.applyStereotype(result); + + return Optional.ofNullable(UMLRTProtocol.getInstance(result)) + .map(UMLRTProtocol::initContents) + .orElse(null); + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTPort.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTPort.java new file mode 100644 index 000000000..cb4ba3169 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTPort.java @@ -0,0 +1,623 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml; + +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.toList; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.function.Predicate; +import java.util.stream.Stream; + +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.PortRegistrationType; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTPort; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.uml2.common.util.CacheAdapter; +import org.eclipse.uml2.uml.Collaboration; +import org.eclipse.uml2.uml.Connector; +import org.eclipse.uml2.uml.ConnectorEnd; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.Type; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.VisibilityKind; + +/** + * A façade for UML {@link Port} elements that represent UML-RT {@link RTPort Port}s, + * providing a view of the element more in keeping with the UML-RT semantics. + */ +public final class UMLRTPort extends UMLRTReplicatedElement { + static final FacadeType<Port, RTPort, UMLRTPort> TYPE = new FacadeType<>( + UMLRTPort.class, + UMLPackage.Literals.PORT, + UMLRealTimePackage.Literals.RT_PORT, + UMLRTPort::getInstance, + UMLRTPort::getRedefinedPort, + UMLRTPort::new); + + private static final Object INSIDE_CONNECTORS_KEY = cacheKey("insideConnectors"); + private static final Object OUTSIDE_CONNECTORS_KEY = cacheKey("outsideConnectors"); + private static final Object IS_CONNECTED_INSIDE_KEY = cacheKey("isConnectedInside"); + private static final Object IS_CONNECTED_OUTSIDE_KEY = cacheKey("isConnectedOutside"); + private static final Object IS_CONNECTED_KEY = cacheKey("isConnected"); + + UMLRTPort(RTPort rtPort) { + super(rtPort.getBase_Port(), rtPort); + } + + /** + * Obtains the canonical instance of the port façade for a port. + * + * @param port + * a port in the UML model + * + * @return its port façade, or {@code null} if the port is not a valid UML-RT port + */ + public static UMLRTPort getInstance(Port port) { + return getFacade(port, TYPE); + } + + /** + * Obtains the UML representation of the port. + * + * @return the UML representation + */ + @Override + public Port toUML() { + return (Port) super.toUML(); + } + + @Override + RTPort toRT() { + return (RTPort) super.toRT(); + } + + /** + * Obtains my type with matching conjugation: the + * {@link UMLRTProtocol#getConjugate() conjugate} protocol if I am + * {@link #isConjugated() conjugated}. + * + * @return my protocol type, accounting for conjugation + * + * @see #isConjugated() + * @see UMLRTProtocol#getConjugate() + */ + public UMLRTProtocol getType() { + Type result = toUML().getType(); + return (result instanceof Collaboration) ? UMLRTProtocol.getInstance((Collaboration) result, isConjugated()) + : null; + } + + /** + * Assigns my type with conjugation, so that my own + * conjugation will be aligned with the protocol's, + * if it is not {@code null}. + * + * @param type + * my protocol type, accounting for conjugation + * + * @see #getType() + * @see #setType(UMLRTProtocol) + * @see #setConjugated(boolean) + */ + public void setType(UMLRTProtocol type) { + if (type == null) { + toUML().setType(null); + } else { + toUML().setType(type.toUML()); + setConjugated(type.isConjugate()); + } + } + + /** + * Queries whether I have any {@linkplain #getInsideConnectors() <em>inside</em> connectors}. + * + * @return whether I am connected on the inside + * + * @see #getInsideConnectors() + */ + public boolean isConnectedInside() { + boolean result; + CacheAdapter cache = getCacheAdapter(); + + if (cache == null) { + result = insideConnectors().findAny().isPresent(); + } else { + Boolean cached = (Boolean) cache.get(toUML(), IS_CONNECTED_INSIDE_KEY); + if (cached == null) { + cached = insideConnectors().findAny().isPresent(); + cache.put(toUML(), IS_CONNECTED_INSIDE_KEY, cached); + } + result = cached; + } + + return result; + } + + /** + * Obtains all of the connectors of this port <em>inside</em> of its + * {@link #getCapsule() capsule}. + * + * @return the inside connectors of the port + * + * @see #getCapsule() + * @see #getOutsideConnectors() + * @see #getPartsWithPort() + */ + public List<UMLRTConnector> getInsideConnectors() { + List<UMLRTConnector> result; + CacheAdapter cache = getCacheAdapter(); + + if (cache == null) { + // Get the connectors that are defined within my capsule + result = insideConnectors().collect( + collectingAndThen(toList(), Collections::unmodifiableList)); + } else { + @SuppressWarnings("unchecked") + List<UMLRTConnector> cached = (List<UMLRTConnector>) cache.get(toUML(), INSIDE_CONNECTORS_KEY); + if (cached == null) { + cached = insideConnectors().collect( + collectingAndThen(toList(), Collections::unmodifiableList)); + cache.put(toUML(), INSIDE_CONNECTORS_KEY, cached); + } + result = cached; + } + + return result; + } + + /** + * Queries whether I have any connectors, whether + * {@linkplain #getInsideConnectors() <em>inside</em>} or + * {@linkplain #getOutsideConnectors() <em>inside</em>}. + * + * @return whether I am connected, either on the inside or the outside, or both + * + * @see #getInsideConnectors() + * @see #getOutsideConnectors() + */ + public boolean isConnected() { + boolean result; + CacheAdapter cache = getCacheAdapter(); + + if (cache == null) { + result = isConnectedInside() || isConnectedOutside(); + } else { + Boolean cached = (Boolean) cache.get(toUML(), IS_CONNECTED_KEY); + if (cached == null) { + cached = isConnectedInside() || isConnectedOutside(); + cache.put(toUML(), IS_CONNECTED_KEY, cached); + } + result = cached; + } + + return result; + } + + Stream<UMLRTConnector> insideConnectors() { + UMLRTCapsule capsule = getCapsule(); + Predicate<UMLRTConnector> excluded = UMLRTConnector::isExcluded; + + return allConnectors() + .map(capsule::getRedefinitionOf) + .filter(Objects::nonNull) + .filter(excluded.negate()) + .distinct(); + } + + Stream<UMLRTConnector> allConnectors() { + return redefinitionChain().stream() + .map(UMLRTPort.class::cast) + .flatMap(UMLRTPort::getEnds) + .map(Element::getOwner) + .map(Connector.class::cast) + .map(UMLRTConnector::getInstance) + .filter(Objects::nonNull); + } + + Stream<ConnectorEnd> getEnds() { + return toUML().getEnds().stream(); + } + + /** + * Queries whether I have any {@linkplain #getOutsideConnectors() <em>outside</em> connectors}. + * + * @return whether I am connected on the outside + * + * @see #getOutsideConnectors() + */ + public boolean isConnectedOutside() { + boolean result; + CacheAdapter cache = getCacheAdapter(); + + if (cache == null) { + result = outsideConnectors().findAny().isPresent(); + } else { + Boolean cached = (Boolean) cache.get(toUML(), IS_CONNECTED_OUTSIDE_KEY); + if (cached == null) { + cached = outsideConnectors().findAny().isPresent(); + cache.put(toUML(), IS_CONNECTED_OUTSIDE_KEY, cached); + } + result = cached; + } + + return result; + } + + /** + * Obtains all of the connectors of this port <em>outside</em> of its + * {@link #getCapsule() capsule}. + * + * @return the outside connectors of the port + * + * @see #getCapsule() + * @see #getInsideConnectors() + * @see #getPartsWithPort() + */ + public List<UMLRTConnector> getOutsideConnectors() { + List<UMLRTConnector> result; + CacheAdapter cache = getCacheAdapter(); + + if (cache == null) { + // Get the connectors that are defined without my capsule + result = outsideConnectors().collect( + collectingAndThen(toList(), Collections::unmodifiableList)); + } else { + @SuppressWarnings("unchecked") + List<UMLRTConnector> cached = (List<UMLRTConnector>) cache.get(toUML(), OUTSIDE_CONNECTORS_KEY); + if (cached == null) { + cached = outsideConnectors().collect( + collectingAndThen(toList(), Collections::unmodifiableList)); + cache.put(toUML(), OUTSIDE_CONNECTORS_KEY, cached); + } + result = cached; + } + + return result; + } + + Stream<UMLRTConnector> outsideConnectors() { + return getPartsWithPort().stream() + .flatMap(part -> part.getConnectorsOf(this).stream()) + .distinct(); + } + + /** + * Obtains all of the capsule-parts that feature this port. + * + * @return the parts that have this port + */ + public List<UMLRTCapsulePart> getPartsWithPort() { + Predicate<UMLRTCapsulePart> excluded = UMLRTCapsulePart::isExcluded; + + // Get the connectors that are defined within my capsule + return allPartsWithPort() + .filter(excluded.negate()) + .distinct() + .collect(collectingAndThen(toList(), Collections::unmodifiableList)); + } + + Stream<UMLRTPort> allRedefinitions() { + Predicate<UMLRTPort> excluded = UMLRTPort::isExcluded; + UMLRTCapsule capsule = getCapsule(); + return (capsule == null) ? Stream.empty() : capsule.getHierarchy() + .map(c -> c.getRedefinitionOf(this)) + .filter(excluded.negate()); + } + + Stream<UMLRTCapsulePart> allPartsWithPort() { + CacheAdapter cache = CacheAdapter.getCacheAdapter(toUML()); + + return allRedefinitions() + .map(UMLRTPort::getCapsule) + .map(UMLRTNamedElement::toUML) + .flatMap(e -> cache.getNonNavigableInverseReferences(e).stream()) + .filter(s -> s.getEStructuralFeature() == UMLPackage.Literals.TYPED_ELEMENT__TYPE) + .map(EStructuralFeature.Setting::getEObject) + .filter(Property.class::isInstance).map(Property.class::cast) + .map(UMLRTCapsulePart::getInstance) + .filter(Objects::nonNull) + .flatMap(UMLRTCapsulePart::allRedefinitions) + .distinct(); + } + + /** + * Queries whether I am conjugated, in which case my protocol + * {@link #getType() type} should perhaps also be viewed in its + * conjugated form. + * + * @return whether I am conjugated + * + * @see #getType() + * @see #getConjugationType() + * @see UMLRTProtocol#getConjugate() + */ + public boolean isConjugated() { + return toUML().isConjugated(); + } + + /** + * Assigns my conjugation. + * + * @param conjugated + * whether I am a conjugate port + */ + public void setConjugated(boolean conjugated) { + toUML().setIsConjugated(conjugated); + } + + /** + * Queries whether I have notification enabled. + * + * @return whether I have notification enabled + */ + public boolean isNotification() { + return toRT().isNotification(); + } + + /** + * Sets whether I have notification enabled. + * + * @param notification + * whether I have notification enabled + */ + public void setNotification(boolean notification) { + toRT().setIsNotification(notification); + } + + /** + * Queries whether I am a behavior port. + * + * @return whether I am a behavior port + */ + public boolean isBehavior() { + return toUML().isBehavior(); + } + + /** + * Sets whether I am a behavior port. + * + * @param behavior + * whether I am a behavior port + */ + public void setBehavior(boolean behavior) { + toUML().setIsBehavior(behavior); + } + + /** + * Queries whether I am a service port. + * + * @return whether I am a service port + */ + public boolean isService() { + return toUML().isService(); + } + + /** + * Sets whether I am a service port. + * + * @param behavior + * whether I am a service port + */ + public void setService(boolean service) { + toUML().setIsService(service); + } + + /** + * Queries whether I am a wired port. + * + * @return whether I am a wired port + */ + public boolean isWired() { + return toRT().isWired(); + } + + /** + * Sets whether I am a wired port. + * + * @param behavior + * whether I am a wired port + */ + public void setWired(boolean wired) { + toRT().setIsWired(wired); + } + + /** + * Queries whether I am a published port. + * + * @return whether I am a published port + */ + public boolean isPublish() { + return toRT().isPublish(); + } + + /** + * Sets whether I am a published port. + * + * @param behavior + * whether I am a published port + */ + public void setPublish(boolean publish) { + toRT().setIsPublish(publish); + } + + /** + * Queries my registration kind. + * + * @return my registration kind + */ + public PortRegistrationType getRegistration() { + return toRT().getRegistration(); + } + + /** + * Sets my registration kind. + * + * @param registration + * my registration kind + */ + public void setRegistration(PortRegistrationType registration) { + toRT().setRegistration(registration); + } + + /** + * Queries my registration override. + * + * @return my registration override + */ + public String getRegistrationOverride() { + return toRT().getRegistrationOverride(); + } + + /** + * Sets my registration override. + * + * @param registrationOverride + * my registration override + */ + public void setRegistrationOverride(String registrationOverride) { + toRT().setRegistrationOverride(registrationOverride); + } + + /** + * Queries the kind of port that I am. + * + * @return my port kind, or {@link UMLRTPortKind#NULL NULL} if my properties are + * configured inconsistently and my kind is consequently indeterminate + */ + public UMLRTPortKind getKind() { + UMLRTPortKind result = UMLRTPortKind.NULL; + + if (isService() && isWired() && isBehavior() && !isPublish()) { + result = UMLRTPortKind.EXTERNAL_BEHAVIOR; + } else if (isBehavior() && isPublish() && !isWired()) { + result = UMLRTPortKind.SPP; // isService won't be checked here => Cf. bug 477033 + } else if (isWired() && isBehavior() && !isService() && !isPublish()) { + result = UMLRTPortKind.INTERNAL_BEHAVIOR; + } else if (isService() && isWired() && !isBehavior() && !isPublish()) { + result = UMLRTPortKind.RELAY; + } else if (isBehavior() && !isWired() && !isPublish()) { + result = UMLRTPortKind.SAP;// isService won't be checked here => Cf. bug 477033 + } + + return result; + } + + /** + * Assings my port kind. This will have side-effects in various + * attributes such as {@link #setService(boolean) isService}, + * {@link #setBehavior(boolean) isBehavior}, + * {@link #setWired(boolean) isWired}, and + * {@link #setPublish(boolean) isPublish}. + * + * @param kind + * my new port kind + * + * @throws NullPointerException + * if the {@code kind} is {@code null} + * @throws IllegalArgumentException + * if the {@code kind} is {@link UMLRTPortKind#isNull() isNull} + */ + public void setKind(UMLRTPortKind kind) { + if (Objects.requireNonNull(kind, "kind").isNull()) { //$NON-NLS-1$ + throw new IllegalArgumentException(kind.label()); + } + + switch (kind) { + case EXTERNAL_BEHAVIOR: + setService(true); + setWired(true); + setBehavior(true); + setPublish(false); + toUML().setVisibility(VisibilityKind.PUBLIC_LITERAL); + break; + case INTERNAL_BEHAVIOR: + setService(false); + setWired(true); + setBehavior(true); + setPublish(false); + toUML().setVisibility(VisibilityKind.PROTECTED_LITERAL); + break; + case RELAY: + setService(true); + setWired(true); + setBehavior(false); + setPublish(false); + toUML().setVisibility(VisibilityKind.PUBLIC_LITERAL); + break; + case SAP: + setService(false); + setWired(false); + setBehavior(true); + setPublish(false); + toUML().setVisibility(VisibilityKind.PROTECTED_LITERAL); + break; + case SPP: + setService(true); + setWired(false); + setBehavior(true); + setPublish(true); + toUML().setVisibility(VisibilityKind.PUBLIC_LITERAL); + break; + default: + throw new IllegalArgumentException("invalid port kind: " + kind); //$NON-NLS-1$ + } + } + + /** + * Queries whether I am of an external port kind. + * + * @return whether I am an external port kind + * + * @see UMLRTPortKind#isExternal() + */ + public boolean isExternal() { + return getKind().isExternal(); + } + + /** + * Queries whether I am of an internal port kind. + * + * @return whether I am an internal port kind + * + * @see UMLRTPortKind#isInternal() + */ + public boolean isInternal() { + return getKind().isInternal(); + } + + /** + * Queries the inherited port that I redefine, if any and even if + * I am {@link #isExcluded() excluded} or am the local representation of + * a port that is inherited as is. + * + * @return the port that I redefine/inherit, or {@code null} if + * I am a root definition + */ + public UMLRTPort getRedefinedPort() { + Port superPort = (Port) ((InternalUMLRTElement) toUML()).rtGetRedefinedElement(); + return UMLRTPort.getInstance(superPort); + } + + @Override + public UMLRTPort getRedefinedElement() { + return getRedefinedPort(); + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTPortKind.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTPortKind.java new file mode 100644 index 000000000..967c6cc50 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTPortKind.java @@ -0,0 +1,116 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml; + +/** + * Enumeration of UML-RT port kinds. + */ +public enum UMLRTPortKind { + EXTERNAL_BEHAVIOR("External Behavior", true, true, true, false), // + INTERNAL_BEHAVIOR("Internal Behavior", false, true, true, false), // + RELAY("Relay", true, false, true, false), // + SAP("SAP", false, true, false, false), // + SPP("SPP", true, true, false, true), // + NULL("<invalid>", false, false, false, false); // + + private final String label; + private final boolean external; + private final boolean behavior; + private final boolean wired; + private final boolean publish; + + UMLRTPortKind(String label, boolean external, boolean behavior, boolean wired, boolean publish) { + this.label = label; + this.external = external; + this.behavior = behavior; + this.wired = wired; + this.publish = publish; + } + + /** + * Obtains my user-presentable label. + * + * @return my label + */ + public String label() { + return label; + } + + /** + * Queries whether I am the {@link #NULL} object. + * + * @return whether I am the null value + */ + public boolean isNull() { + return this == NULL; + } + + /** + * Queries whether I am a kind of an external-facing port. + * The {@link #NULL} kind is neither external nor internal. + * + * @return whether ports of my kind are external facing + */ + public boolean isExternal() { + return external && (this != NULL); + } + + /** + * Queries whether I am a kind of an internal-facing port. + * The {@link #NULL} kind is neither internal nor external. + * + * @return whether ports of my kind are internal facing + */ + public boolean isInternal() { + return !external && (this != NULL); + } + + /** + * Queries whether I am a kind of a wired port. + * The {@link #NULL} kind is neither wired nor non-wired. + * + * @return whether ports of my kind are wired + */ + public boolean isWired() { + return wired && (this != NULL); + } + + /** + * Queries whether I am a kind of a non-wired port. + * The {@link #NULL} kind is neither non-wired nor wired. + * + * @return whether ports of my kind are unwired + */ + public boolean isUnwired() { + return !wired && (this != NULL); + } + + /** + * Queries whether I am a kind of a behaviour port. + * + * @return whether ports of my kind are behaviour ports + */ + public boolean isBehavior() { + return behavior; + } + + /** + * Queries whether I am a kind of a published port. + * + * @return whether ports of my kind are published + */ + public boolean isPublish() { + return publish; + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTProtocol.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTProtocol.java new file mode 100644 index 000000000..f39bc6408 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTProtocol.java @@ -0,0 +1,555 @@ +/***************************************************************************** + * Copyright (c) 2016, 2017 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml; + +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.toList; + +import java.util.Collections; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Supplier; +import java.util.function.UnaryOperator; +import java.util.stream.Stream; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.Protocol; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTMessageKind; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTMessageSet; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.CachedReference; +import org.eclipse.uml2.uml.Collaboration; +import org.eclipse.uml2.uml.Interface; +import org.eclipse.uml2.uml.Operation; +import org.eclipse.uml2.uml.Package; +import org.eclipse.uml2.uml.Type; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.util.UMLUtil; +import org.eclipse.uml2.uml.util.UMLUtil.StereotypeApplicationHelper; + +/** + * A façade for UML {@link Collaboration} elements that represent UML-RT {@link Protocol}s, + * providing a view of the element more in keeping with the UML-RT semantics. + */ +public final class UMLRTProtocol extends UMLRTClassifier { + static final FacadeType<Collaboration, Protocol, UMLRTProtocol> TYPE = new FacadeType<>( + UMLRTProtocol.class, + UMLPackage.Literals.COLLABORATION, + UMLRealTimePackage.Literals.PROTOCOL, + UMLRTProtocol::getInstance, + UMLRTProtocol::getSuperProtocol, + UMLRTProtocol::new); + + private static final Map<RTMessageKind, FacadeReference<Operation, EObject, UMLRTProtocolMessage>> MESSAGE_REFERENCES; + + private final boolean isConjugate; + private final Supplier<UMLRTProtocol> conjugate; + + static { + MESSAGE_REFERENCES = new EnumMap<>(RTMessageKind.class); + RTMessageKind.VALUES.forEach(kind -> MESSAGE_REFERENCES.put(kind, + new FacadeReference.Indirect<>( + UMLRTProtocolMessage.TYPE, + UMLPackage.Literals.INTERFACE__OWNED_OPERATION, + ExtUMLExtPackage.Literals.INTERFACE__IMPLICIT_OPERATION, + UMLPackage.Literals.OPERATION, + protocol -> requireMessageSet((Collaboration) protocol, kind)))); + } + + UMLRTProtocol(Protocol protocol) { + super(protocol.getBase_Collaboration(), protocol); + + this.isConjugate = false; + this.conjugate = new CachedReference<>(() -> new UMLRTProtocol(this)); + } + + private UMLRTProtocol(UMLRTProtocol base) { + super(base.toUML(), base.toRT()); + + this.isConjugate = true; + this.conjugate = () -> base; // The base has a hard ref from the model anyways + } + + /** + * Obtains the protocol façade for the base protocol type represented by the given + * UML collaboration. + * + * @param protocol + * a UML collaboration representing a protocol + * @return the base UML-RT protocol façade, or {@code null} if the collaboration + * is not actually a protocol + */ + public static UMLRTProtocol getInstance(Collaboration protocol) { + return getFacade(protocol, TYPE); + } + + /** + * Obtains the protocol façade of the given conjugation for a UML collaboration. + * + * @param protocol + * a UML collaboration representing a protocol + * @param conjugate + * {@code true} to obtain the conjugate protocol type; {@code false} + * for the base protocol type + * + * @return the protocol type, or {@code null} if the UML collaboration is not a protocol + */ + public static UMLRTProtocol getInstance(Collaboration protocol, boolean conjugate) { + UMLRTProtocol result = getFacade(protocol, TYPE); + return (conjugate && (result != null)) ? result.getConjugate() : result; + } + + /** + * Obtains the UML representation of the protocol. + * + * @return the UML representation + */ + @Override + public Collaboration toUML() { + return (Collaboration) super.toUML(); + } + + @Override + Protocol toRT() { + return (Protocol) super.toRT(); + } + + /** + * Queries my name. If I am a {@link #isConjugate() conjugate} protocol, then + * my name is suffixed by a tilde ({@literal ~}). + * + * @return my name + */ + @Override + public String getName() { + String result = super.getName(); + if (isConjugate()) { + result = result + "~"; //$NON-NLS-1$ + } + return result; + } + + /** + * Sets my name. If I am a {@link #isConjugate() conjugate} protocol, then + * my name must be suffixed by a tilde ({@literal ~}). + * + * @return my name + * + * @throws IllegalArgumentException + * if my name is ill-formed + */ + @Override + public void setName(String newName) { + if (isConjugate()) { + if (!newName.endsWith("~")) { + throw new IllegalArgumentException("conjugate name must end with ~"); //$NON-NLS-1$ + } + + // But it isn't in the UML + newName = newName.substring(0, newName.length() - 1); + } + + super.setName(newName); + } + + /** + * Queries the package that contains me. This is not the protocol-container + * package in the UML representation, but the package in which that is nested. + * + * @return my logical containing package + */ + @Override + public UMLRTPackage getPackage() { + Package protocolContainer = toUML().getNearestPackage(); + return (protocolContainer == null) + ? null + : UMLRTPackage.getInstance(protocolContainer.getNestingPackage()); + } + + /** + * Queries whether I am the conjugate view of the UML-RT protocol. + * If I am the conjugate, then the {@linkplain #getMessages() messages} that + * I present are the inverse direction kind to those of the base {@code protocol}. + * + * @return whether I am the conjugate protocol + * + * @see #getConjugate() + */ + public boolean isConjugate() { + return isConjugate; + } + + /** + * Obtains the conjugate view of myself if I am the base protocol, or else + * the base protocol if I {@linkplain #isConjugate() am a conjugate}. + * + * @return my conjugate + * + * @see #isConjugate() + */ + public UMLRTProtocol getConjugate() { + return conjugate.get(); + } + + /** + * Obtains the 'real' conjugation to encode in the UML model according + * to my {@linkplain #isConjugate() conjugation}. + * + * @param kind + * a message direction kind + * @return the UML model's value of the {@code kind} + * + * @see #isConjugate() + */ + private RTMessageKind forConjugation(RTMessageKind kind) { + if ((kind != null) && isConjugate()) { + switch (kind) { + case IN: + kind = RTMessageKind.OUT; + break; + case OUT: + kind = RTMessageKind.IN; + break; + default: + // INOUT is its own inverse + break; + } + } + return kind; + } + + /** + * Obtains the protocol that is my supertype, if any. + * + * @return my supertype, or {@code null} if I am a root protocol type + */ + public UMLRTProtocol getSuperProtocol() { + return forConjugation((UMLRTProtocol) getGeneral()); + } + + /** + * Assigns the protocol that is my supertype. UML-RT recognizes + * only single inheritance, so if the UML model has any other + * generalizations, they are destroyed. + * + * @param capsule + * my new supertype, or {@code null} if I am to be a root type + */ + public void setSuperProtocol(UMLRTProtocol protocol) { + setGeneral(protocol); + messageSets().forEach(set -> setSuperMessageSet(set, protocol)); + } + + private void setSuperMessageSet(Interface messageSet, UMLRTProtocol protocol) { + RTMessageSet rt = getRTMessageSet(messageSet); + Interface superMessageSet = (protocol == null) + ? null + : protocol.requireMessageSet(rt.getRtMsgKind()); + + setGeneral(messageSet, superMessageSet); + } + + /** + * Obtains the currently loaded protocols that are my direct subtypes. + * Note that there may be other sub-types in resources that are not + * currently loaded. + * + * @return my known subtypes + */ + public List<UMLRTProtocol> getSubProtocols() { + return getSpecifics(false) + .filter(UMLRTProtocol.class::isInstance) + .map(UMLRTProtocol.class::cast) + .map(this::forConjugation) + .collect(collectingAndThen(toList(), Collections::unmodifiableList)); + } + + /** + * Gets the entire protocol specialization hierarchy, rooted at myself, + * as a stream. Note that there may be other types in the hierarchy in + * resources that are not currently loaded; these will not be included + * in the result. + * + * @return my protocol class hierarchy + */ + @Override + public Stream<UMLRTProtocol> getHierarchy() { + return super.getHierarchy() + .filter(UMLRTProtocol.class::isInstance) + .map(UMLRTProtocol.class::cast) + .map(this::forConjugation); + } + + UMLRTProtocol forConjugation(UMLRTProtocol other) { + return ((other != null) && (other != this) && isConjugate()) + ? other.getConjugate() + : other; + } + + static boolean isProtocol(Collaboration collaboration) { + return getProtocol(collaboration) != null; + } + + static Protocol getProtocol(Collaboration collaboration) { + return UMLUtil.getStereotypeApplication(collaboration, Protocol.class); + } + + static boolean isRTMessageSet(Interface interface_) { + return getRTMessageSet(interface_) != null; + } + + static RTMessageSet getRTMessageSet(Interface interface_) { + return UMLUtil.getStereotypeApplication(interface_, RTMessageSet.class); + } + + Stream<Interface> messageSets() { + return toUML().getNearestPackage().getOwnedTypes().stream() + .filter(Interface.class::isInstance).map(Interface.class::cast) + .filter(UMLRTProtocol::isRTMessageSet); + } + + Optional<Interface> getMessageSet(RTMessageKind kind) { + return messageSets().map(UMLRTProtocol::getRTMessageSet) + .filter(set -> set.getRtMsgKind() == kind) + .findFirst() + .map(RTMessageSet::getBase_Interface); + } + + Interface requireMessageSet(RTMessageKind kind) { + return getMessageSet(kind) + .orElseThrow(() -> new IllegalArgumentException("no such message set: " + kind)); //$NON-NLS-1$ + } + + static Interface requireMessageSet(Collaboration protocol, RTMessageKind kind) { + return UMLRTProtocol.getInstance(protocol).getMessageSet(kind) + .orElseThrow(() -> new IllegalArgumentException("no such message set: " + kind)); //$NON-NLS-1$ + } + + /** + * Queries my protocol messages of the given direction {@code kind}, including those + * that are inherited from my super-protocol (if any), + * except for any that I {@link #exclude() exclude}. + * + * @param kind + * the message direction kind + * @return the messages of that direction {@code kind}, or an empty list if there are none + */ + public List<UMLRTProtocolMessage> getMessages(RTMessageKind kind) { + // TODO: Cache in the UML CacheAdapter? + return getFacades(MESSAGE_REFERENCES.get(forConjugation(kind)), messageConjugation()); + } + + /** + * Obtains my protocol messages of the given direction {@code kind}, including + * any that are inherited from my super-protocol + * if I have one but also optionally any that I {@linkplain #exclude() exclude}. + * + * @param kind + * the message direction kind + * @param withExcluded + * whether to return also excluded messages + * @return all of my messages of the given {@code kind}, optionally also with exclusions + */ + public List<UMLRTProtocolMessage> getMessages(RTMessageKind kind, boolean withExclusions) { + // TODO: Cache in the UML CacheAdapter? + return getFacades(MESSAGE_REFERENCES.get(forConjugation(kind)), withExclusions, messageConjugation()); + } + + /** + * Obtains all of my protocol messages, including those + * that are inherited from my super-protocol, if any, + * except for any that I {@link #exclude() exclude}. + * + * @return my non-excluded messages, or an empty list if there are none + */ + public List<UMLRTProtocolMessage> getMessages() { + return getMessages(false); + } + + /** + * Obtains all of my protocol messages, including those + * that are inherited from my super-protocol, if any, + * optionally also including any that I {@link #exclude() exclude}. + * + * @param withExclusions + * whether to also consider excluded messages + * + * @return my messages, or an empty list if there are none + */ + public List<UMLRTProtocolMessage> getMessages(boolean withExclusions) { + // TODO: Cache in the UML CacheAdapter + return MESSAGE_REFERENCES.values().stream() + .flatMap(ref -> ref.facades(toUML(), withExclusions)) + .map(messageConjugation()) + .collect(collectingAndThen(toList(), Collections::unmodifiableList)); + } + + /** + * Obtains the {@code name}d message, possibly inherited from my super-protocol, + * even if I have {@linkplain #exclude() excluded} it. + * + * @param kind + * the message direction kind to find + * @param name + * the message name to find + * @return the named message, or {@code null} if I have no message of that + * {@code kind} and {@code name} + */ + public UMLRTProtocolMessage getMessage(RTMessageKind kind, String name) { + UMLRTProtocolMessage result = get(MESSAGE_REFERENCES.get(forConjugation(kind)), name); + if (result != null) { + result = messageConjugation().apply(result); + } + return result; + } + + /** + * Obtains the {@code name}d message of any direction kind, possibly inherited + * from my super-protocol, even if I have {@linkplain #exclude() excluded} it. + * + * @param name + * the message name to find + * @return the named message, or {@code null} if I have no message of that {@code name} + */ + public UMLRTProtocolMessage getMessage(String name) { + return MESSAGE_REFERENCES.values().stream() + .map(ref -> get(ref, name)) + .filter(Objects::nonNull) + .findAny() + .map(messageConjugation()) + .orElse(null); + } + + UnaryOperator<UMLRTProtocolMessage> messageConjugation() { + return isConjugate() + ? UMLRTProtocolMessage::getConjugate + : UnaryOperator.identity(); + } + + /** + * Create a new protocol message without any parameters. + * + * @param kind + * the message direction kind + * @param name + * the message name + * + * @return the new protocol message + */ + public UMLRTProtocolMessage createMessage(RTMessageKind kind, String name) { + UMLRTProtocolMessage result = create(MESSAGE_REFERENCES.get(forConjugation(kind)), name); + result.initReceiveEvent(); + return messageConjugation().apply(result); + } + + /** + * Create a new protocol message with a {@code data} parameter of the given type. + * + * @param kind + * the message direction kind + * @param name + * the message name + * @param dataParamType + * the type of the {@code data} parameter + * + * @return the new protocol message + */ + public UMLRTProtocolMessage createMessage(RTMessageKind kind, String name, Type dataParamType) { + UMLRTProtocolMessage result = createMessage(kind, name); + result.toUML().createOwnedParameter("data", dataParamType); + return result; + } + + /** + * Create a new protocol message with parameters. + * + * @param kind + * the message direction kind + * @param name + * the message name + * @param parameters + * the ordered list of parameter names + * @param paramTypes + * the corresponding list of parameter types + * + * @return the new protocol message + */ + public UMLRTProtocolMessage createMessage(RTMessageKind kind, String name, List<String> parameters, List<? extends Type> paramTypes) { + UMLRTProtocolMessage result = createMessage(kind, name); + + if ((parameters != null) && (paramTypes != null)) { + int count = parameters.size(); + if (paramTypes.size() != count) { + throw new IllegalArgumentException("parameter names and types mismatched"); //$NON-NLS-1$ + } + for (int i = 0; i < count; i++) { + result.toUML().createOwnedParameter(parameters.get(i), paramTypes.get(i)); + } + } + + return result; + } + + UMLRTProtocol initContents() { + // Message set interfaces + createMessageSet(RTMessageKind.IN); + createMessageSet(RTMessageKind.OUT); + createMessageSet(RTMessageKind.IN_OUT); + + // Wildcard event + toUML().getNearestPackage().createPackagedElement("*", UMLPackage.Literals.ANY_RECEIVE_EVENT); + + return this; + } + + private void createMessageSet(RTMessageKind direction) { + Package protocolContainer = toUML().getNearestPackage(); + + String name = getName(); + switch (direction) { + case OUT: + name = name + "~"; //$NON-NLS-1$ + break; + case IN_OUT: + name = name + "IO"; //$NON-NLS-1$ + break; + default: // IN + // Pass + break; + + } + + Interface messageSet = (Interface) protocolContainer.createOwnedType(name, UMLPackage.Literals.INTERFACE); + RTMessageSet stereo = (RTMessageSet) StereotypeApplicationHelper.getInstance(messageSet).applyStereotype(messageSet, UMLRealTimePackage.Literals.RT_MESSAGE_SET); + stereo.setRtMsgKind(direction); + + switch (direction) { + case IN: + toUML().createInterfaceRealization(null, messageSet); + break; + case OUT: + toUML().createUsage(messageSet); + break; + case IN_OUT: + toUML().createInterfaceRealization(null, messageSet); + toUML().createUsage(messageSet); + break; + } + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTProtocolMessage.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTProtocolMessage.java new file mode 100644 index 000000000..134d9d86b --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTProtocolMessage.java @@ -0,0 +1,290 @@ +/***************************************************************************** + * Copyright (c) 2016, 2017 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml; + +import static org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocol.isRTMessageSet; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Supplier; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTMessageKind; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTMessageSet; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.CachedReference; +import org.eclipse.uml2.uml.CallEvent; +import org.eclipse.uml2.uml.Collaboration; +import org.eclipse.uml2.uml.Operation; +import org.eclipse.uml2.uml.Package; +import org.eclipse.uml2.uml.Parameter; +import org.eclipse.uml2.uml.Type; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * A façade for UML {@link Operation} elements that represent UML-RT {@code ProtocolMessage}s, + * providing a view of the element more in keeping with the UML-RT semantics. + */ +public final class UMLRTProtocolMessage extends UMLRTNamedElement { + static final FacadeType<Operation, EObject, UMLRTProtocolMessage> TYPE = new FacadeType<>( + UMLRTProtocolMessage.class, + UMLPackage.Literals.OPERATION, + null, + UMLRTProtocolMessage::getInstance, + UMLRTProtocolMessage::getRedefinedMessage, + null); + + private final boolean isConjugate; + private final Supplier<UMLRTProtocolMessage> conjugate; + + UMLRTProtocolMessage(Operation operation) { + super(operation, null); + + this.isConjugate = false; + this.conjugate = new CachedReference<>(() -> new UMLRTProtocolMessage(this)); + } + + private UMLRTProtocolMessage(UMLRTProtocolMessage base) { + super(base.toUML(), base.toRT()); + + this.isConjugate = true; + this.conjugate = () -> base; // The base has a hard ref from the model anyways + } + + /** + * Obtains the protocol message façade for the message represented by the given + * UML operation. + * + * @param operation + * a UML operation representing a protocol message + * @return the base UML-RT protocol-message façade, or {@code null} if the operation + * is not actually a protocol message + */ + public static UMLRTProtocolMessage getInstance(Operation operation) { + BasicFacadeAdapter<UMLRTProtocolMessage> adapter = null; + + if ((operation != null) && isProtocolMessage(operation)) { + adapter = TYPE.getAdapter(operation); + if (adapter == null) { + adapter = new UMLRTProtocolMessage(operation).new BasicFacadeAdapter<>(); + operation.eAdapters().add(adapter); + } + } + + return (adapter == null) ? null : adapter.getFacade(); + } + + static UMLRTProtocolMessage getInstance(Operation operation, boolean conjugate) { + UMLRTProtocolMessage result = getInstance(operation); + + return ((result == null) || !conjugate) + ? result + : result.getConjugate(); + } + + static boolean isProtocolMessage(Operation operation) { + return (operation.getInterface() != null) && isRTMessageSet(operation.getInterface()); + } + + /** + * Obtains the UML representation of the protocol message. + * + * @return the UML representation + */ + @Override + public Operation toUML() { + return (Operation) super.toUML(); + } + + /** + * Obtains the protocol message's receive event in the UML model. + * + * @return the UML message receive event + */ + public CallEvent toReceiveEvent() { + return toUML().getNearestPackage().getPackagedElements().stream() + .filter(CallEvent.class::isInstance).map(CallEvent.class::cast) + .filter(ev -> ev.getOperation() == toUML()) + .findAny() + .orElse(null); + } + + /** + * Queries whether I am a conjugate message, that is, a message of my protocol's + * {@link UMLRTProtocol#getConjugate() conjugate} view. + * + * @return whether I am a conjugate + */ + boolean isConjugate() { + return isConjugate; + } + + /** + * Obtains my conjugate message, that is, the corresponding message of my protocol's + * {@link UMLRTProtocol#getConjugate() conjugate} view. + * + * @return my conjugate + */ + UMLRTProtocolMessage getConjugate() { + return conjugate.get(); + } + + Optional<RTMessageSet> getMessageSet() { + return Optional.ofNullable(toUML().getInterface()) + .map(UMLRTProtocol::getRTMessageSet); + } + + /** + * Queries the protocol that defines or inherits me. + * + * @return my containing protocol context + */ + public UMLRTProtocol getProtocol() { + Package protocolContainer = toUML().getNearestPackage(); + + return UMLRTProtocol.getInstance((Collaboration) protocolContainer.getOwnedType( + protocolContainer.getName(), false, UMLPackage.Literals.COLLABORATION, false), + isConjugate()); + } + + /** + * Queries my direction kind. + * + * @return my message direction kind, or {@code null} if I am not a valid + * protocol message + */ + public RTMessageKind getKind() { + return forConjugation(getMessageSet().map(RTMessageSet::getRtMsgKind).orElse(null)); + } + + /** + * Obtains the 'real' conjugation to encode in the UML model according + * to my {@linkplain #isConjugate() conjugation}. + * + * @param kind + * a message direction kind + * @return the UML model's value of the {@code kind} + * + * @see #isConjugate() + */ + private RTMessageKind forConjugation(RTMessageKind kind) { + if ((kind != null) && isConjugate()) { + switch (kind) { + case IN: + kind = RTMessageKind.OUT; + break; + case OUT: + kind = RTMessageKind.IN; + break; + default: + // INOUT is its own inverse + break; + } + } + return kind; + } + + /** + * Assigns my direction kind. Note that this actually moves me to + * a different message-set interface in the UML representation. + * + * @param kind + * my new kind + * + * @throws NullPointerException + * if the {@code kind} is {@code null} + */ + public void setKind(RTMessageKind kind) { + if (getKind() != Objects.requireNonNull(kind, "kind")) { //$NON-NLS-1$ + getProtocol().requireMessageSet(forConjugation(kind)) + .getOwnedOperations().add(toUML()); + } + } + + /** + * Obtains my parameters. As this is the {@link Operation#getOwnedParameters() ownedParameter} + * list from the UML representation, it may be manipulated directly to effect changes + * in the protocol message parameters. + * + * @return my parameters + */ + public List<Parameter> getParameters() { + return toUML().getOwnedParameters(); + } + + /** + * Obtains the {@code name}d parameter. + * + * @param name + * the parameter name to find + * @return the named parameter, or {@code null} if I have no parameter of that {@code name} + */ + public Parameter getParameter(String name) { + return toUML().getOwnedParameter(name, null); + } + + /** + * Obtains the {@code type}d parameter. + * + * @param type + * the parameter type to find + * @return the indicated parameter, or {@code null} if I have no parameter of that {@code type} + */ + public Parameter getParameter(Type type) { + return toUML().getOwnedParameter(null, type); + } + + /** + * Creates a new parameter. + * + * @param name + * the new parameter name + * @parm type the new parameter type + * + * @return the new parameter + */ + public Parameter createParameter(String name, Type type) { + return toUML().createOwnedParameter(name, type); + } + + /** + * Queries the inherited protocol message that I redefine, if any and even if + * I am {@link #isExcluded() excluded} or am the local representation of + * a message that is inherited as is. + * + * @return the protocol message that I redefine/inherit, or {@code null} if + * I am a root definition + */ + public UMLRTProtocolMessage getRedefinedMessage() { + Operation superOperation = (Operation) ((InternalUMLRTElement) toUML()).rtGetRedefinedElement(); + return UMLRTProtocolMessage.getInstance(superOperation, isConjugate()); + } + + @Override + public UMLRTProtocolMessage getRedefinedElement() { + return getRedefinedMessage(); + } + + @Override + public UMLRTNamedElement getRedefinitionContext() { + return getProtocol(); + } + + UMLRTProtocolMessage initReceiveEvent() { + CallEvent event = (CallEvent) toUML().getNearestPackage().createPackagedElement(null, UMLPackage.Literals.CALL_EVENT); + event.setOperation(toUML()); + return this; + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTReplicatedElement.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTReplicatedElement.java new file mode 100644 index 000000000..d4533bf21 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/UMLRTReplicatedElement.java @@ -0,0 +1,146 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.uml2.uml.LiteralInteger; +import org.eclipse.uml2.uml.LiteralUnlimitedNatural; +import org.eclipse.uml2.uml.MultiplicityElement; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.ValueSpecification; + +/** + * A façade for UML {@link Property} elements that represent UML-RT replicated + * features, providing a view of the element more in keeping with the UML-RT semantics. + */ +public abstract class UMLRTReplicatedElement extends UMLRTNamedElement { + + UMLRTReplicatedElement(Property property, EObject stereotype) { + super(property, stereotype); + } + + @Override + public Property toUML() { + return (Property) super.toUML(); + } + + /** + * Obtains the capsule that defines (or inherits) me. + * + * @return my context capsule + */ + public UMLRTCapsule getCapsule() { + return UMLRTCapsule.getInstance(toUML().getClass_()); + } + + /** + * My redefinition context is my {@link #getCapsule() capsule}. + * + * @return my redefinition contet + * + * @see #getCapsule() + */ + @Override + public UMLRTCapsule getRedefinitionContext() { + return getCapsule(); + } + + /** + * Queries whether the replication factor is represented as + * some kind of expression (usually a constant defined elsewhere + * in the model) and not literally as an integer value. + * In the case of a symbolic replication factor, this façade + * API cannot interpret it but can replace it, so it is necessary + * to access the {@linkplain #toUML() UML model element} directly + * to get its multiplicity bounds. + * + * @return whether the replication factor is symbolic + */ + public boolean isSymbolicReplicationFactor() { + return isSymbolicReplicationFactor(toUML().getUpperValue()); + } + + static boolean isSymbolicReplicationFactor(ValueSpecification value) { + // The null value is interpreted by default as 1, which is an integer + return (value != null) + && !(value instanceof LiteralUnlimitedNatural) + && !(value instanceof LiteralInteger) + && !isIntegerValuedExpression(value); + } + + private static boolean isIntegerValuedExpression(ValueSpecification value) { + String stringValue = value.stringValue(); + return isIntegerValued(stringValue); + } + + private static boolean isIntegerValued(String stringValue) { + return (stringValue != null) + && stringValue.chars().allMatch(ch -> (ch >= '0') && (ch <= '9')); + } + + /** + * Queries my replication factor. If the lower and upper bounds in the + * UML representation differ, then the result is the upper bound. + * + * @return my replication factor + */ + public int getReplicationFactor() { + return getReplicationFactor(toUML().getUpperValue()); + } + + static int getReplicationFactor(ValueSpecification value) { + return (value == null) ? 1 : integerValue(value); + } + + private static int integerValue(ValueSpecification value) { + int result; + + if (value instanceof LiteralUnlimitedNatural) { + result = ((LiteralUnlimitedNatural) value).getValue(); + } else if (value instanceof LiteralInteger) { + result = ((LiteralInteger) value).getValue(); + } else { + String stringValue = value.stringValue(); + if (isIntegerValued(stringValue)) { + result = Integer.valueOf(stringValue); + } else { + result = 1; + } + } + + return result; + } + + /** + * Sets my replication factor. If the lower bound in the UML + * representation is zero to indicate optionality, then only + * the upper bound is changed. + * + * @return my replication factor + */ + public void setReplicationFactor(int replication) { + setReplicationFactor(toUML(), replication); + } + + static void setReplicationFactor(MultiplicityElement mult, int replication) { + if ((replication != getReplicationFactor(mult.getUpperValue())) + || (replication != getReplicationFactor(mult.getLowerValue()))) { + mult.setLower(replication); + + if (mult.getLower() != 0) { + mult.setUpper(replication); + } + } + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/ClassRTImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/ClassRTImpl.java new file mode 100644 index 000000000..908e08f59 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/ClassRTImpl.java @@ -0,0 +1,198 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import static org.eclipse.papyrusrt.umlrt.uml.internal.util.DerivedUnionEObjectEListExt.extendSubsets; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.EStructuralFeature.Setting; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.papyrusrt.umlrt.uml.internal.operations.ClassOperations; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionHolder; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.DerivedUnionEObjectEListExt; +import org.eclipse.uml2.common.util.CacheAdapter; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.NamedElement; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * UML-RT semantics for {@link org.eclipse.uml2.uml.Class}. + */ +public class ClassRTImpl extends org.eclipse.uml2.uml.internal.impl.ClassImpl implements InternalUMLRTClassifier { + + private static final int[] EXT_OWNED_MEMBER_ESUBSETS = extendSubsets(OWNED_MEMBER_ESUBSETS, + ExtUMLExtPackage.CLASS__IMPLICIT_ATTRIBUTE, + ExtUMLExtPackage.CLASS__IMPLICIT_CONNECTOR, + ExtUMLExtPackage.CLASS__IMPLICIT_OPERATION); + + private final ExtensionHolder extension = new ExtensionHolder(this); + + protected ClassRTImpl() { + super(); + } + + @Override + public EObject create(EClass eClass) { + EObject result; + + if (eClass.getEPackage() == eClass().getEPackage()) { + result = UMLRTUMLFactoryImpl.eINSTANCE.create(eClass); + } else { + result = super.create(eClass); + } + + return result; + } + + @SuppressWarnings("unchecked") + @Override + public <T> T umlGet(int featureID) { + return (T) super.eGet(featureID, true, true); + } + + @Override + public void rtUnsetAll() { + // I inherit no features + } + + @Override + public void rtCreateExtension() { + extension.createExtension(); + } + + @Override + public void rtDestroyExtension() { + extension.destroyExtension(); + } + + @Override + public void rtSuppressForwardingWhile(Runnable action) { + extension.suppressForwardingWhile(action); + } + + @Override + public void rtInherit(InternalUMLRTClassifier supertype) { + if (supertype instanceof Class) { + ClassOperations.rtInherit(this, (InternalUMLRTClassifier & Class) supertype); + } + } + + @Override + public void rtDisinherit(InternalUMLRTClassifier supertype) { + if (supertype instanceof Class) { + ClassOperations.rtDisinherit(this, (InternalUMLRTClassifier & Class) supertype); + } + } + + @Override + public int eDerivedStructuralFeatureID(EStructuralFeature eStructuralFeature) { + return extension.getDerivedStructuralFeatureID(eStructuralFeature); + } + + @Override + public boolean eDynamicIsSet(int featureID) { + return (featureID <= ExtensionHolder.UML_EXTENSION_FEATURE_BASE) + ? extension.isSet(featureID) + : super.eDynamicIsSet(featureID); + } + + @Override + public boolean eOpenIsSet(EStructuralFeature eFeature) { + return extension.isSet(eFeature); + } + + @Override + public Object eDynamicGet(int featureID, boolean resolve, boolean coreType) { + return (featureID <= ExtensionHolder.UML_EXTENSION_FEATURE_BASE) + ? extension.get(featureID, resolve) + : super.eDynamicGet(featureID, resolve, coreType); + } + + @Override + public Object eOpenGet(EStructuralFeature eFeature, boolean resolve) { + return extension.get(eFeature, resolve); + } + + @Override + public void eDynamicSet(int featureID, Object newValue) { + if (featureID <= ExtensionHolder.UML_EXTENSION_FEATURE_BASE) { + extension.set(featureID, newValue); + } else { + super.eDynamicSet(featureID, newValue); + } + } + + @Override + public void eOpenSet(EStructuralFeature eFeature, Object newValue) { + extension.set(eFeature, newValue); + } + + @Override + public void eDynamicUnset(int featureID) { + if (featureID <= ExtensionHolder.UML_EXTENSION_FEATURE_BASE) { + extension.unset(featureID); + } else { + super.eDynamicUnset(featureID); + } + } + + @Override + public void eOpenUnset(EStructuralFeature eFeature) { + extension.unset(eFeature); + } + + @Override + public Setting eSetting(EStructuralFeature eFeature) { + int featureID = eDerivedStructuralFeatureID(eFeature); + return (featureID <= ExtensionHolder.UML_EXTENSION_FEATURE_BASE) + ? extension.setting(eFeature) + : super.eSetting(eFeature); + } + + @Override + public EList<EObject> eContents() { + return extension.getContents(this); + } + + @Override + public EList<NamedElement> getOwnedMembers() { + EList<NamedElement> result; + + CacheAdapter cache = getCacheAdapter(); + if (cache == null) { + result = new DerivedUnionEObjectEListExt<>(NamedElement.class, + this, UMLPackage.CLASS__OWNED_MEMBER, EXT_OWNED_MEMBER_ESUBSETS); + } else { + Resource eResource = eResource(); + @SuppressWarnings("unchecked") + EList<NamedElement> ownedMembers = (EList<NamedElement>) cache.get( + eResource, this, UMLPackage.Literals.NAMESPACE__OWNED_MEMBER); + if (ownedMembers == null) { + ownedMembers = new DerivedUnionEObjectEListExt<>( + NamedElement.class, this, + UMLPackage.CLASS__OWNED_MEMBER, EXT_OWNED_MEMBER_ESUBSETS); + cache.put(eResource, this, + UMLPackage.Literals.NAMESPACE__OWNED_MEMBER, + ownedMembers); + } + result = ownedMembers; + } + + return result; + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/CollaborationRTImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/CollaborationRTImpl.java new file mode 100644 index 000000000..7cb3cb9ee --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/CollaborationRTImpl.java @@ -0,0 +1,68 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.papyrusrt.umlrt.uml.internal.operations.CollaborationOperations; +import org.eclipse.uml2.uml.Collaboration; + +/** + * UML-RT semantics for {@link Collaboration}. + */ +public class CollaborationRTImpl extends org.eclipse.uml2.uml.internal.impl.CollaborationImpl implements InternalUMLRTCollaboration { + + protected CollaborationRTImpl() { + super(); + } + + @Override + public EObject create(EClass eClass) { + EObject result; + + if (eClass.getEPackage() == eClass().getEPackage()) { + result = UMLRTUMLFactoryImpl.eINSTANCE.create(eClass); + } else { + result = super.create(eClass); + } + + return result; + } + + @Override + public void rtInherit(InternalUMLRTClassifier supertype) { + if (supertype instanceof InternalUMLRTCollaboration) { + CollaborationOperations.rtInherit(this, (InternalUMLRTCollaboration) supertype); + } + } + + @Override + public void rtDisinherit(InternalUMLRTClassifier supertype) { + if (supertype instanceof Collaboration) { + CollaborationOperations.rtDisinherit(this, (InternalUMLRTCollaboration) supertype); + } + } + + @SuppressWarnings("unchecked") + @Override + public <T> T umlGet(int featureID) { + return (T) super.eGet(featureID, true, true); + } + + @Override + public void rtUnsetAll() { + // I inherit no features + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/ConnectorEndRTImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/ConnectorEndRTImpl.java new file mode 100644 index 000000000..e2b8c41b3 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/ConnectorEndRTImpl.java @@ -0,0 +1,362 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.papyrusrt.umlrt.uml.internal.operations.MultiplicityElementOperations; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionResource; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.InheritableEList; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.NotificationForwarder; +import org.eclipse.uml2.uml.ConnectableElement; +import org.eclipse.uml2.uml.Connector; +import org.eclipse.uml2.uml.ConnectorEnd; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.ValueSpecification; + +/** + * UML-RT semantics for {@link ConnectorEnd}. + */ +public class ConnectorEndRTImpl extends org.eclipse.uml2.uml.internal.impl.ConnectorEndImpl implements InternalUMLRTMultiplicityElement { + + private static final int ROLE__SET_FLAG = 0x1 << 0; + private static final int PART_WITH_PORT__SET_FLAG = 0x1 << 1; + + private static final Set<EStructuralFeature> INHERITED_FEATURES = new HashSet<>(Arrays.asList( + UMLPackage.Literals.CONNECTOR_END__ROLE, + UMLPackage.Literals.CONNECTOR_END__PART_WITH_PORT + /* Don't include multiplicity bounds because they forward for themselves */)); + + private int uFlags = 0x0; + + public ConnectorEndRTImpl() { + super(); + } + + @Override + public EObject create(EClass eClass) { + EObject result; + + if (eClass.getEPackage() == eClass().getEPackage()) { + result = UMLRTUMLFactoryImpl.eINSTANCE.create(eClass); + } else { + result = super.create(eClass); + } + + return result; + } + + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case UMLPackage.CONNECTOR_END__ROLE: + return isSetRole(); + case UMLPackage.CONNECTOR_END__PART_WITH_PORT: + return isSetPartWithPort(); + case UMLPackage.CONNECTOR_END__LOWER_VALUE: + return isSetLowerValue(); + case UMLPackage.CONNECTOR_END__UPPER_VALUE: + return isSetUpperValue(); + default: + return super.eIsSet(featureID); + } + } + + @SuppressWarnings("unchecked") + @Override + public <T> T umlGet(int featureID) { + switch (featureID) { + case UMLPackage.CONNECTOR_END__ROLE: + return (T) super.getRole(); + case UMLPackage.CONNECTOR_END__PART_WITH_PORT: + return (T) super.getPartWithPort(); + case UMLPackage.CONNECTOR_END__LOWER_VALUE: + return (T) super.getLowerValue(); + case UMLPackage.CONNECTOR_END__UPPER_VALUE: + return (T) super.getUpperValue(); + default: + return (T) super.eGet(featureID, true, true); + } + } + + @Override + public void eUnset(int featureID) { + switch (featureID) { + case UMLPackage.CONNECTOR_END__ROLE: + unsetRole(); + break; + case UMLPackage.CONNECTOR_END__PART_WITH_PORT: + unsetPartWithPort(); + break; + case UMLPackage.CONNECTOR_END__LOWER_VALUE: + unsetLowerValue(); + break; + case UMLPackage.CONNECTOR_END__UPPER_VALUE: + unsetUpperValue(); + break; + default: + super.eUnset(featureID); + break; + } + } + + @Override + public EObject eContainer() { + Element owner = rtOwner(); + return (owner != null) ? owner : super.eContainer(); + } + + @Override + public Resource eResource() { + Resource result = rtResource(); + + if (result instanceof ExtensionResource) { + EObject container = eContainer(); + if (container != null) { + result = container.eResource(); + } + } + + return result; + } + + @SuppressWarnings("unchecked") + @Override + public <R extends InternalUMLRTElement> R rtGetRedefinedElement() { + R result = null; + + Connector connector = (Connector) getOwner(); + if (connector instanceof InternalUMLRTElement) { + Connector redefined = ((InternalUMLRTElement) connector).rtGetRedefinedElement(); + if (redefined != null) { + int index = connector.getEnds().indexOf(this); + if ((index >= 0) && (index < redefined.getEnds().size())) { + ConnectorEnd end = redefined.getEnds().get(index); + if (end instanceof InternalUMLRTElement) { + result = (R) end; + } + } + } + } + + return result; + } + + @Override + public Collection<? extends EStructuralFeature> rtInheritedFeatures() { + return INHERITED_FEATURES; + } + + @Override + public void umlSetRedefinedElement(InternalUMLRTElement redefined) { + if (!(redefined instanceof ConnectorEnd)) { + throw new IllegalArgumentException("not a connector end: " + redefined); //$NON-NLS-1$ + } + + ConnectorEnd end = (ConnectorEnd) redefined; + int index = ((Connector) end.getOwner()).getEnds().indexOf(end); + if (index >= 0) { + EList<ConnectorEnd> ends = ((Connector) getOwner()).getEnds(); + int myIndex = ends.indexOf(this); + if (myIndex != index) { + ends.move(index, myIndex); + } + } + } + + void handleRedefinedConnector(Connector connector) { + if (connector != null) { + NotificationForwarder.adapt(this, + () -> new NotificationForwarder(this, + /* FIXME: Function? */null, rtInheritedFeatures())); + } else if (eBasicHasAdapters()) { + NotificationForwarder.unadapt(this); + } + + // And let my bounds know + ConnectorEnd redefined = rtGetRedefinedElement(); + if (lowerValue instanceof InternalUMLRTValueSpecification) { + ((InternalUMLRTValueSpecification) lowerValue).handleRedefinedMultiplicityElement(redefined); + } + if (upperValue instanceof InternalUMLRTValueSpecification) { + ((InternalUMLRTValueSpecification) upperValue).handleRedefinedMultiplicityElement(redefined); + } + } + + @Override + public void rtReify() { + Element owner = getOwner(); + if (owner instanceof Connector) { + EReference containment = eContainmentFeature(); + if (containment == UMLPackage.Literals.CONNECTOR__END) { + // Either all ends are real, or none. + EList<ConnectorEnd> ends = ((Connector) owner).getEnds(); + if (ends instanceof InheritableEList<?>) { + ((InheritableEList<ConnectorEnd>) ends).touch(); + } + } + } + } + + @Override + public void rtVirtualize() { + Element owner = getOwner(); + if (owner instanceof Connector) { + EReference containment = eContainmentFeature(); + if (containment == UMLPackage.Literals.CONNECTOR__END) { + // Either all ends are virtual, or none. + owner.eUnset(containment); + } + } + } + + @Override + public void rtUnsetAll() { + unsetRole(); + unsetPartWithPort(); + unsetLowerValue(); + unsetUpperValue(); + } + + @Override + public Element basicGetOwner() { + return rtOwner(); + } + + @Override + public ConnectableElement getRole() { + return inheritFeature(UMLPackage.Literals.CONNECTOR_END__ROLE); + } + + @Override + public void setRole(ConnectableElement newRole) { + // Make sure that the notification gets the correct old value + role = getRole(); + uFlags = uFlags | ROLE__SET_FLAG; + super.setRole(newRole); + } + + public boolean isSetRole() { + return (uFlags & ROLE__SET_FLAG) != 0; + } + + public void unsetRole() { + // Make sure that the notification gets the correct old and new values + ConnectableElement oldRole = getRole(); + boolean oldRoleESet = (uFlags & ROLE__SET_FLAG) != 0; + role = null; + uFlags = uFlags & ~ROLE__SET_FLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.CONNECTOR_END__ROLE, oldRole, getRole(), oldRoleESet)); + } + } + + @Override + public Property getPartWithPort() { + return inheritFeature(UMLPackage.Literals.CONNECTOR_END__PART_WITH_PORT); + } + + @Override + public void setPartWithPort(Property newPartWithPort) { + // Make sure that the notification gets the correct old value + partWithPort = getPartWithPort(); + uFlags = uFlags | PART_WITH_PORT__SET_FLAG; + super.setPartWithPort(newPartWithPort); + } + + public boolean isSetPartWithPort() { + return (uFlags & PART_WITH_PORT__SET_FLAG) != 0; + } + + public void unsetPartWithPort() { + // Make sure that the notification gets the correct old and new values + Property oldPartWithPort = getPartWithPort(); + boolean oldPartWithPortESet = (uFlags & PART_WITH_PORT__SET_FLAG) != 0; + partWithPort = null; + uFlags = uFlags & ~PART_WITH_PORT__SET_FLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.CONNECTOR_END__PART_WITH_PORT, oldPartWithPort, getPartWithPort(), oldPartWithPortESet)); + } + } + + @Override + public ValueSpecification umlGetLowerValue(boolean resolve) { + return resolve ? super.getLowerValue() : super.basicGetLowerValue(); + } + + @Override + public NotificationChain umlBasicSetLowerValue(ValueSpecification newLowerValue, NotificationChain msgs) { + return super.basicSetLowerValue(newLowerValue, msgs); + } + + @Override + public ValueSpecification getLowerValue() { + return MultiplicityElementOperations.getLowerValue(this); + } + + @Override + public void setLowerValue(ValueSpecification newLowerValue) { + MultiplicityElementOperations.setLowerValue(this, newLowerValue); + } + + public boolean isSetLowerValue() { + return MultiplicityElementOperations.isSetLowerValue(this); + } + + public void unsetLowerValue() { + MultiplicityElementOperations.unsetLowerValue(this); + } + + @Override + public ValueSpecification umlGetUpperValue(boolean resolve) { + return resolve ? super.getUpperValue() : super.basicGetUpperValue(); + } + + @Override + public NotificationChain umlBasicSetUpperValue(ValueSpecification newUpperValue, NotificationChain msgs) { + return super.basicSetUpperValue(newUpperValue, msgs); + } + + @Override + public ValueSpecification getUpperValue() { + return MultiplicityElementOperations.getUpperValue(this); + } + + @Override + public void setUpperValue(ValueSpecification newLowerValue) { + MultiplicityElementOperations.setUpperValue(this, newLowerValue); + } + + public boolean isSetUpperValue() { + return MultiplicityElementOperations.isSetUpperValue(this); + } + + public void unsetUpperValue() { + MultiplicityElementOperations.unsetUpperValue(this); + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/ConnectorRTImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/ConnectorRTImpl.java new file mode 100644 index 000000000..a99c7c2ad --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/ConnectorRTImpl.java @@ -0,0 +1,295 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionResource; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.InheritableEList; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.InheritableEObjectEList; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.RedefinedElementsList; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.RedefinedElementsListImpl; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Connector; +import org.eclipse.uml2.uml.ConnectorEnd; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.Namespace; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.VisibilityKind; + +/** + * UML-RT semantics for {@link Connector}. + */ +public class ConnectorRTImpl extends org.eclipse.uml2.uml.internal.impl.ConnectorImpl implements InternalUMLRTElement { + + private static final Set<EStructuralFeature> INHERITED_FEATURES = new HashSet<>(Arrays.asList( + UMLPackage.Literals.NAMED_ELEMENT__NAME, + UMLPackage.Literals.NAMED_ELEMENT__VISIBILITY + /* Don't include the 'end' list because it forwards for itself */)); + + protected ConnectorRTImpl() { + super(); + } + + @Override + public EObject create(EClass eClass) { + EObject result; + + if (eClass.getEPackage() == eClass().getEPackage()) { + result = UMLRTUMLFactoryImpl.eINSTANCE.create(eClass); + } else { + result = super.create(eClass); + } + + return result; + } + + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case UMLPackage.CONNECTOR__NAME: + return isSetName(); + case UMLPackage.CONNECTOR__VISIBILITY: + return isSetVisibility(); + case UMLPackage.CONNECTOR__END: + return isSetEnds(); + default: + return super.eIsSet(featureID); + } + } + + @SuppressWarnings("unchecked") + @Override + public <T> T umlGet(int featureID) { + switch (featureID) { + case UMLPackage.CONNECTOR__NAME: + return (T) super.getName(); + case UMLPackage.CONNECTOR__VISIBILITY: + return (T) super.getVisibility(); + case UMLPackage.CONNECTOR__END: + return (T) super.getEnds(); + default: + return (T) super.eGet(featureID, true, true); + } + } + + @Override + public void eUnset(int featureID) { + switch (featureID) { + case UMLPackage.CONNECTOR__END: + unsetEnds(); + break; + default: + super.eUnset(featureID); + break; + } + } + + @Override + public void umlSetRedefinedElement(InternalUMLRTElement redefined) { + if (!(redefined instanceof Connector)) { + throw new IllegalArgumentException("not a connector: " + redefined); //$NON-NLS-1$ + } + + ((RedefinedElementsList<Connector>) getRedefinedConnectors()).setRedefinedElement( + (Connector) redefined); + } + + @Override + public EList<Connector> getRedefinedConnectors() { + if (redefinedConnectors == null) { + redefinedConnectors = new RedefinedElementsListImpl<>( + Connector.class, this, + UMLPackage.CONNECTOR__REDEFINED_CONNECTOR, + this::handleRedefinedConnector); + } + return redefinedConnectors; + } + + void handleRedefinedConnector(Connector connector) { + if (ends != null) { + ends.forEach(e -> ((ConnectorEndRTImpl) e).handleRedefinedConnector(connector)); + } + } + + @Override + public Collection<? extends EStructuralFeature> rtInheritedFeatures() { + return INHERITED_FEATURES; + } + + @Override + public EObject eContainer() { + Element owner = rtOwner(); + return (owner != null) ? owner : super.eContainer(); + } + + @Override + public Resource eResource() { + Resource result = rtResource(); + + if (result instanceof ExtensionResource) { + EObject container = eContainer(); + if (container != null) { + result = container.eResource(); + } + } + + return result; + } + + @Override + public void rtReify() { + Namespace namespace = getNamespace(); + if (namespace instanceof Class) { + Class class_ = (Class) namespace; + if ((class_ != null) && !class_.getOwnedConnectors().contains(this)) { + class_.getOwnedConnectors().add(this); + rtAdjustStereotypes(); + } + } + } + + @Override + public void rtVirtualize() { + Namespace namespace = getNamespace(); + if (namespace instanceof Class) { + Class class_ = (Class) namespace; + + @SuppressWarnings("unchecked") + EList<? super Connector> implicitConnectors = (EList<? super Connector>) class_.eGet(ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR); + if (!implicitConnectors.contains(this)) { + implicitConnectors.add(this); + rtAdjustStereotypes(); + } + } + } + + @Override + public void rtUnsetAll() { + unsetName(); + unsetVisibility(); + unsetEnds(); + } + + @Override + public Element basicGetOwner() { + return rtOwner(); + } + + @Override + public Namespace basicGetNamespace() { + EObject rtOwner = rtOwner(); + return (rtOwner instanceof org.eclipse.uml2.uml.Class) + ? (org.eclipse.uml2.uml.Class) rtOwner + : super.basicGetNamespace(); + } + + @Override + public String getName() { + return inheritFeature(UMLPackage.Literals.NAMED_ELEMENT__NAME); + } + + @Override + public void setName(String newName) { + // Make sure that the notification gets the correct old value + name = getName(); + super.setName(newName); + } + + @Override + public void unsetName() { + // Make sure that the notification gets the correct old and new values + String oldName = getName(); + boolean oldNameESet = (eFlags & NAME_ESETFLAG) != 0; + name = NAME_EDEFAULT; + eFlags = eFlags & ~NAME_ESETFLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.NAMED_ELEMENT__NAME, oldName, getName(), oldNameESet)); + } + } + + @Override + public VisibilityKind getVisibility() { + return inheritFeature(UMLPackage.Literals.NAMED_ELEMENT__VISIBILITY); + } + + @Override + public void setVisibility(VisibilityKind newVisibility) { + // Make sure that the notification gets the correct old value + if (newVisibility == null) { + newVisibility = VISIBILITY_EDEFAULT; + } + eFlags = eFlags | (getVisibility().ordinal() << VISIBILITY_EFLAG_OFFSET); + super.setVisibility(newVisibility); + } + + @Override + public void unsetVisibility() { + // Make sure that the notification gets the correct old and new values + VisibilityKind oldVisibility = getVisibility(); + boolean oldVisibilityESet = (eFlags & VISIBILITY_ESETFLAG) != 0; + eFlags = (eFlags & ~VISIBILITY_EFLAG) | VISIBILITY_EFLAG_DEFAULT; + eFlags = eFlags & ~VISIBILITY_ESETFLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.NAMED_ELEMENT__VISIBILITY, oldVisibility, getVisibility(), oldVisibilityESet)); + } + } + + @Override + public EList<ConnectorEnd> getEnds() { + if (ends == null) { + ends = new InheritableEObjectEList.Containment<ConnectorEnd>(this, UMLPackage.CONNECTOR__END) { + private static final long serialVersionUID = 1L; + + @Override + protected ConnectorEnd createRedefinition(ConnectorEnd inherited) { + ConnectorEndRTImpl result = (ConnectorEndRTImpl) create(inherited.eClass()); + // Redefinition is implied by correspondence of the ends by index + result.handleRedefinedConnector(rtGetRedefinedElement()); + return result; + } + }; + } + + EList<ConnectorEnd> inherited = inheritFeature(UMLPackage.Literals.CONNECTOR__END); + + if (inherited != ends) { + // Inherit this into our list. If it's null, that means we are the root definition + ((InheritableEList<ConnectorEnd>) ends).inherit(inherited); + } + + return ends; + } + + public boolean isSetEnds() { + return (ends != null) && ((InheritableEList<ConnectorEnd>) ends).isSet(); + } + + public void unsetEnds() { + if (ends != null) { + ((InheritableEList<ConnectorEnd>) ends).unset(); + } + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/InterfaceRTImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/InterfaceRTImpl.java new file mode 100644 index 000000000..ddb1e539e --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/InterfaceRTImpl.java @@ -0,0 +1,197 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import static org.eclipse.papyrusrt.umlrt.uml.internal.util.DerivedUnionEObjectEListExt.extendSubsets; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.EStructuralFeature.Setting; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.papyrusrt.umlrt.uml.internal.operations.InterfaceOperations; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionHolder; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.DerivedUnionEObjectEListExt; +import org.eclipse.uml2.common.util.CacheAdapter; +import org.eclipse.uml2.uml.Interface; +import org.eclipse.uml2.uml.NamedElement; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * UML-RT semantics for {@link org.eclipse.uml2.uml.Interface}. + */ +public class InterfaceRTImpl extends org.eclipse.uml2.uml.internal.impl.InterfaceImpl implements InternalUMLRTClassifier { + + private static final int[] EXT_OWNED_MEMBER_ESUBSETS = extendSubsets(OWNED_MEMBER_ESUBSETS, + ExtUMLExtPackage.INTERFACE__IMPLICIT_OPERATION); + + private final ExtensionHolder extension = new ExtensionHolder(this); + + protected InterfaceRTImpl() { + super(); + } + + @Override + public EObject create(EClass eClass) { + EObject result; + + if (eClass.getEPackage() == eClass().getEPackage()) { + result = UMLRTUMLFactoryImpl.eINSTANCE.create(eClass); + } else { + result = super.create(eClass); + } + + return result; + } + + @SuppressWarnings("unchecked") + @Override + public <T> T umlGet(int featureID) { + return (T) super.eGet(featureID, true, true); + } + + @Override + public void rtUnsetAll() { + // I inherit no features + } + + @Override + public void rtCreateExtension() { + extension.createExtension(); + } + + @Override + public void rtDestroyExtension() { + extension.destroyExtension(); + } + + @Override + public void rtSuppressForwardingWhile(Runnable action) { + extension.suppressForwardingWhile(action); + } + + @Override + public void rtInherit(InternalUMLRTClassifier supertype) { + if (supertype instanceof Interface) { + InterfaceOperations.rtInherit(this, (InternalUMLRTClassifier & Interface) supertype); + } + } + + @Override + public void rtDisinherit(InternalUMLRTClassifier supertype) { + if (supertype instanceof Interface) { + InterfaceOperations.rtDisinherit(this, (InternalUMLRTClassifier & Interface) supertype); + } + } + + @Override + public int eDerivedStructuralFeatureID(EStructuralFeature eStructuralFeature) { + return extension.getDerivedStructuralFeatureID(eStructuralFeature); + } + + @Override + public boolean eDynamicIsSet(int featureID) { + return (featureID <= ExtensionHolder.UML_EXTENSION_FEATURE_BASE) + ? extension.isSet(featureID) + : super.eDynamicIsSet(featureID); + } + + @Override + public boolean eOpenIsSet(EStructuralFeature eFeature) { + return extension.isSet(eFeature); + } + + @Override + public Object eDynamicGet(int featureID, boolean resolve, boolean coreType) { + return (featureID <= ExtensionHolder.UML_EXTENSION_FEATURE_BASE) + ? extension.get(featureID, resolve) + : super.eDynamicGet(featureID, resolve, coreType); + } + + @Override + public Object eOpenGet(EStructuralFeature eFeature, boolean resolve) { + return extension.get(eFeature, resolve); + } + + @Override + public void eDynamicSet(int featureID, Object newValue) { + if (featureID <= ExtensionHolder.UML_EXTENSION_FEATURE_BASE) { + extension.set(featureID, newValue); + } else { + super.eDynamicSet(featureID, newValue); + } + } + + @Override + public void eOpenSet(EStructuralFeature eFeature, Object newValue) { + extension.set(eFeature, newValue); + } + + @Override + public void eDynamicUnset(int featureID) { + if (featureID <= ExtensionHolder.UML_EXTENSION_FEATURE_BASE) { + extension.unset(featureID); + } else { + super.eDynamicUnset(featureID); + } + } + + @Override + public void eOpenUnset(EStructuralFeature eFeature) { + extension.unset(eFeature); + } + + @Override + public Setting eSetting(EStructuralFeature eFeature) { + int featureID = eDerivedStructuralFeatureID(eFeature); + return (featureID <= ExtensionHolder.UML_EXTENSION_FEATURE_BASE) + ? extension.setting(eFeature) + : super.eSetting(eFeature); + } + + @Override + public EList<EObject> eContents() { + return extension.getContents(this); + } + + @Override + public EList<NamedElement> getOwnedMembers() { + EList<NamedElement> result; + + CacheAdapter cache = getCacheAdapter(); + if (cache == null) { + result = new DerivedUnionEObjectEListExt<>(NamedElement.class, + this, UMLPackage.INTERFACE__OWNED_MEMBER, EXT_OWNED_MEMBER_ESUBSETS); + } else { + Resource eResource = eResource(); + @SuppressWarnings("unchecked") + EList<NamedElement> ownedMembers = (EList<NamedElement>) cache.get( + eResource, this, UMLPackage.Literals.NAMESPACE__OWNED_MEMBER); + if (ownedMembers == null) { + ownedMembers = new DerivedUnionEObjectEListExt<>( + NamedElement.class, this, + UMLPackage.INTERFACE__OWNED_MEMBER, EXT_OWNED_MEMBER_ESUBSETS); + cache.put(eResource, this, + UMLPackage.Literals.NAMESPACE__OWNED_MEMBER, + ownedMembers); + } + result = ownedMembers; + } + + return result; + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/InternalUMLRTClassifier.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/InternalUMLRTClassifier.java new file mode 100644 index 000000000..a226ac8af --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/InternalUMLRTClassifier.java @@ -0,0 +1,167 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.uml2.common.util.CacheAdapter; +import org.eclipse.uml2.uml.Classifier; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.Generalization; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.util.UMLUtil; + +/** + * Internal protocol for classifiers. + */ +public interface InternalUMLRTClassifier extends InternalUMLRTElement, Classifier { + /** + * Inherits features from my (new or changed) supertype, supporting + * only single generalization per the UML-RT semantics. + * + * @param supertype + * my new or changed supertype + */ + void rtInherit(InternalUMLRTClassifier supertype); + + /** + * Disinherits features from my (former) supertype, supporting + * only single generalization per the UML-RT semantics. + * + * @param supertype + * my former supertype + */ + void rtDisinherit(InternalUMLRTClassifier supertype); + + default InternalUMLRTClassifier rtGetSupertype() { + InternalUMLRTClassifier result; + + List<Classifier> generals = getGenerals(); + switch (generals.size()) { + case 0: + result = null; + break; + case 1: + result = (generals.get(0) instanceof InternalUMLRTClassifier) + ? (InternalUMLRTClassifier) generals.get(0) + : null; + break; + default: + result = generals.stream() + .filter(InternalUMLRTClassifier.class::isInstance) + .filter(g -> g.eClass() == eClass()) + .map(InternalUMLRTClassifier.class::cast) + .findFirst() + .orElse(null); + break; + } + return result; + } + + default void rtSetSupertype(InternalUMLRTClassifier supertype) { + // UML-RT recognizes single inheritance only + + if (supertype == null) { + new ArrayList<>(getGeneralizations()).forEach(Element::destroy); + } else if (rtGetSupertype() != supertype) { + if (supertype.eClass() != eClass()) { + throw new IllegalArgumentException("incompatible metaclass: " + supertype); //$NON-NLS-1$ + } + + List<Generalization> generalizations = getGeneralizations(); + if (generalizations.isEmpty()) { + createGeneralization(supertype); + } else { + generalizations.get(0).setGeneral(supertype); + } + } + } + + default Stream<? extends InternalUMLRTClassifier> rtSubtypes() { + return CacheAdapter.getCacheAdapter(this).getNonNavigableInverseReferences(this).stream() + .filter(setting -> setting.getEStructuralFeature() == UMLPackage.Literals.GENERALIZATION__GENERAL) + .map(EStructuralFeature.Setting::getEObject) + .map(Generalization.class::cast) + .map(Generalization::getSpecific) + .filter(InternalUMLRTClassifier.class::isInstance) + .filter(g -> g.eClass() == eClass()) + .map(InternalUMLRTClassifier.class::cast); + } + + default <T extends Element> void rtInherit(InternalUMLRTClassifier general, EReference reference, EReference extension, + Class<T> type, Class<? extends EObject> stereotype) { + + Predicate<InternalUMLRTElement> typeFilter = (stereotype == null) + ? type::isInstance + : elem -> type.isInstance(elem) && UMLUtil.getStereotypeApplication((Element) elem, stereotype) != null; + + List<InternalUMLRTElement> redefinitions = rtGet(reference, extension).collect(Collectors.toList()); + general.rtGet(reference, extension) + .filter(typeFilter) + .filter(inh -> !rtHasRedefinition(inh, redefinitions)) + .forEach(inh -> rtAddImplicitRedefinition(inh, extension)); + } + + default Stream<InternalUMLRTElement> rtGet(EReference reference, EReference extension) { + Stream<InternalUMLRTElement> result = ((List<?>) this.eGet(reference)).stream() + .filter(InternalUMLRTElement.class::isInstance).map(InternalUMLRTElement.class::cast); + + if (extension != null) { + result = Stream.concat(result, ((List<?>) this.eGet(extension)).stream() + .filter(InternalUMLRTElement.class::isInstance).map(InternalUMLRTElement.class::cast)); + } + + return result; + } + + default boolean rtHasRedefinition(InternalUMLRTElement inherited, Collection<? extends InternalUMLRTElement> redefinitions) { + return redefinitions.stream() // Includes exclusions + .map(InternalUMLRTElement::rtGetRedefinedElement) + .anyMatch(inherited::equals); + } + + @SuppressWarnings("unchecked") + default InternalUMLRTElement rtAddImplicitRedefinition(InternalUMLRTElement inherited, EReference extension) { + InternalUMLRTElement result = (InternalUMLRTElement) create(Objects.requireNonNull(extension).getEReferenceType()); + + List<? super InternalUMLRTElement> implicitElements = (List<? super InternalUMLRTElement>) eGet(extension); + implicitElements.add(result); + + result.rtApplyStereotypes(inherited); + result.rtRedefine(inherited); + + return result; + } + + default void rtDisinherit(InternalUMLRTClassifier general, EReference reference, EReference extension) { + List<InternalUMLRTElement> redefinitions = rtGet(reference, extension).collect(Collectors.toList()); + + redefinitions.stream() + .filter(redef -> Optional.ofNullable(redef.rtGetRedefinedElement()) + .filter(inh -> ((Element) inh).getOwner() == general) + .isPresent()) + .filter(Element.class::isInstance).map(Element.class::cast) + .forEach(Element::destroy); + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/InternalUMLRTCollaboration.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/InternalUMLRTCollaboration.java new file mode 100644 index 000000000..53b925c9c --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/InternalUMLRTCollaboration.java @@ -0,0 +1,40 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import java.util.Optional; +import java.util.stream.Stream; + +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.Protocol; +import org.eclipse.uml2.uml.Collaboration; +import org.eclipse.uml2.uml.Interface; +import org.eclipse.uml2.uml.Package; +import org.eclipse.uml2.uml.util.UMLUtil; + +/** + * Internal protocol for collaborations. + */ +public interface InternalUMLRTCollaboration extends InternalUMLRTClassifier, Collaboration { + default Stream<Interface> rtMessageSets() { + Package protocolContainer = (UMLUtil.getStereotypeApplication(this, Protocol.class) == null) + ? null + : getPackage(); + + return Optional.ofNullable(protocolContainer) + .map(package_ -> package_.getOwnedTypes().stream() + .filter(Interface.class::isInstance).map(Interface.class::cast) + .filter(interface_ -> (interface_.getName() != null) && interface_.getName().startsWith(getName()))) + .orElseGet(Stream::empty); + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/InternalUMLRTElement.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/InternalUMLRTElement.java new file mode 100644 index 000000000..22219c4e9 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/InternalUMLRTElement.java @@ -0,0 +1,341 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.Callable; + +import org.eclipse.emf.common.util.WrappedException; +import org.eclipse.emf.ecore.EClass; +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.ecore.resource.Resource; +import org.eclipse.papyrusrt.umlrt.uml.internal.operations.ElementOperations; +import org.eclipse.papyrusrt.umlrt.uml.internal.operations.RedefinableElementOperations; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionResource; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.ReificationAdapter; +import org.eclipse.uml2.common.util.CacheAdapter; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.RedefinableElement; +import org.eclipse.uml2.uml.util.UMLUtil; +import org.eclipse.uml2.uml.util.UMLUtil.StereotypeApplicationHelper; + +/** + * Common interface of UML model elements that implement specialized + * semantics for UML-RT. + */ +public interface InternalUMLRTElement extends InternalEObject { + + /** Exposes the corresponding API of BasicEObjectImpl. */ + int eDerivedStructuralFeatureID(EStructuralFeature eStructuralFeature); + + /** + * Queries whether the given {@code feature} has a value set according to + * UML-RT semantics. It may be set even if UML-ishly it is + * {@linkplain EObject#eIsSet(EStructuralFeature) unset} but its owner is, + * itself, UML-RT-ishly set (recursively). + * + * @param feature + * a feature + * @return whether it is explicitly set, according to UML-RT + * + * @see EObject#eIsSet(EStructuralFeature) + */ + default boolean rtIsSet(EStructuralFeature feature) { + // Most elements are not concerned with being owned by a redefinition + return eIsSet(feature); + } + + /** + * Obtains the value of the given {@code feature} according to + * core UML semantics. + * + * @param feature + * a feature + * @return its basic UML value + */ + @SuppressWarnings("unchecked") + default <T> T umlGet(EStructuralFeature feature) { + int featureID = eDerivedStructuralFeatureID(feature); + return (featureID >= 0) ? umlGet(featureID) : (T) eGet(feature); + } + + /** + * Obtains the value of the feature identified by the given + * {@link EClass}-local identifier according to core UML semantics. + * + * @param featureID + * a feature identifier + * @return the feature's basic UML value + */ + <T> T umlGet(int featureID); + + /** + * Ensures that my extension exists. + * + * @throws UnsupportedOperationException + * if I cannot be extended + */ + default void rtCreateExtension() { + throw new UnsupportedOperationException("createExtension"); + } + + /** + * Ensures that my extension does not exist. + * + * @throws UnsupportedOperationException + * if I cannot be extended + */ + default void rtDestroyExtension() { + throw new UnsupportedOperationException("destroyExtension"); + } + + /** + * Suppresses the forwarding of notifications from my extension (if I have one) + * for the duration of the given {@code action} that I shall run. + * + * @param action + * an action to run without forwarding of extension notifications + */ + default void rtSuppressForwardingWhile(Runnable action) { + action.run(); + } + + /** + * Obtains the possibly inherited value of the given {@code feature} according + * to UML-RT semantics. + * + * @param feature + * a feature to access + * @return its value, which may be explicitly set or inherited from a redefined element + */ + default <T> T inheritFeature(EStructuralFeature feature) { + return RedefinableElementOperations.inheritFeature(this, feature, CacheAdapter.getInstance()); + } + + /** + * Queries the features that I inherited from elements that I + * {@linkplain #rtGetRedefinedElement() redefine}. + * + * @return my inherited features + * + * @see #rtGetRedefinedElement() + */ + default Collection<? extends EStructuralFeature> rtInheritedFeatures() { + return Collections.emptySet(); + } + + /** + * Queries whether I am a redefinition of an inherited element according + * to UML-RT semantics. + * + * @return whether I am an UML-RT redefinition + */ + default boolean rtIsRedefinition() { + // Virtual elements are, by definition, redefinitions (that's why they exist) + return rtIsVirtual() || RedefinableElementOperations.isRedefinition(this); + } + + /** + * Obtains the element that I redefine, according to UML-RT semantics. + * + * @return my UML-RT redefined element, or {@code null} if I am not a + * {@linkplain #rtIsRedefinition() redefinition} or I am + * {@linkplain #rtIsExcluded() excluded} + */ + @SuppressWarnings("unchecked") + default <R extends InternalUMLRTElement> R rtGetRedefinedElement() { + return (R) RedefinableElementOperations.getRedefinedElement(this); + } + + default void umlSetRedefinedElement(InternalUMLRTElement redefined) { + throw new UnsupportedOperationException("redefinition not supported"); //$NON-NLS-1$ + } + + /** + * Queries whether I am a redefinition that excludes the inherited + * element according to UML-RT semantics. + * + * @return whether I am an UML-RT exclusion + */ + default boolean rtIsExcluded() { + return RedefinableElementOperations.isExcluded(this); + } + + default Element rtGetElement() { + return (this instanceof Element) ? (Element) this : UMLUtil.getBaseElement(this); + } + + default boolean rtExclude() { + return run(() -> { + boolean result = RedefinableElementOperations.exclude(this); + + if (result) { + // Strip me of all inheritable features + rtUnsetAll(); + } + + return result; + }); + } + + default boolean rtReinherit() { + return run(() -> { + boolean result = RedefinableElementOperations.reinherit(this); + + if (result) { + // Strip me of all inheritable features + rtUnsetAll(); + } + + return result; + }); + } + + /** + * Unsets all of my features that are inheritable. + */ + void rtUnsetAll(); + + default void rtRedefine(InternalUMLRTElement element) { + if (element.eClass() != this.eClass()) { + throw new IllegalArgumentException(String.format("a %s cannot redefine a %s", + this.eClass().getName(), element.eClass().getName())); + } + + RedefinableElementOperations.redefine((RedefinableElement & InternalUMLRTElement) this, + (RedefinableElement & InternalUMLRTElement) element); + } + + default Element rtOwner() { + return RedefinableElementOperations.getOwner(this); + } + + default Resource rtResource() { + return eInternalResource(); + } + + default void rtReify() { + throw new UnsupportedOperationException("rtReify"); //$NON-NLS-1$ + } + + default void rtVirtualize() { + throw new UnsupportedOperationException("rtVirtualize"); //$NON-NLS-1$ + } + + /** + * Runs an {@code action} on me without allowing anything that + * it does to cause me to be {@linkplain #rtReify() reified}, + * unless that is explicitly requested. + * + * @param action + * an action + * + * @see #rtReify() + */ + default void run(Runnable action) { + ReificationAdapter adapter = ReificationAdapter.getInstance(this); + if (adapter == null) { + // Just run the action + action.run(); + } else { + adapter.run(action); + } + } + + /** + * Runs an {@code action} on me without allowing anything that + * it does to cause me to be {@linkplain #rtReify() reified}, + * unless that is explicitly requested. + * + * @param action + * an action + * @return the {@code action}'s result + * + * @see #rtReify() + */ + default <V> V run(Callable<V> action) { + V result; + + ReificationAdapter adapter = ReificationAdapter.getInstance(this); + if (adapter == null) { + // Just run the action + try { + result = action.call(); + } catch (Exception e) { + throw new WrappedException(e); + } + } else { + result = adapter.run(action); + } + + return result; + } + + default boolean rtApplyStereotypes(InternalUMLRTElement prototype) { + boolean result = false; + + if ((this instanceof Element) && (prototype.eClass() == eClass())) { + result = ElementOperations.rtApplyStereotype((InternalUMLRTElement & Element) this, + (InternalUMLRTElement & Element) prototype); + } + + return result; + } + + default void rtAdjustStereotypes() { + if (this instanceof Element) { + Element element = (Element) this; + List<EObject> stereotypeApplications = new ArrayList<>(element.getStereotypeApplications()); + if (!stereotypeApplications.isEmpty()) { + if (rtIsVirtual()) { + // They must also be stored in the Extension Extent + rtResource().getContents().addAll(stereotypeApplications); + } else { + // Store my stereotypes in the appropriate model resource + StereotypeApplicationHelper helper = StereotypeApplicationHelper.getInstance(this); + stereotypeApplications.forEach(appl -> helper.addToContainmentList(element, appl)); + } + } + + // Also, if I need it, apply the RTRedefinedElement stereotype + if (!rtIsVirtual() && rtIsRedefinition() && (this instanceof RedefinableElement)) { + RedefinableElementOperations.ensureStereotype( + (RedefinableElement & InternalUMLRTElement) this); + } + } + } + + default boolean rtIsVirtual() { + boolean result = rtResource() instanceof ExtensionResource; + + if (!result) { + InternalEObject container = eInternalContainer(); + if (container != null) { + // I am virtual if I am contained in an unset reference + EReference containment = eContainmentFeature(); + result = !container.eIsSet(containment); + } + } + + return result; + } + + EObject create(EClass eClass); +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/InternalUMLRTMultiplicityElement.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/InternalUMLRTMultiplicityElement.java new file mode 100644 index 000000000..d4bc92521 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/InternalUMLRTMultiplicityElement.java @@ -0,0 +1,67 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.uml2.uml.MultiplicityElement; +import org.eclipse.uml2.uml.ValueSpecification; + +/** + * Internal protocol for multiplicity elements. + */ +public interface InternalUMLRTMultiplicityElement extends InternalUMLRTElement, MultiplicityElement { + /** + * Obtains the lower value, with or without proxy resolution, according to UML semantics. + * + * @param resolve + * whether to resolve proxies + * + * @return the UML-ish lower value (not inherited) + */ + ValueSpecification umlGetLowerValue(boolean resolve); + + /** + * Basic-sets the lower value, according to UML semantics. + * + * @param newLowerValue + * the new lower value + * @param msgs + * an incoming notification chain to append, or {@code null} if none, yet + * + * @return the outgoing notifications + */ + NotificationChain umlBasicSetLowerValue(ValueSpecification newLowerValue, NotificationChain msgs); + + /** + * Obtains the upper value, with or without proxy resolution, according to UML semantics. + * + * @param resolve + * whether to resolve proxies + * + * @return the UML-ish lower value (not inherited) + */ + ValueSpecification umlGetUpperValue(boolean resolve); + + /** + * Basic-sets the upper value, according to UML semantics. + * + * @param newUpperValue + * the new upper value + * @param msgs + * an incoming notification chain to append, or {@code null} if none, yet + * + * @return the outgoing notifications + */ + NotificationChain umlBasicSetUpperValue(ValueSpecification newUpperValue, NotificationChain msgs); +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/InternalUMLRTValueSpecification.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/InternalUMLRTValueSpecification.java new file mode 100644 index 000000000..c8603b486 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/InternalUMLRTValueSpecification.java @@ -0,0 +1,33 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import org.eclipse.uml2.uml.MultiplicityElement; +import org.eclipse.uml2.uml.ValueSpecification; + +/** + * Internal protocol for value specifications serving as multiplicity + * bounds for {@link MultiplicityElement}s. + */ +public interface InternalUMLRTValueSpecification extends InternalUMLRTElement, ValueSpecification { + /** + * Notifies me that my owning multiplicity-element's redefinition + * status has changed. + * + * @param mult + * my owner's new redefined element, or {@code null} + * if it is now not a redefinition + */ + void handleRedefinedMultiplicityElement(MultiplicityElement mult); +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/LiteralIntegerRTImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/LiteralIntegerRTImpl.java new file mode 100644 index 000000000..da729e10a --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/LiteralIntegerRTImpl.java @@ -0,0 +1,190 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.papyrusrt.umlrt.uml.internal.operations.ValueSpecificationOperations; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionResource; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.NotificationForwarder; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.LiteralInteger; +import org.eclipse.uml2.uml.MultiplicityElement; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * UML-RT semantics for {@link LiteralInteger}. + */ +public class LiteralIntegerRTImpl extends org.eclipse.uml2.uml.internal.impl.LiteralIntegerImpl implements InternalUMLRTValueSpecification { + + private static final int VALUE__SET_FLAG = 0x1 << 0; + + private static final Set<EStructuralFeature> INHERITED_FEATURES = new HashSet<>(Arrays.asList( + UMLPackage.Literals.LITERAL_INTEGER__VALUE)); + + private int uFlags = 0x0; + + public LiteralIntegerRTImpl() { + super(); + } + + @Override + public EObject create(EClass eClass) { + EObject result; + + if (eClass.getEPackage() == eClass().getEPackage()) { + result = UMLRTUMLFactoryImpl.eINSTANCE.create(eClass); + } else { + result = super.create(eClass); + } + + return result; + } + + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case UMLPackage.LITERAL_INTEGER__VALUE: + return isSetValue(); + default: + return super.eIsSet(featureID); + } + } + + @SuppressWarnings("unchecked") + @Override + public <T> T umlGet(int featureID) { + switch (featureID) { + case UMLPackage.LITERAL_INTEGER__VALUE: + return (T) (Integer) super.getValue(); + default: + return (T) super.eGet(featureID, true, true); + } + } + + @Override + public void eUnset(int featureID) { + switch (featureID) { + case UMLPackage.LITERAL_INTEGER__VALUE: + unsetValue(); + break; + default: + super.eUnset(featureID); + break; + } + } + + @Override + public EObject eContainer() { + Element owner = rtOwner(); + return (owner != null) ? owner : super.eContainer(); + } + + @Override + public Resource eResource() { + Resource result = rtResource(); + + if (result instanceof ExtensionResource) { + EObject container = eContainer(); + if (container != null) { + result = container.eResource(); + } + } + + return result; + } + + @Override + public <R extends InternalUMLRTElement> R rtGetRedefinedElement() { + return ValueSpecificationOperations.rtGetRedefinedElement(this); + } + + @Override + public void umlSetRedefinedElement(InternalUMLRTElement redefined) { + ValueSpecificationOperations.umlSetRedefinedElement(this, redefined); + } + + @Override + public Collection<? extends EStructuralFeature> rtInheritedFeatures() { + return INHERITED_FEATURES; + } + + @Override + public void handleRedefinedMultiplicityElement(MultiplicityElement mult) { + if (mult != null) { + NotificationForwarder.adapt(this, + () -> new NotificationForwarder(this, null, rtInheritedFeatures())); + } else if (eBasicHasAdapters()) { + NotificationForwarder.unadapt(this); + } + } + + @Override + public void rtReify() { + ValueSpecificationOperations.rtReify(this); + } + + @Override + public void rtVirtualize() { + ValueSpecificationOperations.rtVirtualize(this); + } + + @Override + public void rtUnsetAll() { + unsetValue(); + } + + @Override + public Element basicGetOwner() { + return rtOwner(); + } + + @Override + public int getValue() { + return inheritFeature(UMLPackage.Literals.LITERAL_INTEGER__VALUE); + } + + @Override + public void setValue(int newValue) { + // Make sure that the notification gets the correct old value + value = getValue(); + uFlags = uFlags | VALUE__SET_FLAG; + super.setValue(newValue); + } + + public boolean isSetValue() { + // I can only inherit my value if I am a virtual element + return ((uFlags & VALUE__SET_FLAG) != 0) || !rtIsVirtual(); + } + + public void unsetValue() { + // Make sure that the notification gets the correct old and new values + int oldValue = getValue(); + boolean oldValueESet = (uFlags & VALUE__SET_FLAG) != 0; + value = VALUE_EDEFAULT; + uFlags = uFlags & ~VALUE__SET_FLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.LITERAL_INTEGER__VALUE, oldValue, getValue(), oldValueESet)); + } + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/LiteralStringRTImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/LiteralStringRTImpl.java new file mode 100644 index 000000000..f6ece8a4f --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/LiteralStringRTImpl.java @@ -0,0 +1,192 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.papyrusrt.umlrt.uml.internal.operations.ValueSpecificationOperations; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionResource; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.NotificationForwarder; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.LiteralString; +import org.eclipse.uml2.uml.MultiplicityElement; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * UML-RT semantics for {@link LiteralString}. + */ +public class LiteralStringRTImpl extends org.eclipse.uml2.uml.internal.impl.LiteralStringImpl implements InternalUMLRTValueSpecification { + + private static final int VALUE__SET_FLAG = 0x1 << 0; + + private static final Set<EStructuralFeature> INHERITED_FEATURES = new HashSet<>(Arrays.asList( + UMLPackage.Literals.LITERAL_STRING__VALUE)); + + private int uFlags = 0x0; + + public LiteralStringRTImpl() { + super(); + } + + @Override + public EObject create(EClass eClass) { + EObject result; + + if (eClass.getEPackage() == eClass().getEPackage()) { + result = UMLRTUMLFactoryImpl.eINSTANCE.create(eClass); + } else { + result = super.create(eClass); + } + + return result; + } + + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case UMLPackage.LITERAL_STRING__VALUE: + return isSetValue(); + default: + return super.eIsSet(featureID); + } + } + + @SuppressWarnings("unchecked") + @Override + public <T> T umlGet(int featureID) { + switch (featureID) { + case UMLPackage.LITERAL_STRING__VALUE: + return (T) super.getValue(); + default: + return (T) super.eGet(featureID, true, true); + } + } + + @Override + public void eUnset(int featureID) { + switch (featureID) { + case UMLPackage.LITERAL_STRING__VALUE: + unsetValue(); + break; + default: + super.eUnset(featureID); + break; + } + } + + @Override + public EObject eContainer() { + Element owner = rtOwner(); + return (owner != null) ? owner : super.eContainer(); + } + + @Override + public Resource eResource() { + Resource result = rtResource(); + + if (result instanceof ExtensionResource) { + EObject container = eContainer(); + if (container != null) { + result = container.eResource(); + } + } + + return result; + } + + @Override + public <R extends InternalUMLRTElement> R rtGetRedefinedElement() { + return ValueSpecificationOperations.rtGetRedefinedElement(this); + } + + @Override + public void umlSetRedefinedElement(InternalUMLRTElement redefined) { + ValueSpecificationOperations.umlSetRedefinedElement(this, redefined); + } + + @Override + public Collection<? extends EStructuralFeature> rtInheritedFeatures() { + return INHERITED_FEATURES; + } + + @Override + public void handleRedefinedMultiplicityElement(MultiplicityElement mult) { + if (mult != null) { + NotificationForwarder.adapt(this, + () -> new NotificationForwarder(this, null, rtInheritedFeatures())); + } else if (eBasicHasAdapters()) { + NotificationForwarder.unadapt(this); + } + } + + @Override + public void rtReify() { + ValueSpecificationOperations.rtReify(this); + } + + @Override + public void rtVirtualize() { + ValueSpecificationOperations.rtVirtualize(this); + } + + @Override + public void rtUnsetAll() { + unsetValue(); + } + + @Override + public Element basicGetOwner() { + return rtOwner(); + } + + @Override + public String getValue() { + return inheritFeature(UMLPackage.Literals.LITERAL_STRING__VALUE); + } + + @Override + public void setValue(String newValue) { + // Make sure that the notification gets the correct old value + value = getValue(); + uFlags = uFlags | VALUE__SET_FLAG; + super.setValue(newValue); + } + + @Override + public boolean isSetValue() { + // I can only inherit my value if I am a virtual element + return ((uFlags & VALUE__SET_FLAG) != 0) || !rtIsVirtual(); + } + + @Override + public void unsetValue() { + // Make sure that the notification gets the correct old and new values + String oldValue = getValue(); + boolean oldValueESet = (uFlags & VALUE__SET_FLAG) != 0; + value = VALUE_EDEFAULT; + uFlags = uFlags & ~VALUE__SET_FLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.LITERAL_STRING__VALUE, oldValue, getValue(), oldValueESet)); + } + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/LiteralUnlimitedNaturalRTImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/LiteralUnlimitedNaturalRTImpl.java new file mode 100644 index 000000000..169dae3b3 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/LiteralUnlimitedNaturalRTImpl.java @@ -0,0 +1,190 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.papyrusrt.umlrt.uml.internal.operations.ValueSpecificationOperations; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionResource; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.NotificationForwarder; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.LiteralUnlimitedNatural; +import org.eclipse.uml2.uml.MultiplicityElement; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * UML-RT semantics for {@link LiteralUnlimitedNatural}. + */ +public class LiteralUnlimitedNaturalRTImpl extends org.eclipse.uml2.uml.internal.impl.LiteralUnlimitedNaturalImpl implements InternalUMLRTValueSpecification { + + private static final int VALUE__SET_FLAG = 0x1 << 0; + + private static final Set<EStructuralFeature> INHERITED_FEATURES = new HashSet<>(Arrays.asList( + UMLPackage.Literals.LITERAL_UNLIMITED_NATURAL__VALUE)); + + private int uFlags = 0x0; + + public LiteralUnlimitedNaturalRTImpl() { + super(); + } + + @Override + public EObject create(EClass eClass) { + EObject result; + + if (eClass.getEPackage() == eClass().getEPackage()) { + result = UMLRTUMLFactoryImpl.eINSTANCE.create(eClass); + } else { + result = super.create(eClass); + } + + return result; + } + + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case UMLPackage.LITERAL_UNLIMITED_NATURAL__VALUE: + return isSetValue(); + default: + return super.eIsSet(featureID); + } + } + + @SuppressWarnings("unchecked") + @Override + public <T> T umlGet(int featureID) { + switch (featureID) { + case UMLPackage.LITERAL_UNLIMITED_NATURAL__VALUE: + return (T) (Integer) super.getValue(); + default: + return (T) super.eGet(featureID, true, true); + } + } + + @Override + public void eUnset(int featureID) { + switch (featureID) { + case UMLPackage.LITERAL_UNLIMITED_NATURAL__VALUE: + unsetValue(); + break; + default: + super.eUnset(featureID); + break; + } + } + + @Override + public EObject eContainer() { + Element owner = rtOwner(); + return (owner != null) ? owner : super.eContainer(); + } + + @Override + public Resource eResource() { + Resource result = rtResource(); + + if (result instanceof ExtensionResource) { + EObject container = eContainer(); + if (container != null) { + result = container.eResource(); + } + } + + return result; + } + + @Override + public <R extends InternalUMLRTElement> R rtGetRedefinedElement() { + return ValueSpecificationOperations.rtGetRedefinedElement(this); + } + + @Override + public void umlSetRedefinedElement(InternalUMLRTElement redefined) { + ValueSpecificationOperations.umlSetRedefinedElement(this, redefined); + } + + @Override + public Collection<? extends EStructuralFeature> rtInheritedFeatures() { + return INHERITED_FEATURES; + } + + @Override + public void handleRedefinedMultiplicityElement(MultiplicityElement mult) { + if (mult != null) { + NotificationForwarder.adapt(this, + () -> new NotificationForwarder(this, null, rtInheritedFeatures())); + } else if (eBasicHasAdapters()) { + NotificationForwarder.unadapt(this); + } + } + + @Override + public void rtReify() { + ValueSpecificationOperations.rtReify(this); + } + + @Override + public void rtVirtualize() { + ValueSpecificationOperations.rtVirtualize(this); + } + + @Override + public void rtUnsetAll() { + unsetValue(); + } + + @Override + public Element basicGetOwner() { + return rtOwner(); + } + + @Override + public int getValue() { + return inheritFeature(UMLPackage.Literals.LITERAL_UNLIMITED_NATURAL__VALUE); + } + + @Override + public void setValue(int newValue) { + // Make sure that the notification gets the correct old value + value = getValue(); + uFlags = uFlags | VALUE__SET_FLAG; + super.setValue(newValue); + } + + public boolean isSetValue() { + // I can only inherit my value if I am a virtual element + return ((uFlags & VALUE__SET_FLAG) != 0) || !rtIsVirtual(); + } + + public void unsetValue() { + // Make sure that the notification gets the correct old and new values + int oldValue = getValue(); + boolean oldValueESet = (uFlags & VALUE__SET_FLAG) != 0; + value = VALUE_EDEFAULT; + uFlags = uFlags & ~VALUE__SET_FLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.LITERAL_UNLIMITED_NATURAL__VALUE, oldValue, getValue(), oldValueESet)); + } + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/ModelRTImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/ModelRTImpl.java new file mode 100644 index 000000000..0576836da --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/ModelRTImpl.java @@ -0,0 +1,53 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.uml2.uml.Model; + +/** + * UML-RT semantics for {@link Model}. + */ +public class ModelRTImpl extends org.eclipse.uml2.uml.internal.impl.ModelImpl implements InternalUMLRTElement { + + protected ModelRTImpl() { + super(); + } + + @Override + public EObject create(EClass eClass) { + EObject result; + + if (eClass.getEPackage() == eClass().getEPackage()) { + result = UMLRTUMLFactoryImpl.eINSTANCE.create(eClass); + } else { + result = super.create(eClass); + } + + return result; + } + + @SuppressWarnings("unchecked") + @Override + public <T> T umlGet(int featureID) { + return (T) super.eGet(featureID, true, true); + } + + @Override + public void rtUnsetAll() { + // I inherit no features + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/OpaqueExpressionRTImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/OpaqueExpressionRTImpl.java new file mode 100644 index 000000000..a6fcb77aa --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/OpaqueExpressionRTImpl.java @@ -0,0 +1,210 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.papyrusrt.umlrt.uml.internal.operations.ValueSpecificationOperations; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionResource; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.InheritableEList; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.InheritableEcoreEList; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.NotificationForwarder; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.MultiplicityElement; +import org.eclipse.uml2.uml.OpaqueExpression; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * UML-RT semantics for {@link OpaqueExpression}. + */ +public class OpaqueExpressionRTImpl extends org.eclipse.uml2.uml.internal.impl.OpaqueExpressionImpl implements InternalUMLRTValueSpecification { + + private static final Set<EStructuralFeature> INHERITED_FEATURES = new HashSet<>(Arrays.asList( + UMLPackage.Literals.OPAQUE_EXPRESSION__BODY, + UMLPackage.Literals.OPAQUE_EXPRESSION__LANGUAGE)); + + public OpaqueExpressionRTImpl() { + super(); + + class InheritableValueList<E> extends InheritableEcoreEList<E> { + private static final long serialVersionUID = 1L; + + InheritableValueList(int featureID) { + super(OpaqueExpressionRTImpl.this, featureID); + } + + @Override + public boolean isSet() { + // I can only inherit my value if I am a virtual element + return super.isSet() || !rtIsVirtual(); + } + } + + this.bodies = new InheritableValueList<>(UMLPackage.OPAQUE_EXPRESSION__BODY); + this.languages = new InheritableValueList<>(UMLPackage.OPAQUE_EXPRESSION__LANGUAGE); + } + + @Override + public EObject create(EClass eClass) { + EObject result; + + if (eClass.getEPackage() == eClass().getEPackage()) { + result = UMLRTUMLFactoryImpl.eINSTANCE.create(eClass); + } else { + result = super.create(eClass); + } + + return result; + } + + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case UMLPackage.OPAQUE_EXPRESSION__BODY: + return isSetBodies(); + case UMLPackage.OPAQUE_EXPRESSION__LANGUAGE: + return isSetLanguages(); + default: + return super.eIsSet(featureID); + } + } + + @SuppressWarnings("unchecked") + @Override + public <T> T umlGet(int featureID) { + switch (featureID) { + case UMLPackage.OPAQUE_EXPRESSION__BODY: + return (T) super.getBodies(); + case UMLPackage.OPAQUE_EXPRESSION__LANGUAGE: + return (T) super.getLanguages(); + default: + return (T) super.eGet(featureID, true, true); + } + } + + @Override + public void eUnset(int featureID) { + switch (featureID) { + case UMLPackage.OPAQUE_EXPRESSION__BODY: + unsetBodies(); + break; + case UMLPackage.OPAQUE_EXPRESSION__LANGUAGE: + unsetLanguages(); + break; + default: + super.eUnset(featureID); + break; + } + } + + @Override + public EObject eContainer() { + Element owner = rtOwner(); + return (owner != null) ? owner : super.eContainer(); + } + + @Override + public Resource eResource() { + Resource result = rtResource(); + + if (result instanceof ExtensionResource) { + EObject container = eContainer(); + if (container != null) { + result = container.eResource(); + } + } + + return result; + } + + @Override + public <R extends InternalUMLRTElement> R rtGetRedefinedElement() { + return ValueSpecificationOperations.rtGetRedefinedElement(this); + } + + @Override + public void umlSetRedefinedElement(InternalUMLRTElement redefined) { + ValueSpecificationOperations.umlSetRedefinedElement(this, redefined); + } + + @Override + public Collection<? extends EStructuralFeature> rtInheritedFeatures() { + return INHERITED_FEATURES; + } + + @Override + public void handleRedefinedMultiplicityElement(MultiplicityElement mult) { + if (mult != null) { + NotificationForwarder.adapt(this, + () -> new NotificationForwarder(this, null, rtInheritedFeatures())); + } else if (eBasicHasAdapters()) { + NotificationForwarder.unadapt(this); + } + } + + @Override + public void rtReify() { + ValueSpecificationOperations.rtReify(this); + } + + @Override + public void rtVirtualize() { + ValueSpecificationOperations.rtVirtualize(this); + } + + @Override + public void rtUnsetAll() { + unsetBodies(); + unsetLanguages(); + } + + @Override + public Element basicGetOwner() { + return rtOwner(); + } + + @Override + public EList<String> getBodies() { + EList<String> result = inheritFeature(UMLPackage.Literals.OPAQUE_EXPRESSION__BODY); + + if (result != bodies) { + // Inherit this into our list. If it's null, that means we are the root definition + ((InheritableEList<String>) bodies).inherit(result); + result = bodies; + } + + return bodies; + } + + @Override + public EList<String> getLanguages() { + EList<String> result = inheritFeature(UMLPackage.Literals.OPAQUE_EXPRESSION__LANGUAGE); + + if (result != languages) { + // Inherit this into our list. If it's null, that means we are the root definition + ((InheritableEList<String>) languages).inherit(result); + result = languages; + } + + return languages; + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/OperationRTImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/OperationRTImpl.java new file mode 100644 index 000000000..cf8467b58 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/OperationRTImpl.java @@ -0,0 +1,316 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionResource; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.InheritableEList; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.InheritableEObjectEList; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.RedefinedElementsList; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.RedefinedElementsListImpl; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.Interface; +import org.eclipse.uml2.uml.Operation; +import org.eclipse.uml2.uml.OperationOwner; +import org.eclipse.uml2.uml.Parameter; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.VisibilityKind; + +/** + * UML-RT semantics for {@link Operation}. + */ +public class OperationRTImpl extends org.eclipse.uml2.uml.internal.impl.OperationImpl implements InternalUMLRTElement { + + private static final Set<EStructuralFeature> INHERITED_FEATURES = new HashSet<>(Arrays.asList( + UMLPackage.Literals.NAMED_ELEMENT__NAME, + UMLPackage.Literals.NAMED_ELEMENT__VISIBILITY + /* Don't include the 'ownedParameter' list because it forwards for itself */)); + + protected OperationRTImpl() { + super(); + } + + @Override + public EObject create(EClass eClass) { + EObject result; + + if (eClass.getEPackage() == eClass().getEPackage()) { + result = UMLRTUMLFactoryImpl.eINSTANCE.create(eClass); + } else { + result = super.create(eClass); + } + + return result; + } + + @Override + public EObject eContainer() { + Element owner = rtOwner(); + return (owner != null) ? owner : super.eContainer(); + } + + @Override + public Resource eResource() { + Resource result = rtResource(); + + if (result instanceof ExtensionResource) { + EObject container = eContainer(); + if (container != null) { + result = container.eResource(); + } + } + + return result; + } + + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case UMLPackage.OPERATION__NAME: + return isSetName(); + case UMLPackage.OPERATION__VISIBILITY: + return isSetVisibility(); + case UMLPackage.OPERATION__OWNED_PARAMETER: + return isSetOwnedParameters(); + default: + return super.eIsSet(featureID); + } + } + + @SuppressWarnings("unchecked") + @Override + public <T> T umlGet(int featureID) { + switch (featureID) { + case UMLPackage.OPERATION__NAME: + return (T) super.getName(); + case UMLPackage.OPERATION__VISIBILITY: + return (T) super.getVisibility(); + case UMLPackage.OPERATION__OWNED_PARAMETER: + return (T) super.getOwnedParameters(); + default: + return (T) super.eGet(featureID, true, true); + } + } + + @Override + public void eUnset(int featureID) { + switch (featureID) { + case UMLPackage.OPERATION__OWNED_PARAMETER: + unsetOwnedParameters(); + break; + default: + super.eUnset(featureID); + break; + } + } + + @Override + public void umlSetRedefinedElement(InternalUMLRTElement redefined) { + if (!(redefined instanceof Operation)) { + throw new IllegalArgumentException("not an operation: " + redefined); //$NON-NLS-1$ + } + + ((RedefinedElementsList<Operation>) getRedefinedOperations()).setRedefinedElement( + (Operation) redefined); + } + + @Override + public EList<Operation> getRedefinedOperations() { + if (redefinedOperations == null) { + redefinedOperations = new RedefinedElementsListImpl<>( + Operation.class, this, + UMLPackage.OPERATION__REDEFINED_OPERATION); + } + return redefinedOperations; + } + + @Override + public Collection<? extends EStructuralFeature> rtInheritedFeatures() { + return INHERITED_FEATURES; + } + + @Override + public void rtReify() { + Element owner_ = getOwner(); + OperationOwner owner = (owner_ instanceof OperationOwner) ? (OperationOwner) owner_ : null; + if ((owner != null) && !owner.getOwnedOperations().contains(this)) { + owner.getOwnedOperations().add(this); + rtAdjustStereotypes(); + } + } + + @SuppressWarnings("unchecked") + @Override + public void rtVirtualize() { + EList<? super Operation> implicitOperations = null; + + Element owner = getOwner(); + if (owner instanceof Class) { + implicitOperations = (EList<? super Operation>) owner.eGet(ExtUMLExtPackage.Literals.CLASS__IMPLICIT_OPERATION); + } else if (owner instanceof Interface) { + implicitOperations = (EList<? super Operation>) owner.eGet(ExtUMLExtPackage.Literals.INTERFACE__IMPLICIT_OPERATION); + } + + if ((implicitOperations != null) && !implicitOperations.contains(this)) { + implicitOperations.add(this); + rtAdjustStereotypes(); + } + } + + @Override + public void rtUnsetAll() { + unsetName(); + unsetVisibility(); + unsetOwnedParameters(); + } + + @Override + public Element basicGetOwner() { + return rtOwner(); + } + + @Override + public Class basicGetClass_() { + Element rtOwner = rtOwner(); + return (rtOwner instanceof org.eclipse.uml2.uml.Class) + ? (org.eclipse.uml2.uml.Class) rtOwner + : null; + } + + @Override + public Class getClass_() { + Element rtOwner = rtOwner(); + return (rtOwner instanceof org.eclipse.uml2.uml.Class) + ? (org.eclipse.uml2.uml.Class) rtOwner + : null; + } + + @Override + public Interface getInterface() { + Element rtOwner = rtOwner(); + return (rtOwner instanceof Interface) + ? (Interface) rtOwner + : null; + } + + @Override + public Interface basicGetInterface() { + Element rtOwner = rtOwner(); + return (rtOwner instanceof Interface) + ? (Interface) rtOwner + : null; + } + + @Override + public String getName() { + return inheritFeature(UMLPackage.Literals.NAMED_ELEMENT__NAME); + } + + @Override + public void setName(String newName) { + // Make sure that the notification gets the correct old value + name = getName(); + super.setName(newName); + } + + @Override + public void unsetName() { + // Make sure that the notification gets the correct old and new values + String oldName = getName(); + boolean oldNameESet = (eFlags & NAME_ESETFLAG) != 0; + name = NAME_EDEFAULT; + eFlags = eFlags & ~NAME_ESETFLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.NAMED_ELEMENT__NAME, oldName, getName(), oldNameESet)); + } + } + + @Override + public VisibilityKind getVisibility() { + return inheritFeature(UMLPackage.Literals.NAMED_ELEMENT__VISIBILITY); + } + + @Override + public void setVisibility(VisibilityKind newVisibility) { + // Make sure that the notification gets the correct old value + if (newVisibility == null) { + newVisibility = VISIBILITY_EDEFAULT; + } + eFlags = eFlags | (getVisibility().ordinal() << VISIBILITY_EFLAG_OFFSET); + super.setVisibility(newVisibility); + } + + @Override + public void unsetVisibility() { + // Make sure that the notification gets the correct old and new values + VisibilityKind oldVisibility = getVisibility(); + boolean oldVisibilityESet = (eFlags & VISIBILITY_ESETFLAG) != 0; + eFlags = (eFlags & ~VISIBILITY_EFLAG) | VISIBILITY_EFLAG_DEFAULT; + eFlags = eFlags & ~VISIBILITY_ESETFLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.NAMED_ELEMENT__VISIBILITY, oldVisibility, getVisibility(), oldVisibilityESet)); + } + } + + @Override + public EList<Parameter> getOwnedParameters() { + if (ownedParameters == null) { + ownedParameters = new InheritableEObjectEList.Containment<Parameter>(this, UMLPackage.OPERATION__OWNED_PARAMETER) { + private static final long serialVersionUID = 1L; + + @Override + protected Parameter createRedefinition(Parameter inherited) { + ParameterRTImpl result = (ParameterRTImpl) create(inherited.eClass()); + // Redefinition is implied by correspondence of the parameters by index + result.handleRedefinedOperation(rtGetRedefinedElement()); + return result; + } + }; + } + + EList<Parameter> inherited = inheritFeature(UMLPackage.Literals.BEHAVIORAL_FEATURE__OWNED_PARAMETER); + + if (inherited != ownedParameters) { + // Inherit this into our list. If it's null, that means we are the root definition + ((InheritableEList<Parameter>) ownedParameters).inherit(inherited); + } + + return ownedParameters; + } + + @Override + public boolean isSetOwnedParameters() { + return (ownedParameters != null) && ((InheritableEList<Parameter>) ownedParameters).isSet(); + } + + public void unsetOwnedParameters() { + if (ownedParameters != null) { + ((InheritableEList<Parameter>) ownedParameters).unset(); + } + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/PackageRTImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/PackageRTImpl.java new file mode 100644 index 000000000..d0c9c488d --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/PackageRTImpl.java @@ -0,0 +1,52 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * UML-RT semantics for {@link org.eclipse.uml2.uml.Package}. + */ +public class PackageRTImpl extends org.eclipse.uml2.uml.internal.impl.PackageImpl implements InternalUMLRTElement { + + protected PackageRTImpl() { + super(); + } + + @Override + public EObject create(EClass eClass) { + EObject result; + + if (eClass.getEPackage() == eClass().getEPackage()) { + result = UMLRTUMLFactoryImpl.eINSTANCE.create(eClass); + } else { + result = super.create(eClass); + } + + return result; + } + + @SuppressWarnings("unchecked") + @Override + public <T> T umlGet(int featureID) { + return (T) super.eGet(featureID, true, true); + } + + @Override + public void rtUnsetAll() { + // I inherit no features + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/ParameterRTImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/ParameterRTImpl.java new file mode 100644 index 000000000..d08b08533 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/ParameterRTImpl.java @@ -0,0 +1,372 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.papyrusrt.umlrt.uml.internal.operations.MultiplicityElementOperations; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionResource; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.InheritableEList; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.NotificationForwarder; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.Operation; +import org.eclipse.uml2.uml.Parameter; +import org.eclipse.uml2.uml.Type; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.ValueSpecification; +import org.eclipse.uml2.uml.VisibilityKind; + +/** + * UML-RT semantics for {@link Parameter}. + */ +public class ParameterRTImpl extends org.eclipse.uml2.uml.internal.impl.ParameterImpl implements InternalUMLRTMultiplicityElement { + + private static final Set<EStructuralFeature> INHERITED_FEATURES = new HashSet<>(Arrays.asList( + UMLPackage.Literals.NAMED_ELEMENT__NAME, + UMLPackage.Literals.NAMED_ELEMENT__VISIBILITY, + UMLPackage.Literals.TYPED_ELEMENT__TYPE + /* Don't include multiplicity bounds because they forward for themselves */)); + + public ParameterRTImpl() { + super(); + } + + @Override + public EObject create(EClass eClass) { + EObject result; + + if (eClass.getEPackage() == eClass().getEPackage()) { + result = UMLRTUMLFactoryImpl.eINSTANCE.create(eClass); + } else { + result = super.create(eClass); + } + + return result; + } + + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case UMLPackage.PARAMETER__NAME: + return isSetName(); + case UMLPackage.PARAMETER__VISIBILITY: + return isSetVisibility(); + case UMLPackage.PARAMETER__TYPE: + return type != null; + case UMLPackage.PARAMETER__LOWER_VALUE: + return isSetLowerValue(); + case UMLPackage.PARAMETER__UPPER_VALUE: + return isSetUpperValue(); + default: + return super.eIsSet(featureID); + } + } + + @SuppressWarnings("unchecked") + @Override + public <T> T umlGet(int featureID) { + switch (featureID) { + case UMLPackage.PARAMETER__NAME: + return (T) super.getName(); + case UMLPackage.PARAMETER__VISIBILITY: + return (T) super.getVisibility(); + case UMLPackage.PARAMETER__TYPE: + return (T) super.getType(); + case UMLPackage.PARAMETER__LOWER_VALUE: + return (T) super.getLowerValue(); + case UMLPackage.PARAMETER__UPPER_VALUE: + return (T) super.getUpperValue(); + default: + return (T) super.eGet(featureID, true, true); + } + } + + @Override + public void eUnset(int featureID) { + switch (featureID) { + case UMLPackage.PARAMETER__LOWER_VALUE: + unsetLowerValue(); + break; + case UMLPackage.PARAMETER__UPPER_VALUE: + unsetUpperValue(); + break; + default: + super.eUnset(featureID); + break; + } + } + + @Override + public EObject eContainer() { + Element owner = rtOwner(); + return (owner != null) ? owner : super.eContainer(); + } + + @Override + public Resource eResource() { + Resource result = rtResource(); + + if (result instanceof ExtensionResource) { + EObject container = eContainer(); + if (container != null) { + result = container.eResource(); + } + } + + return result; + } + + @SuppressWarnings("unchecked") + @Override + public <R extends InternalUMLRTElement> R rtGetRedefinedElement() { + R result = null; + + Operation operation = getOperation(); + if ((operation != null) && (operation instanceof InternalUMLRTElement)) { + Operation redefined = ((InternalUMLRTElement) operation).rtGetRedefinedElement(); + if (redefined != null) { + int index = operation.getOwnedParameters().indexOf(this); + if ((index >= 0) && (index < redefined.getOwnedParameters().size())) { + Parameter parameter = redefined.getOwnedParameters().get(index); + if (parameter instanceof InternalUMLRTElement) { + result = (R) parameter; + } + } + } + } + + return result; + } + + @Override + public Collection<? extends EStructuralFeature> rtInheritedFeatures() { + return INHERITED_FEATURES; + } + + @Override + public void umlSetRedefinedElement(InternalUMLRTElement redefined) { + if (!(redefined instanceof Parameter)) { + throw new IllegalArgumentException("not a parameter: " + redefined); //$NON-NLS-1$ + } + + Parameter parameter = (Parameter) redefined; + int index = ((Operation) parameter.getOwner()).getOwnedParameters().indexOf(parameter); + if (index >= 0) { + EList<Parameter> parameters = ((Operation) getOwner()).getOwnedParameters(); + int myIndex = parameters.indexOf(this); + if (myIndex != index) { + parameters.move(index, myIndex); + } + } + } + + void handleRedefinedOperation(Operation operation) { + if (operation != null) { + NotificationForwarder.adapt(this, + () -> new NotificationForwarder(this, + /* FIXME: Function? */null, rtInheritedFeatures())); + } else if (eBasicHasAdapters()) { + NotificationForwarder.unadapt(this); + } + + // And let my bounds know + Parameter redefined = rtGetRedefinedElement(); + if (lowerValue instanceof InternalUMLRTValueSpecification) { + ((InternalUMLRTValueSpecification) lowerValue).handleRedefinedMultiplicityElement(redefined); + } + if (upperValue instanceof InternalUMLRTValueSpecification) { + ((InternalUMLRTValueSpecification) upperValue).handleRedefinedMultiplicityElement(redefined); + } + } + + @Override + public void rtReify() { + Operation operation = getOperation(); + if (operation != null) { + EReference containment = eContainmentFeature(); + if (containment == UMLPackage.Literals.BEHAVIORAL_FEATURE__OWNED_PARAMETER) { + // Either all parameters are real, or none. + EList<Parameter> parameters = operation.getOwnedParameters(); + if (parameters instanceof InheritableEList<?>) { + ((InheritableEList<Parameter>) parameters).touch(); + } + } + } + } + + @Override + public void rtVirtualize() { + Operation operation = getOperation(); + if (operation != null) { + EReference containment = eContainmentFeature(); + if (containment == UMLPackage.Literals.BEHAVIORAL_FEATURE__OWNED_PARAMETER) { + // Either all parameters are virtual, or none. + operation.eUnset(containment); + } + } + } + + @Override + public void rtUnsetAll() { + unsetName(); + unsetVisibility(); + setType(null); + unsetLowerValue(); + unsetUpperValue(); + } + + @Override + public Element basicGetOwner() { + return rtOwner(); + } + + @Override + public Operation basicGetOperation() { + Element owner = basicGetOwner(); + return (owner instanceof Operation) + ? (Operation) owner + : null; + } + + @Override + public String getName() { + return inheritFeature(UMLPackage.Literals.NAMED_ELEMENT__NAME); + } + + @Override + public void setName(String newName) { + // Make sure that the notification gets the correct old value + name = getName(); + super.setName(newName); + } + + @Override + public void unsetName() { + // Make sure that the notification gets the correct old and new values + String oldName = getName(); + boolean oldNameESet = (eFlags & NAME_ESETFLAG) != 0; + name = NAME_EDEFAULT; + eFlags = eFlags & ~NAME_ESETFLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.NAMED_ELEMENT__NAME, oldName, getName(), oldNameESet)); + } + } + + @Override + public VisibilityKind getVisibility() { + return inheritFeature(UMLPackage.Literals.NAMED_ELEMENT__VISIBILITY); + } + + @Override + public void setVisibility(VisibilityKind newVisibility) { + // Make sure that the notification gets the correct old value + if (newVisibility == null) { + newVisibility = VISIBILITY_EDEFAULT; + } + eFlags = eFlags | (getVisibility().ordinal() << VISIBILITY_EFLAG_OFFSET); + super.setVisibility(newVisibility); + } + + @Override + public void unsetVisibility() { + // Make sure that the notification gets the correct old and new values + VisibilityKind oldVisibility = getVisibility(); + boolean oldVisibilityESet = (eFlags & VISIBILITY_ESETFLAG) != 0; + eFlags = (eFlags & ~VISIBILITY_EFLAG) | VISIBILITY_EFLAG_DEFAULT; + eFlags = eFlags & ~VISIBILITY_ESETFLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.NAMED_ELEMENT__VISIBILITY, oldVisibility, getVisibility(), oldVisibilityESet)); + } + } + + @Override + public Type getType() { + return inheritFeature(UMLPackage.Literals.TYPED_ELEMENT__TYPE); + } + + @Override + public void setType(Type newType) { + // Make sure that the notification gets the correct old value + type = getType(); + super.setType(newType); + } + + @Override + public ValueSpecification umlGetLowerValue(boolean resolve) { + return resolve ? super.getLowerValue() : super.basicGetLowerValue(); + } + + @Override + public NotificationChain umlBasicSetLowerValue(ValueSpecification newLowerValue, NotificationChain msgs) { + return super.basicSetLowerValue(newLowerValue, msgs); + } + + @Override + public ValueSpecification getLowerValue() { + return MultiplicityElementOperations.getLowerValue(this); + } + + @Override + public void setLowerValue(ValueSpecification newLowerValue) { + MultiplicityElementOperations.setLowerValue(this, newLowerValue); + } + + public boolean isSetLowerValue() { + return MultiplicityElementOperations.isSetLowerValue(this); + } + + public void unsetLowerValue() { + MultiplicityElementOperations.unsetLowerValue(this); + } + + @Override + public ValueSpecification umlGetUpperValue(boolean resolve) { + return resolve ? super.getUpperValue() : super.basicGetUpperValue(); + } + + @Override + public NotificationChain umlBasicSetUpperValue(ValueSpecification newUpperValue, NotificationChain msgs) { + return super.basicSetUpperValue(newUpperValue, msgs); + } + + @Override + public ValueSpecification getUpperValue() { + return MultiplicityElementOperations.getUpperValue(this); + } + + @Override + public void setUpperValue(ValueSpecification newLowerValue) { + MultiplicityElementOperations.setUpperValue(this, newLowerValue); + } + + public boolean isSetUpperValue() { + return MultiplicityElementOperations.isSetUpperValue(this); + } + + public void unsetUpperValue() { + MultiplicityElementOperations.unsetUpperValue(this); + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/PortRTImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/PortRTImpl.java new file mode 100644 index 000000000..ed1faf23e --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/PortRTImpl.java @@ -0,0 +1,513 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTPort; +import org.eclipse.papyrusrt.umlrt.uml.internal.operations.MultiplicityElementOperations; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionResource; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.RedefinedElementsList; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.SubsetSupersetRedefinedElementsList; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.Namespace; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.Type; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.ValueSpecification; +import org.eclipse.uml2.uml.VisibilityKind; +import org.eclipse.uml2.uml.util.UMLUtil; + +/** + * UML-RT semantics for {@link Port}. + */ +public class PortRTImpl extends org.eclipse.uml2.uml.internal.impl.PortImpl implements InternalUMLRTMultiplicityElement { + + private static final int IS_SERVICE__SET_FLAG = 0x1 << 0; + private static final int IS_BEHAVIOR__SET_FLAG = 0x1 << 1; + private static final int IS_CONJUGATED__SET_FLAG = 0x1 << 2; + + private static final Set<EStructuralFeature> INHERITED_FEATURES = new HashSet<>(Arrays.asList( + UMLPackage.Literals.NAMED_ELEMENT__NAME, + UMLPackage.Literals.NAMED_ELEMENT__VISIBILITY, + UMLPackage.Literals.TYPED_ELEMENT__TYPE, + UMLPackage.Literals.PORT__IS_SERVICE, + UMLPackage.Literals.PORT__IS_BEHAVIOR, + UMLPackage.Literals.PORT__IS_CONJUGATED + /* Don't include multiplicity bounds because they forward for themselves */)); + + private int uFlags = 0x0; + + public PortRTImpl() { + super(); + } + + @Override + public EObject create(EClass eClass) { + EObject result; + + if (eClass.getEPackage() == eClass().getEPackage()) { + result = UMLRTUMLFactoryImpl.eINSTANCE.create(eClass); + } else { + result = super.create(eClass); + } + + return result; + } + + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case UMLPackage.PORT__NAME: + return isSetName(); + case UMLPackage.PORT__VISIBILITY: + return isSetVisibility(); + case UMLPackage.PORT__TYPE: + return type != null; + case UMLPackage.PORT__IS_SERVICE: + return isSetService(); + case UMLPackage.PORT__IS_BEHAVIOR: + return isSetBehavior(); + case UMLPackage.PORT__IS_CONJUGATED: + return isSetConjugated(); + case UMLPackage.PORT__LOWER_VALUE: + return isSetLowerValue(); + case UMLPackage.PORT__UPPER_VALUE: + return isSetUpperValue(); + default: + return super.eIsSet(featureID); + } + } + + @SuppressWarnings("unchecked") + @Override + public <T> T umlGet(int featureID) { + switch (featureID) { + case UMLPackage.PORT__NAME: + return (T) super.getName(); + case UMLPackage.PORT__VISIBILITY: + return (T) super.getVisibility(); + case UMLPackage.PORT__TYPE: + return (T) super.getType(); + case UMLPackage.PORT__IS_SERVICE: + return (T) (Boolean) super.isService(); + case UMLPackage.PORT__IS_BEHAVIOR: + return (T) (Boolean) super.isBehavior(); + case UMLPackage.PORT__IS_CONJUGATED: + return (T) (Boolean) super.isConjugated(); + case UMLPackage.PORT__LOWER_VALUE: + return (T) super.getLowerValue(); + case UMLPackage.PORT__UPPER_VALUE: + return (T) super.getUpperValue(); + default: + return (T) super.eGet(featureID, true, true); + } + } + + @Override + public void eUnset(int featureID) { + switch (featureID) { + case UMLPackage.PORT__LOWER_VALUE: + unsetLowerValue(); + break; + case UMLPackage.PORT__UPPER_VALUE: + unsetUpperValue(); + break; + case UMLPackage.PORT__IS_SERVICE: + unsetIsService(); + break; + case UMLPackage.PORT__IS_BEHAVIOR: + unsetIsBehavior(); + break; + case UMLPackage.PORT__IS_CONJUGATED: + unsetIsConjugated(); + break; + default: + super.eUnset(featureID); + break; + } + } + + @Override + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case UMLPackage.PORT__IS_SERVICE: + if (newValue == null) { + unsetIsService(); + } else { + setIsService((Boolean) newValue); + } + break; + case UMLPackage.PORT__IS_BEHAVIOR: + if (newValue == null) { + unsetIsBehavior(); + } else { + setIsBehavior((Boolean) newValue); + } + break; + case UMLPackage.PORT__IS_CONJUGATED: + if (newValue == null) { + unsetIsConjugated(); + } else { + setIsConjugated((Boolean) newValue); + } + break; + default: + super.eSet(featureID, newValue); + break; + } + } + + @Override + public void umlSetRedefinedElement(InternalUMLRTElement redefined) { + if (!(redefined instanceof Port)) { + throw new IllegalArgumentException("not a port: " + redefined); //$NON-NLS-1$ + } + ((RedefinedElementsList<Port>) getRedefinedPorts()).setRedefinedElement((Port) redefined); + } + + @Override + public EList<Port> getRedefinedPorts() { + if (redefinedPorts == null) { + redefinedPorts = new SubsetSupersetRedefinedElementsList<>( + Port.class, this, UMLPackage.PORT__REDEFINED_PORT, + REDEFINED_PORT_ESUPERSETS, null, + this::handleRedefinedPort); + } + return redefinedPorts; + } + + @Override + public Collection<? extends EStructuralFeature> rtInheritedFeatures() { + return INHERITED_FEATURES; + } + + void handleRedefinedPort(Port port) { + // Let my stereotype application know + RTPort stereo = UMLUtil.getStereotypeApplication(this, RTPort.class); + if (stereo instanceof RTPortRTImpl) { + ((RTPortRTImpl) stereo).handleRedefinedPort(port); + } + + // And my bounds + if (lowerValue instanceof InternalUMLRTValueSpecification) { + ((InternalUMLRTValueSpecification) lowerValue).handleRedefinedMultiplicityElement(port); + } + if (upperValue instanceof InternalUMLRTValueSpecification) { + ((InternalUMLRTValueSpecification) upperValue).handleRedefinedMultiplicityElement(port); + } + } + + @Override + public EObject eContainer() { + Element owner = rtOwner(); + return (owner != null) ? owner : super.eContainer(); + } + + @Override + public Resource eResource() { + Resource result = rtResource(); + + if (result instanceof ExtensionResource) { + EObject container = eContainer(); + if (container != null) { + result = container.eResource(); + } + } + + return result; + } + + @Override + public void rtReify() { + Class class_ = getClass_(); + if ((class_ != null) && !class_.getOwnedPorts().contains(this)) { + class_.getOwnedPorts().add(this); + rtAdjustStereotypes(); + } + } + + @Override + public void rtVirtualize() { + Namespace namespace = getNamespace(); + if (namespace instanceof Class) { + Class class_ = (Class) namespace; + + @SuppressWarnings("unchecked") + EList<? super Port> implicitPorts = (EList<? super Port>) class_.eGet(ExtUMLExtPackage.Literals.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT); + if (!implicitPorts.contains(this)) { + implicitPorts.add(this); + rtAdjustStereotypes(); + } + } + } + + @Override + public void rtUnsetAll() { + unsetName(); + unsetVisibility(); + setType(null); + unsetLowerValue(); + unsetUpperValue(); + unsetIsBehavior(); + unsetIsConjugated(); + unsetIsService(); + + getStereotypeApplications().stream() + .filter(InternalUMLRTElement.class::isInstance) + .map(InternalUMLRTElement.class::cast) + .forEach(InternalUMLRTElement::rtUnsetAll); + } + + @Override + public Element basicGetOwner() { + return rtOwner(); + } + + @Override + public Class basicGetClass_() { + Element rtOwner = rtOwner(); + return (rtOwner instanceof org.eclipse.uml2.uml.Class) + ? (org.eclipse.uml2.uml.Class) rtOwner + : null; + } + + @Override + public String getName() { + return inheritFeature(UMLPackage.Literals.NAMED_ELEMENT__NAME); + } + + @Override + public void setName(String newName) { + // Make sure that the notification gets the correct old value + name = getName(); + super.setName(newName); + } + + @Override + public void unsetName() { + // Make sure that the notification gets the correct old and new values + String oldName = getName(); + boolean oldNameESet = (eFlags & NAME_ESETFLAG) != 0; + name = NAME_EDEFAULT; + eFlags = eFlags & ~NAME_ESETFLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.NAMED_ELEMENT__NAME, oldName, getName(), oldNameESet)); + } + } + + @Override + public VisibilityKind getVisibility() { + return inheritFeature(UMLPackage.Literals.NAMED_ELEMENT__VISIBILITY); + } + + @Override + public void setVisibility(VisibilityKind newVisibility) { + // Make sure that the notification gets the correct old value + if (newVisibility == null) { + newVisibility = VISIBILITY_EDEFAULT; + } + eFlags = eFlags | (getVisibility().ordinal() << VISIBILITY_EFLAG_OFFSET); + super.setVisibility(newVisibility); + } + + @Override + public void unsetVisibility() { + // Make sure that the notification gets the correct old and new values + VisibilityKind oldVisibility = getVisibility(); + boolean oldVisibilityESet = (eFlags & VISIBILITY_ESETFLAG) != 0; + eFlags = (eFlags & ~VISIBILITY_EFLAG) | VISIBILITY_EFLAG_DEFAULT; + eFlags = eFlags & ~VISIBILITY_ESETFLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.NAMED_ELEMENT__VISIBILITY, oldVisibility, getVisibility(), oldVisibilityESet)); + } + } + + @Override + public Type getType() { + return inheritFeature(UMLPackage.Literals.TYPED_ELEMENT__TYPE); + } + + @Override + public void setType(Type newType) { + // Make sure that the notification gets the correct old value + type = getType(); + super.setType(newType); + } + + public boolean isSetService() { + return (uFlags & IS_SERVICE__SET_FLAG) != 0; + } + + @Override + public boolean isService() { + return inheritFeature(UMLPackage.Literals.PORT__IS_SERVICE); + } + + @Override + public void setIsService(boolean newIsService) { + boolean wasSet = isSetService(); + boolean oldIsService = isService(); + + eFlags = newIsService ? (eFlags | IS_SERVICE_EFLAG) : (eFlags & ~IS_SERVICE_EFLAG); + uFlags = uFlags | IS_SERVICE__SET_FLAG; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, + UMLPackage.PORT__IS_SERVICE, oldIsService, newIsService, !wasSet)); + } + + public void unsetIsService() { + boolean wasSet = isSetService(); + boolean oldIsService = isService(); + + eFlags = IS_SERVICE_EDEFAULT ? (eFlags | IS_SERVICE_EFLAG) : (eFlags & ~IS_SERVICE_EFLAG); + uFlags = uFlags & ~IS_SERVICE__SET_FLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.PORT__IS_SERVICE, oldIsService, isService(), wasSet)); + } + } + + public boolean isSetBehavior() { + return (uFlags & IS_BEHAVIOR__SET_FLAG) != 0; + } + + @Override + public boolean isBehavior() { + return inheritFeature(UMLPackage.Literals.PORT__IS_BEHAVIOR); + } + + @Override + public void setIsBehavior(boolean newIsBehavior) { + boolean wasSet = isSetBehavior(); + boolean oldIsBehavior = isBehavior(); + + eFlags = newIsBehavior ? (eFlags | IS_BEHAVIOR_EFLAG) : (eFlags & ~IS_BEHAVIOR_EFLAG); + uFlags = uFlags | IS_BEHAVIOR__SET_FLAG; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, + UMLPackage.PORT__IS_BEHAVIOR, oldIsBehavior, newIsBehavior, !wasSet)); + } + + public void unsetIsBehavior() { + boolean wasSet = isSetBehavior(); + boolean oldIsBehavior = isBehavior(); + + eFlags = IS_BEHAVIOR_EDEFAULT ? (eFlags | IS_BEHAVIOR_EFLAG) : (eFlags & ~IS_BEHAVIOR_EFLAG); + uFlags = uFlags & ~IS_BEHAVIOR__SET_FLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.PORT__IS_BEHAVIOR, oldIsBehavior, isBehavior(), wasSet)); + } + } + + public boolean isSetConjugated() { + return (uFlags & IS_CONJUGATED__SET_FLAG) != 0; + } + + @Override + public boolean isConjugated() { + return inheritFeature(UMLPackage.Literals.PORT__IS_CONJUGATED); + } + + @Override + public void setIsConjugated(boolean newIsConjugated) { + boolean wasSet = isSetConjugated(); + boolean oldIsConjugated = isConjugated(); + + eFlags = newIsConjugated ? (eFlags | IS_CONJUGATED_EFLAG) : (eFlags & ~IS_CONJUGATED_EFLAG); + uFlags = uFlags | IS_CONJUGATED__SET_FLAG; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, + UMLPackage.PORT__IS_CONJUGATED, oldIsConjugated, newIsConjugated, !wasSet)); + } + + public void unsetIsConjugated() { + boolean wasSet = isSetConjugated(); + boolean oldIsConjugated = isConjugated(); + + eFlags = IS_CONJUGATED_EDEFAULT ? (eFlags | IS_CONJUGATED_EFLAG) : (eFlags & ~IS_CONJUGATED_EFLAG); + uFlags = uFlags & ~IS_CONJUGATED__SET_FLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.PORT__IS_CONJUGATED, oldIsConjugated, isConjugated(), wasSet)); + } + } + + @Override + public ValueSpecification umlGetLowerValue(boolean resolve) { + return resolve ? super.getLowerValue() : super.basicGetLowerValue(); + } + + @Override + public NotificationChain umlBasicSetLowerValue(ValueSpecification newLowerValue, NotificationChain msgs) { + return super.basicSetLowerValue(newLowerValue, msgs); + } + + @Override + public ValueSpecification getLowerValue() { + return MultiplicityElementOperations.getLowerValue(this); + } + + @Override + public void setLowerValue(ValueSpecification newLowerValue) { + MultiplicityElementOperations.setLowerValue(this, newLowerValue); + } + + public boolean isSetLowerValue() { + return MultiplicityElementOperations.isSetLowerValue(this); + } + + public void unsetLowerValue() { + MultiplicityElementOperations.unsetLowerValue(this); + } + + @Override + public ValueSpecification umlGetUpperValue(boolean resolve) { + return resolve ? super.getUpperValue() : super.basicGetUpperValue(); + } + + @Override + public NotificationChain umlBasicSetUpperValue(ValueSpecification newUpperValue, NotificationChain msgs) { + return super.basicSetUpperValue(newUpperValue, msgs); + } + + @Override + public ValueSpecification getUpperValue() { + return MultiplicityElementOperations.getUpperValue(this); + } + + @Override + public void setUpperValue(ValueSpecification newLowerValue) { + MultiplicityElementOperations.setUpperValue(this, newLowerValue); + } + + public boolean isSetUpperValue() { + return MultiplicityElementOperations.isSetUpperValue(this); + } + + public void unsetUpperValue() { + MultiplicityElementOperations.unsetUpperValue(this); + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/PropertyRTImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/PropertyRTImpl.java new file mode 100644 index 000000000..3538a1567 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/PropertyRTImpl.java @@ -0,0 +1,388 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.papyrusrt.umlrt.uml.internal.operations.MultiplicityElementOperations; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionResource; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.RedefinedElementsList; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.RedefinedElementsListImpl; +import org.eclipse.uml2.uml.AggregationKind; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.Namespace; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.Type; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.ValueSpecification; +import org.eclipse.uml2.uml.VisibilityKind; + +/** + * UML-RT semantics for {@link Property}. + */ +public class PropertyRTImpl extends org.eclipse.uml2.uml.internal.impl.PropertyImpl implements InternalUMLRTMultiplicityElement { + + private static final int AGGREGATION__SET_FLAG = 0x1 << 0; + + private static final Set<EStructuralFeature> INHERITED_FEATURES = new HashSet<>(Arrays.asList( + UMLPackage.Literals.NAMED_ELEMENT__NAME, + UMLPackage.Literals.NAMED_ELEMENT__VISIBILITY, + UMLPackage.Literals.TYPED_ELEMENT__TYPE, + UMLPackage.Literals.PROPERTY__AGGREGATION + /* Don't include multiplicity bounds because they forward for themselves */)); + + private int uFlags = 0x0; + + protected PropertyRTImpl() { + super(); + } + + @Override + public EObject create(EClass eClass) { + EObject result; + + if (eClass.getEPackage() == eClass().getEPackage()) { + result = UMLRTUMLFactoryImpl.eINSTANCE.create(eClass); + } else { + result = super.create(eClass); + } + + return result; + } + + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case UMLPackage.PROPERTY__NAME: + return isSetName(); + case UMLPackage.PROPERTY__VISIBILITY: + return isSetVisibility(); + case UMLPackage.PROPERTY__TYPE: + return type != null; + case UMLPackage.PROPERTY__LOWER_VALUE: + return isSetLowerValue(); + case UMLPackage.PROPERTY__UPPER_VALUE: + return isSetUpperValue(); + case UMLPackage.PROPERTY__AGGREGATION: + return isSetAggregation(); + default: + return super.eIsSet(featureID); + } + } + + @SuppressWarnings("unchecked") + @Override + public <T> T umlGet(int featureID) { + switch (featureID) { + case UMLPackage.PROPERTY__NAME: + return (T) super.getName(); + case UMLPackage.PROPERTY__VISIBILITY: + return (T) super.getVisibility(); + case UMLPackage.PROPERTY__TYPE: + return (T) super.getType(); + case UMLPackage.PROPERTY__LOWER_VALUE: + return (T) super.getLowerValue(); + case UMLPackage.PROPERTY__UPPER_VALUE: + return (T) super.getUpperValue(); + case UMLPackage.PROPERTY__AGGREGATION: + return (T) super.getAggregation(); + default: + return (T) super.eGet(featureID, true, true); + } + } + + + @Override + public void eUnset(int featureID) { + switch (featureID) { + case UMLPackage.PROPERTY__LOWER_VALUE: + unsetLowerValue(); + break; + case UMLPackage.PROPERTY__UPPER_VALUE: + unsetUpperValue(); + break; + case UMLPackage.PROPERTY__AGGREGATION: + unsetAggregation(); + break; + default: + super.eUnset(featureID); + break; + } + } + + @Override + public void umlSetRedefinedElement(InternalUMLRTElement redefined) { + if (!(redefined instanceof Property)) { + throw new IllegalArgumentException("not a property: " + redefined); //$NON-NLS-1$ + } + + ((RedefinedElementsList<Property>) getRedefinedProperties()).setRedefinedElement((Property) redefined); + } + + @Override + public EList<Property> getRedefinedProperties() { + if (redefinedProperties == null) { + redefinedProperties = new RedefinedElementsListImpl<>( + Property.class, this, UMLPackage.PROPERTY__REDEFINED_PROPERTY, + this::handleRedefinedProperty); + } + return redefinedProperties; + } + + void handleRedefinedProperty(Property property) { + // Let my bounds know + if (lowerValue instanceof InternalUMLRTValueSpecification) { + ((InternalUMLRTValueSpecification) lowerValue).handleRedefinedMultiplicityElement(property); + } + if (upperValue instanceof InternalUMLRTValueSpecification) { + ((InternalUMLRTValueSpecification) upperValue).handleRedefinedMultiplicityElement(property); + } + } + + @Override + public Collection<? extends EStructuralFeature> rtInheritedFeatures() { + return INHERITED_FEATURES; + } + + @Override + public EObject eContainer() { + Element owner = rtOwner(); + return (owner != null) ? owner : super.eContainer(); + } + + @Override + public Resource eResource() { + Resource result = rtResource(); + + if (result instanceof ExtensionResource) { + EObject container = eContainer(); + if (container != null) { + result = container.eResource(); + } + } + + return result; + } + + @Override + public void rtReify() { + Class class_ = getClass_(); + if ((class_ != null) && !class_.getOwnedAttributes().contains(this)) { + class_.getOwnedAttributes().add(this); + rtAdjustStereotypes(); + } + } + + @Override + public void rtVirtualize() { + Namespace namespace = getNamespace(); + if (namespace instanceof Class) { + Class class_ = (Class) namespace; + + @SuppressWarnings("unchecked") + EList<? super Property> implicitAttributes = (EList<? super Property>) class_.eGet(ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE); + if (!implicitAttributes.contains(this)) { + implicitAttributes.add(this); + rtAdjustStereotypes(); + } + } + } + + @Override + public void rtUnsetAll() { + unsetName(); + unsetVisibility(); + setType(null); + unsetLowerValue(); + unsetUpperValue(); + unsetAggregation(); + } + + @Override + public Element basicGetOwner() { + return rtOwner(); + } + + @Override + public Class basicGetClass_() { + Element rtOwner = rtOwner(); + return (rtOwner instanceof org.eclipse.uml2.uml.Class) + ? (org.eclipse.uml2.uml.Class) rtOwner + : null; + } + + @Override + public String getName() { + return inheritFeature(UMLPackage.Literals.NAMED_ELEMENT__NAME); + } + + @Override + public void setName(String newName) { + // Make sure that the notification gets the correct old value + name = getName(); + super.setName(newName); + } + + @Override + public void unsetName() { + // Make sure that the notification gets the correct old and new values + String oldName = getName(); + boolean oldNameESet = (eFlags & NAME_ESETFLAG) != 0; + name = NAME_EDEFAULT; + eFlags = eFlags & ~NAME_ESETFLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.NAMED_ELEMENT__NAME, oldName, getName(), oldNameESet)); + } + } + + @Override + public VisibilityKind getVisibility() { + return inheritFeature(UMLPackage.Literals.NAMED_ELEMENT__VISIBILITY); + } + + @Override + public void setVisibility(VisibilityKind newVisibility) { + // Make sure that the notification gets the correct old value + if (newVisibility == null) { + newVisibility = VISIBILITY_EDEFAULT; + } + eFlags = eFlags | (getVisibility().ordinal() << VISIBILITY_EFLAG_OFFSET); + super.setVisibility(newVisibility); + } + + @Override + public void unsetVisibility() { + // Make sure that the notification gets the correct old and new values + VisibilityKind oldVisibility = getVisibility(); + boolean oldVisibilityESet = (eFlags & VISIBILITY_ESETFLAG) != 0; + eFlags = (eFlags & ~VISIBILITY_EFLAG) | VISIBILITY_EFLAG_DEFAULT; + eFlags = eFlags & ~VISIBILITY_ESETFLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.NAMED_ELEMENT__VISIBILITY, oldVisibility, getVisibility(), oldVisibilityESet)); + } + } + + @Override + public Type getType() { + return inheritFeature(UMLPackage.Literals.TYPED_ELEMENT__TYPE); + } + + @Override + public void setType(Type newType) { + // Make sure that the notification gets the correct old value + type = getType(); + super.setType(newType); + } + + @Override + public AggregationKind getAggregation() { + return inheritFeature(UMLPackage.Literals.PROPERTY__AGGREGATION); + } + + @Override + public void setAggregation(AggregationKind newAggregation) { + // Make sure that the notification gets the correct old value + if (newAggregation == null) { + newAggregation = AGGREGATION_EDEFAULT; + } + eFlags = eFlags | (getAggregation().ordinal() << AGGREGATION_EFLAG_OFFSET); + uFlags = uFlags | AGGREGATION__SET_FLAG; + super.setAggregation(newAggregation); + } + + public boolean isSetAggregation() { + return (uFlags & AGGREGATION__SET_FLAG) != 0; + } + + public void unsetAggregation() { + // Make sure that the notification gets the correct old and new values + AggregationKind oldAggregation = getAggregation(); + boolean wasSet = isSetAggregation(); + + eFlags = (eFlags & ~AGGREGATION_EFLAG) | AGGREGATION_EFLAG_DEFAULT; + uFlags = uFlags & ~AGGREGATION__SET_FLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLPackage.PROPERTY__AGGREGATION, oldAggregation, getAggregation(), wasSet)); + } + } + + @Override + public ValueSpecification umlGetLowerValue(boolean resolve) { + return resolve ? super.getLowerValue() : super.basicGetLowerValue(); + } + + @Override + public NotificationChain umlBasicSetLowerValue(ValueSpecification newLowerValue, NotificationChain msgs) { + return super.basicSetLowerValue(newLowerValue, msgs); + } + + @Override + public ValueSpecification getLowerValue() { + return MultiplicityElementOperations.getLowerValue(this); + } + + @Override + public void setLowerValue(ValueSpecification newLowerValue) { + MultiplicityElementOperations.setLowerValue(this, newLowerValue); + } + + public boolean isSetLowerValue() { + return MultiplicityElementOperations.isSetLowerValue(this); + } + + public void unsetLowerValue() { + MultiplicityElementOperations.unsetLowerValue(this); + } + + @Override + public ValueSpecification umlGetUpperValue(boolean resolve) { + return resolve ? super.getUpperValue() : super.basicGetUpperValue(); + } + + @Override + public NotificationChain umlBasicSetUpperValue(ValueSpecification newUpperValue, NotificationChain msgs) { + return super.basicSetUpperValue(newUpperValue, msgs); + } + + @Override + public ValueSpecification getUpperValue() { + return MultiplicityElementOperations.getUpperValue(this); + } + + @Override + public void setUpperValue(ValueSpecification newLowerValue) { + MultiplicityElementOperations.setUpperValue(this, newLowerValue); + } + + public boolean isSetUpperValue() { + return MultiplicityElementOperations.isSetUpperValue(this); + } + + public void unsetUpperValue() { + MultiplicityElementOperations.unsetUpperValue(this); + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/RTPortRTImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/RTPortRTImpl.java new file mode 100644 index 000000000..8b2aa6f05 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/RTPortRTImpl.java @@ -0,0 +1,414 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.PortRegistrationType; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTPort; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.NotificationForwarder; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.util.UMLUtil; + +/** + * UML-RT semantics for {@link RTPort}. + */ +public class RTPortRTImpl extends org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.impl.RTPortImpl implements InternalUMLRTElement { + + private static final int IS_NOTIFICATION__SET_FLAG = 0x1 << 0; + private static final int IS_PUBLISH__SET_FLAG = 0x1 << 1; + private static final int IS_WIRED__SET_FLAG = 0x1 << 2; + private static final int REGISTRATION__SET_FLAG = 0x1 << 3; + private static final int REGISTRATION_OVERRIDE__SET_FLAG = 0x1 << 4; + + private static final Set<EStructuralFeature> INHERITED_FEATURES = new HashSet<>(Arrays.asList( + UMLRealTimePackage.Literals.RT_PORT__IS_NOTIFICATION, + UMLRealTimePackage.Literals.RT_PORT__IS_PUBLISH, + UMLRealTimePackage.Literals.RT_PORT__IS_WIRED, + UMLRealTimePackage.Literals.RT_PORT__REGISTRATION, + UMLRealTimePackage.Literals.RT_PORT__REGISTRATION_OVERRIDE)); + + private int uFlags = 0x0; + + protected RTPortRTImpl() { + super(); + } + + @Override + public EObject create(EClass eClass) { + EPackage ePackage = eClass.getEPackage(); + return (ePackage == UMLPackage.eINSTANCE) + ? UMLRTUMLFactoryImpl.eINSTANCE.create(eClass) + : (ePackage == UMLRealTimePackage.eINSTANCE) + ? UMLRTUMLRealTimeFactoryImpl.eINSTANCE.create(eClass) + : ePackage.getEFactoryInstance().create(eClass); + } + + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case UMLRealTimePackage.RT_PORT__IS_NOTIFICATION: + return isSetNotification(); + case UMLRealTimePackage.RT_PORT__IS_PUBLISH: + return isSetPublish(); + case UMLRealTimePackage.RT_PORT__IS_WIRED: + return isSetWired(); + case UMLRealTimePackage.RT_PORT__REGISTRATION: + return isSetRegistration(); + case UMLRealTimePackage.RT_PORT__REGISTRATION_OVERRIDE: + return isSetRegistrationOverride(); + default: + return super.eIsSet(featureID); + } + } + + @SuppressWarnings("unchecked") + @Override + public <T> T umlGet(int featureID) { + switch (featureID) { + case UMLRealTimePackage.RT_PORT__IS_NOTIFICATION: + return (T) (Boolean) super.isNotification(); + case UMLRealTimePackage.RT_PORT__IS_PUBLISH: + return (T) (Boolean) super.isPublish(); + case UMLRealTimePackage.RT_PORT__IS_WIRED: + return (T) (Boolean) super.isWired(); + case UMLRealTimePackage.RT_PORT__REGISTRATION: + return (T) super.getRegistration(); + case UMLRealTimePackage.RT_PORT__REGISTRATION_OVERRIDE: + return (T) super.getRegistrationOverride(); + default: + return (T) super.eGet(featureID, true, true); + } + } + + @Override + public void eUnset(int featureID) { + switch (featureID) { + case UMLRealTimePackage.RT_PORT__IS_NOTIFICATION: + unsetIsNotification(); + break; + case UMLRealTimePackage.RT_PORT__IS_PUBLISH: + unsetIsPublish(); + break; + case UMLRealTimePackage.RT_PORT__IS_WIRED: + unsetIsWired(); + break; + case UMLRealTimePackage.RT_PORT__REGISTRATION: + unsetRegistration(); + break; + case UMLRealTimePackage.RT_PORT__REGISTRATION_OVERRIDE: + unsetRegistrationOverride(); + break; + default: + super.eUnset(featureID); + break; + } + } + + @Override + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case UMLRealTimePackage.RT_PORT__IS_NOTIFICATION: + if (newValue == null) { + unsetIsNotification(); + } else { + setIsNotification((Boolean) newValue); + } + break; + case UMLRealTimePackage.RT_PORT__IS_PUBLISH: + if (newValue == null) { + unsetIsPublish(); + } else { + setIsPublish((Boolean) newValue); + } + break; + case UMLRealTimePackage.RT_PORT__IS_WIRED: + if (newValue == null) { + unsetIsWired(); + } else { + setIsWired((Boolean) newValue); + } + break; + case UMLRealTimePackage.RT_PORT__REGISTRATION: + if (newValue == null) { + unsetRegistration(); + } else { + setRegistration((PortRegistrationType) newValue); + } + break; + case UMLRealTimePackage.RT_PORT__REGISTRATION_OVERRIDE: + setRegistrationOverride((String) newValue); + break; + default: + super.eSet(featureID, newValue); + break; + } + } + + @Override + public void umlSetRedefinedElement(InternalUMLRTElement redefined) { + if (!(redefined instanceof RTPort)) { + throw new IllegalArgumentException("not an rtPort: " + redefined); //$NON-NLS-1$ + } + + RTPort rtPort = (RTPort) redefined; + Port port = rtPort.getBase_Port(); + Port base = getBase_Port(); + if ((port instanceof InternalUMLRTElement) && (base instanceof InternalUMLRTElement)) { + ((InternalUMLRTElement) base).umlSetRedefinedElement((InternalUMLRTElement) port); + } + } + + @Override + public <R extends InternalUMLRTElement> R rtGetRedefinedElement() { + R result = null; + + Port base = getBase_Port(); + if (base instanceof InternalUMLRTElement) { + Port redefined = ((InternalUMLRTElement) base).rtGetRedefinedElement(); + if (redefined != null) { + RTPort redefinedRTPort = UMLUtil.getStereotypeApplication(redefined, RTPort.class); + if (redefinedRTPort instanceof InternalUMLRTElement) { + @SuppressWarnings("unchecked") + R redefinedR = (R) redefinedRTPort; + result = redefinedR; + } + } + } + + return result; + } + + @Override + public Collection<? extends EStructuralFeature> rtInheritedFeatures() { + return INHERITED_FEATURES; + } + + void handleRedefinedPort(Port port) { + if (port != null) { + NotificationForwarder.adapt(this, () -> new NotificationForwarder.FromStereotype(this, + UMLRealTimePackage.Literals.RT_PORT__BASE_PORT, + UMLPackage.Literals.PORT__REDEFINED_PORT, + rtInheritedFeatures())); + } else if (eBasicHasAdapters()) { + NotificationForwarder.unadapt(this); + } + } + + @Override + public void rtReify() { + Port base = getBase_Port(); + if (base instanceof InternalUMLRTElement) { + ((InternalUMLRTElement) base).rtReify(); + } + } + + @Override + public void rtVirtualize() { + Port base = getBase_Port(); + if (base instanceof InternalUMLRTElement) { + ((InternalUMLRTElement) base).rtVirtualize(); + } + } + + @Override + public void rtUnsetAll() { + unsetIsNotification(); + unsetIsPublish(); + unsetIsWired(); + unsetRegistration(); + unsetRegistrationOverride(); + } + + @Override + public void setBase_Port(Port newBase_Port) { + super.setBase_Port(newBase_Port); + + if (newBase_Port instanceof InternalUMLRTElement) { + Port redefined = (Port) ((InternalUMLRTElement) newBase_Port).rtGetRedefinedElement(); + handleRedefinedPort(redefined); + } else { + handleRedefinedPort(null); + } + } + + public boolean isSetNotification() { + return (uFlags & IS_NOTIFICATION__SET_FLAG) != 0; + } + + @Override + public boolean isNotification() { + return inheritFeature(UMLRealTimePackage.Literals.RT_PORT__IS_NOTIFICATION); + } + + @Override + public void setIsNotification(boolean newIsNotification) { + boolean wasSet = isSetNotification(); + boolean oldIsNotification = isNotification(); + + isNotification = isNotification(); + uFlags = uFlags | IS_NOTIFICATION__SET_FLAG; + isNotification = newIsNotification; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, UMLRealTimePackage.RT_PORT__IS_NOTIFICATION, oldIsNotification, isNotification, !wasSet)); + } + + public void unsetIsNotification() { + boolean wasSet = isSetNotification(); + boolean oldIsNotification = isNotification(); + + isNotification = IS_NOTIFICATION_EDEFAULT; + uFlags = uFlags & ~IS_NOTIFICATION__SET_FLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLRealTimePackage.RT_PORT__IS_NOTIFICATION, oldIsNotification, isNotification(), wasSet)); + } + } + + public boolean isSetPublish() { + return (uFlags & IS_PUBLISH__SET_FLAG) != 0; + } + + @Override + public boolean isPublish() { + return inheritFeature(UMLRealTimePackage.Literals.RT_PORT__IS_PUBLISH); + } + + @Override + public void setIsPublish(boolean newIsPublish) { + boolean wasSet = isSetPublish(); + boolean oldIsPublish = isPublish; + + uFlags = uFlags | IS_PUBLISH__SET_FLAG; + isPublish = newIsPublish; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, UMLRealTimePackage.RT_PORT__IS_PUBLISH, oldIsPublish, isPublish, !wasSet)); + } + + public void unsetIsPublish() { + boolean wasSet = isSetPublish(); + boolean oldIsPublish = isPublish; + + isPublish = IS_PUBLISH_EDEFAULT; + uFlags = uFlags & ~IS_PUBLISH__SET_FLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLRealTimePackage.RT_PORT__IS_PUBLISH, oldIsPublish, isPublish(), wasSet)); + } + } + + public boolean isSetWired() { + return (uFlags & IS_WIRED__SET_FLAG) != 0; + } + + @Override + public boolean isWired() { + return inheritFeature(UMLRealTimePackage.Literals.RT_PORT__IS_WIRED); + } + + @Override + public void setIsWired(boolean newIsWired) { + boolean wasSet = isSetWired(); + boolean oldIsWired = isWired(); + + uFlags = uFlags | IS_WIRED__SET_FLAG; + isWired = newIsWired; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, UMLRealTimePackage.RT_PORT__IS_WIRED, oldIsWired, isWired, !wasSet)); + } + + public void unsetIsWired() { + boolean wasSet = isSetWired(); + boolean oldIsWired = isWired(); + + isWired = IS_WIRED_EDEFAULT; + uFlags = uFlags & ~IS_WIRED__SET_FLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLRealTimePackage.RT_PORT__IS_WIRED, oldIsWired, isWired(), wasSet)); + } + } + + public boolean isSetRegistration() { + return (uFlags & REGISTRATION__SET_FLAG) != 0; + } + + @Override + public PortRegistrationType getRegistration() { + return inheritFeature(UMLRealTimePackage.Literals.RT_PORT__REGISTRATION); + } + + @Override + public void setRegistration(PortRegistrationType newRegistration) { + boolean wasSet = isSetRegistration(); + PortRegistrationType oldRegistration = registration; + + uFlags = uFlags | REGISTRATION__SET_FLAG; + registration = newRegistration == null ? REGISTRATION_EDEFAULT : newRegistration; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, UMLRealTimePackage.RT_PORT__REGISTRATION, oldRegistration, registration, !wasSet)); + } + + public void unsetRegistration() { + boolean wasSet = isSetRegistration(); + PortRegistrationType oldRegistration = getRegistration(); + + registration = REGISTRATION_EDEFAULT; + uFlags = uFlags & ~REGISTRATION__SET_FLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.UNSET, UMLRealTimePackage.RT_PORT__REGISTRATION, oldRegistration, getRegistration(), wasSet)); + } + } + + public boolean isSetRegistrationOverride() { + return (uFlags & REGISTRATION_OVERRIDE__SET_FLAG) != 0; + } + + @Override + public String getRegistrationOverride() { + return inheritFeature(UMLRealTimePackage.Literals.RT_PORT__REGISTRATION_OVERRIDE); + } + + @Override + public void setRegistrationOverride(String newRegistrationOverride) { + boolean wasSet = isSetRegistrationOverride(); + String oldRegistrationOverride = registrationOverride; + + registrationOverride = getRegistrationOverride(); + uFlags = uFlags | REGISTRATION_OVERRIDE__SET_FLAG; + registrationOverride = newRegistrationOverride; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, UMLRealTimePackage.RT_PORT__REGISTRATION_OVERRIDE, oldRegistrationOverride, registrationOverride, !wasSet)); + } + + public void unsetRegistrationOverride() { + boolean wasSet = isSetRegistrationOverride(); + String oldRegistrationOverride = registrationOverride; + + registrationOverride = REGISTRATION_OVERRIDE_EDEFAULT; + uFlags = uFlags & ~REGISTRATION_OVERRIDE__SET_FLAG; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.SET, UMLRealTimePackage.RT_PORT__REGISTRATION_OVERRIDE, oldRegistrationOverride, getRegistrationOverride(), wasSet)); + } + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/UMLRTUMLFactoryImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/UMLRTUMLFactoryImpl.java new file mode 100644 index 000000000..9c0db813f --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/UMLRTUMLFactoryImpl.java @@ -0,0 +1,151 @@ +/***************************************************************************** + * Copyright (c) 2016, 2017 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import java.lang.reflect.Proxy; + +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.util.BasicExtendedMetaData; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Collaboration; +import org.eclipse.uml2.uml.Connector; +import org.eclipse.uml2.uml.ConnectorEnd; +import org.eclipse.uml2.uml.Interface; +import org.eclipse.uml2.uml.LiteralInteger; +import org.eclipse.uml2.uml.LiteralString; +import org.eclipse.uml2.uml.LiteralUnlimitedNatural; +import org.eclipse.uml2.uml.Model; +import org.eclipse.uml2.uml.OpaqueExpression; +import org.eclipse.uml2.uml.Operation; +import org.eclipse.uml2.uml.Package; +import org.eclipse.uml2.uml.Parameter; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.UMLFactory; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.internal.impl.UMLFactoryImpl; + +/** + * @author damus + * + */ +public class UMLRTUMLFactoryImpl extends UMLFactoryImpl { + + public static final UMLFactory eINSTANCE = new UMLRTUMLFactoryImpl(); + + private final UMLPackage umlPackage; + + /** + * Initializes me. + */ + public UMLRTUMLFactoryImpl() { + super(); + + // A shim for the UMLPackage that provides me as its factory + this.umlPackage = (UMLPackage) Proxy.newProxyInstance(getClass().getClassLoader(), + new java.lang.Class[] { + UMLPackage.class, + BasicExtendedMetaData.EPackageExtendedMetaData.Holder.class, + }, + (proxy, method, args) -> { + switch (method.getName()) { + case "getEFactoryInstance": //$NON-NLS-1$ + case "getUMLFactory": //$NON-NLS-1$ + return UMLRTUMLFactoryImpl.eINSTANCE; + default: + return method.invoke(UMLPackage.eINSTANCE, args); + } + }); + } + + @Override + public EPackage getEPackage() { + return umlPackage; + } + + @Override + public Class createClass() { + return new ClassRTImpl(); + } + + @Override + public Collaboration createCollaboration() { + return new CollaborationRTImpl(); + } + + @Override + public Connector createConnector() { + return new ConnectorRTImpl(); + } + + @Override + public ConnectorEnd createConnectorEnd() { + return new ConnectorEndRTImpl(); + } + + @Override + public Interface createInterface() { + return new InterfaceRTImpl(); + } + + @Override + public LiteralInteger createLiteralInteger() { + return new LiteralIntegerRTImpl(); + } + + @Override + public LiteralUnlimitedNatural createLiteralUnlimitedNatural() { + return new LiteralUnlimitedNaturalRTImpl(); + } + + @Override + public LiteralString createLiteralString() { + return new LiteralStringRTImpl(); + } + + @Override + public Model createModel() { + return new ModelRTImpl(); + } + + @Override + public OpaqueExpression createOpaqueExpression() { + return new OpaqueExpressionRTImpl(); + } + + @Override + public Operation createOperation() { + return new OperationRTImpl(); + } + + @Override + public Package createPackage() { + return new PackageRTImpl(); + } + + @Override + public Parameter createParameter() { + return new ParameterRTImpl(); + } + + @Override + public Port createPort() { + return new PortRTImpl(); + } + + @Override + public Property createProperty() { + return new PropertyRTImpl(); + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/UMLRTUMLRealTimeFactoryImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/UMLRTUMLRealTimeFactoryImpl.java new file mode 100644 index 000000000..d9c007d4c --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/impl/UMLRTUMLRealTimeFactoryImpl.java @@ -0,0 +1,67 @@ +/***************************************************************************** + * Copyright (c) 2016, 2017 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.impl; + +import java.lang.reflect.Proxy; + +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.util.BasicExtendedMetaData; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTPort; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimeFactory; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.impl.UMLRealTimeFactoryImpl; + +/** + * @author damus + * + */ +public class UMLRTUMLRealTimeFactoryImpl extends UMLRealTimeFactoryImpl { + + public static final UMLRealTimeFactory eINSTANCE = new UMLRTUMLRealTimeFactoryImpl(); + + private final UMLRealTimePackage umlRealTimePackage; + + /** + * Initializes me. + */ + public UMLRTUMLRealTimeFactoryImpl() { + super(); + + // A shim for the UMLRealTimePackage that provides me as its factory + this.umlRealTimePackage = (UMLRealTimePackage) Proxy.newProxyInstance(getClass().getClassLoader(), + new java.lang.Class[] { + UMLRealTimePackage.class, + BasicExtendedMetaData.EPackageExtendedMetaData.Holder.class, + }, + (proxy, method, args) -> { + switch (method.getName()) { + case "getEFactoryInstance": //$NON-NLS-1$ + case "getUMLRealTimeFactory": //$NON-NLS-1$ + return UMLRTUMLRealTimeFactoryImpl.eINSTANCE; + default: + return method.invoke(UMLRealTimePackage.eINSTANCE, args); + } + }); + } + + @Override + public EPackage getEPackage() { + return umlRealTimePackage; + } + + @Override + public RTPort createRTPort() { + return new RTPortRTImpl(); + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/ClassOperations.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/ClassOperations.java new file mode 100644 index 000000000..0fbc44dba --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/ClassOperations.java @@ -0,0 +1,68 @@ +/***************************************************************************** + * Copyright (c) 2016, 2017 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.operations; + +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.CapsulePart; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTConnector; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTPort; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.ClassRTImpl; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTClassifier; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Connector; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.util.UMLUtil; + +/** + * Externalized operations for {@link Class}es + */ +public class ClassOperations extends UMLUtil { + + // Not meant to be instantiable by clients + protected ClassOperations() { + super(); + } + + public static <T extends InternalUMLRTClassifier & Class> void rtInherit(ClassRTImpl class_, T superclass) { + class_.rtInherit(superclass, UMLPackage.Literals.ENCAPSULATED_CLASSIFIER__OWNED_PORT, + ExtUMLExtPackage.Literals.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT, + Port.class, RTPort.class); + class_.rtInherit(superclass, UMLPackage.Literals.STRUCTURED_CLASSIFIER__OWNED_ATTRIBUTE, + ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE, + Property.class, CapsulePart.class); + class_.rtInherit(superclass, UMLPackage.Literals.STRUCTURED_CLASSIFIER__OWNED_CONNECTOR, + ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR, + Connector.class, RTConnector.class); + + // TODO: anything else to inherit? + } + + public static <T extends InternalUMLRTClassifier & Class> void rtDisinherit(ClassRTImpl class_, T superclass) { + class_.rtDisinherit(superclass, UMLPackage.Literals.ENCAPSULATED_CLASSIFIER__OWNED_PORT, + ExtUMLExtPackage.Literals.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT); + class_.rtDisinherit(superclass, UMLPackage.Literals.STRUCTURED_CLASSIFIER__OWNED_ATTRIBUTE, + ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE); + class_.rtDisinherit(superclass, UMLPackage.Literals.STRUCTURED_CLASSIFIER__OWNED_CONNECTOR, + ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR); + + // TODO: anything else to disinherit? + + // Don't need the extension for anything, now + class_.rtDestroyExtension(); + } + + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/CollaborationOperations.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/CollaborationOperations.java new file mode 100644 index 000000000..05e401a00 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/CollaborationOperations.java @@ -0,0 +1,77 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.operations; + +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTMessageKind; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTMessageSet; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTClassifier; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTCollaboration; +import org.eclipse.uml2.uml.Collaboration; +import org.eclipse.uml2.uml.Interface; +import org.eclipse.uml2.uml.util.UMLUtil; + +/** + * Externalized operations for {@link Collaboration}s + */ +public class CollaborationOperations extends UMLUtil { + + // Not meant to be instantiable by clients + protected CollaborationOperations() { + super(); + } + + public static void rtInherit(InternalUMLRTCollaboration collaboration, InternalUMLRTCollaboration supercollab) { + // Ensure that the message-sets likewise inherit + collaboration.rtMessageSets() + .filter(InternalUMLRTClassifier.class::isInstance) + .forEach(set -> { + RTMessageKind kind = getKind(set); + if (kind != null) { + Interface super_ = getMessageSet(supercollab, kind); + if (super_ instanceof InternalUMLRTClassifier) { + ((InternalUMLRTClassifier) set).rtSetSupertype((InternalUMLRTClassifier) super_); + } + } + }); + } + + public static void rtDisinherit(InternalUMLRTCollaboration collaboration, InternalUMLRTCollaboration supercollab) { + // Ensure that the message-sets likewise disinherit + collaboration.rtMessageSets() + .filter(InternalUMLRTClassifier.class::isInstance) + .forEach(set -> { + RTMessageSet stereo = getStereotypeApplication(set, RTMessageSet.class); + if (stereo != null) { + Interface super_ = getMessageSet(supercollab, stereo.getRtMsgKind()); + if (super_ instanceof InternalUMLRTClassifier) { + InternalUMLRTClassifier specific = (InternalUMLRTClassifier) set; + if (specific.rtGetSupertype() == super_) { + specific.rtSetSupertype(null); + } + } + } + }); + } + + protected static Interface getMessageSet(InternalUMLRTCollaboration collaboration, RTMessageKind kind) { + return collaboration.rtMessageSets() + .filter(set -> getKind(set) == kind) + .findFirst().orElse(null); + } + + protected static RTMessageKind getKind(Interface messageSet) { + RTMessageSet stereo = getStereotypeApplication(messageSet, RTMessageSet.class); + return (stereo == null) ? null : stereo.getRtMsgKind(); + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/ElementOperations.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/ElementOperations.java new file mode 100644 index 000000000..cbdc55261 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/ElementOperations.java @@ -0,0 +1,52 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.operations; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.util.UMLUtil; + +/** + * Externalized operations for {@link Element}s + */ +public class ElementOperations extends UMLUtil { + + // Not meant to be instantiable by clients + protected ElementOperations() { + super(); + } + + public static <T extends InternalUMLRTElement & Element> boolean rtApplyStereotype(T element, T prototype) { + boolean result = false; + + for (EObject next : prototype.getStereotypeApplications()) { + EClass stereotype = next.eClass(); + + // The RTRedefinedElement is not a canonical stereotype and is + // handled independently for every element + if ((stereotype != UMLRealTimePackage.Literals.RT_REDEFINED_ELEMENT) + && (stereotype.getEPackage() == UMLRealTimePackage.eINSTANCE)) { + + applyStereotype(element, stereotype); + result = true; + } + } + + return result; + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/InterfaceOperations.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/InterfaceOperations.java new file mode 100644 index 000000000..e53745371 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/InterfaceOperations.java @@ -0,0 +1,53 @@ +/***************************************************************************** + * Copyright (c) 2016, 2017 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.operations; + +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InterfaceRTImpl; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTClassifier; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.uml2.uml.Interface; +import org.eclipse.uml2.uml.Operation; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.util.UMLUtil; + +/** + * Externalized operations for {@link Interface}s + */ +public class InterfaceOperations extends UMLUtil { + + // Not meant to be instantiable by clients + protected InterfaceOperations() { + super(); + } + + public static <T extends InternalUMLRTClassifier & Interface> void rtInherit(InterfaceRTImpl interface_, T superinterface) { + interface_.rtInherit(superinterface, UMLPackage.Literals.INTERFACE__OWNED_OPERATION, + ExtUMLExtPackage.Literals.INTERFACE__IMPLICIT_OPERATION, + Operation.class, null); + + // TODO: anything else to inherit? + } + + public static <T extends InternalUMLRTClassifier & Interface> void rtDisinherit(InterfaceRTImpl interface_, T superinterface) { + interface_.rtDisinherit(superinterface, UMLPackage.Literals.INTERFACE__OWNED_OPERATION, + ExtUMLExtPackage.Literals.INTERFACE__IMPLICIT_OPERATION); + + // TODO: anything else to disinherit? + + // Don't need the extension for anything, now + interface_.rtDestroyExtension(); + } + + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/MultiplicityElementOperations.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/MultiplicityElementOperations.java new file mode 100644 index 000000000..c80bce780 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/MultiplicityElementOperations.java @@ -0,0 +1,158 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.operations; + +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTMultiplicityElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTValueSpecification; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.InheritableSingleContainment; +import org.eclipse.uml2.uml.MultiplicityElement; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.ValueSpecification; +import org.eclipse.uml2.uml.util.UMLUtil; + +/** + * Externalized operations for {@link MultiplicityElement}s + */ +public class MultiplicityElementOperations extends UMLUtil { + + // Not meant to be instantiable by clients + protected MultiplicityElementOperations() { + super(); + } + + static LowerValue getInheritableLowerValue(InternalUMLRTMultiplicityElement owner) { + return (LowerValue) EcoreUtil.getExistingAdapter(owner, LowerValue.class); + } + + static LowerValue demandInheritableLowerValue(InternalUMLRTMultiplicityElement owner) { + LowerValue result = getInheritableLowerValue(owner); + + if (result == null) { + result = new LowerValue(owner); + owner.eAdapters().add(0, result); + } + + return result; + } + + public static ValueSpecification getLowerValue(InternalUMLRTMultiplicityElement owner) { + return demandInheritableLowerValue(owner).getInheritable(); + } + + public static void setLowerValue(InternalUMLRTMultiplicityElement owner, ValueSpecification newLowerValue) { + demandInheritableLowerValue(owner).set(newLowerValue); + } + + public static boolean isSetLowerValue(InternalUMLRTMultiplicityElement owner) { + LowerValue lowerValue = getInheritableLowerValue(owner); + return (lowerValue != null) && lowerValue.isSet(); + } + + public static void unsetLowerValue(InternalUMLRTMultiplicityElement owner) { + LowerValue lowerValue = getInheritableLowerValue(owner); + if (lowerValue != null) { + lowerValue.unset(); + } + } + + static UpperValue getInheritableUpperValue(InternalUMLRTMultiplicityElement owner) { + return (UpperValue) EcoreUtil.getExistingAdapter(owner, UpperValue.class); + } + + static UpperValue demandInheritableUpperValue(InternalUMLRTMultiplicityElement owner) { + UpperValue result = getInheritableUpperValue(owner); + + if (result == null) { + result = new UpperValue(owner); + owner.eAdapters().add(0, result); + } + + return result; + } + + public static ValueSpecification getUpperValue(InternalUMLRTMultiplicityElement owner) { + return demandInheritableUpperValue(owner).getInheritable(); + } + + public static void setUpperValue(InternalUMLRTMultiplicityElement owner, ValueSpecification newUpperValue) { + demandInheritableUpperValue(owner).set(newUpperValue); + } + + public static boolean isSetUpperValue(InternalUMLRTMultiplicityElement owner) { + UpperValue upperValue = getInheritableUpperValue(owner); + return (upperValue != null) && upperValue.isSet(); + } + + public static void unsetUpperValue(InternalUMLRTMultiplicityElement owner) { + UpperValue upperValue = getInheritableUpperValue(owner); + if (upperValue != null) { + upperValue.unset(); + } + } + + // + // Nested types + // + + private static final class LowerValue extends InheritableSingleContainment<ValueSpecification> { + LowerValue(InternalUMLRTMultiplicityElement owner) { + super(owner.eDerivedStructuralFeatureID(UMLPackage.MULTIPLICITY_ELEMENT__LOWER_VALUE, MultiplicityElement.class)); + } + + @Override + public Object get(boolean resolve) { + return ((InternalUMLRTMultiplicityElement) getTarget()).umlGetLowerValue(resolve); + } + + @Override + protected NotificationChain basicSet(ValueSpecification newValue, NotificationChain msgs) { + return ((InternalUMLRTMultiplicityElement) getTarget()).umlBasicSetLowerValue(newValue, msgs); + } + + @Override + protected ValueSpecification createRedefinition(ValueSpecification inherited) { + InternalUMLRTValueSpecification result = (InternalUMLRTValueSpecification) super.createRedefinition(inherited); + result.handleRedefinedMultiplicityElement( + ((InternalUMLRTMultiplicityElement) getTarget()).rtGetRedefinedElement()); + return result; + } + } + + private static final class UpperValue extends InheritableSingleContainment<ValueSpecification> { + UpperValue(InternalUMLRTMultiplicityElement owner) { + super(owner.eDerivedStructuralFeatureID(UMLPackage.MULTIPLICITY_ELEMENT__UPPER_VALUE, MultiplicityElement.class)); + } + + @Override + public Object get(boolean resolve) { + return ((InternalUMLRTMultiplicityElement) getTarget()).umlGetUpperValue(resolve); + } + + @Override + protected NotificationChain basicSet(ValueSpecification newValue, NotificationChain msgs) { + return ((InternalUMLRTMultiplicityElement) getTarget()).umlBasicSetUpperValue(newValue, msgs); + } + + @Override + protected ValueSpecification createRedefinition(ValueSpecification inherited) { + InternalUMLRTValueSpecification result = (InternalUMLRTValueSpecification) super.createRedefinition(inherited); + result.handleRedefinedMultiplicityElement( + ((InternalUMLRTMultiplicityElement) getTarget()).rtGetRedefinedElement()); + return result; + } + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/RedefinableElementOperations.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/RedefinableElementOperations.java new file mode 100644 index 000000000..258c8bee1 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/RedefinableElementOperations.java @@ -0,0 +1,241 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.operations; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTRedefinedElement; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement; +import org.eclipse.papyrusrt.umlrt.uml.util.UMLRTExtensionUtil; +import org.eclipse.uml2.common.util.CacheAdapter; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.RedefinableElement; +import org.eclipse.uml2.uml.util.UMLUtil; + +/** + * Externalized operations for {@link RedefinableElement}s + */ +public class RedefinableElementOperations extends UMLUtil { + + protected RedefinableElementOperations() { + super(); + } + + @SuppressWarnings("unchecked") + public static <R extends InternalUMLRTElement> R getRedefinedElement(R element) { + R result = null; + + if (element instanceof RedefinableElement) { + result = null; + List<RedefinableElement> redefined = ((RedefinableElement) element).getRedefinedElements(); + + // UML-RT recognizes only single redefinition, but being more general + // here is practical + EClass metaclass = element.eClass(); + for (RedefinableElement next : redefined) { + if (next.eClass() == metaclass) { + result = (R) next; + break; + } + } + } + + return result; + } + + @SuppressWarnings("unchecked") + public static <R extends InternalUMLRTElement, T> T inheritFeature(R element, EStructuralFeature feature) { + T result = null; + + if (element != null) { + if (element.rtIsSet(feature)) { + result = (T) element.umlGet(feature); + } else { + R redefined = element.rtGetRedefinedElement(); + if (redefined != null) { + // Inherit this, whatever it is + result = (T) redefined.eGet(feature); + } + } + } + + if (result == null) { + result = (T) feature.getDefaultValue(); + } + + return result; + } + + public static <R extends InternalUMLRTElement, T> T inheritFeature(R element, EStructuralFeature feature, CacheAdapter cache) { + T result; + + if (cache == null) { + result = inheritFeature(element, feature); + } else { + @SuppressWarnings("unchecked") + T cached = (T) cache.get(element, feature); + if (cached == null) { + cached = inheritFeature(element, feature); + cache.put(element, feature, cached); + } + result = cached; + } + + return result; + } + + public static boolean isRedefinition(InternalUMLRTElement element) { + boolean result = element.rtIsVirtual(); + + // Virtual elements are, by definition, redefinitions (that's why they exist) + if (!result) { + // UML-RT recognizes only single redefinition + result = element.rtGetRedefinedElement() != null; + } + + return result; + } + + public static boolean isExcluded(InternalUMLRTElement element) { + boolean result = false; + + Element uml = (element instanceof Element) + ? (Element) element + : UMLUtil.getBaseElement(element); + + if (uml instanceof RedefinableElement) { + // RedefinableElement case (others use the false constraint convention) + RTRedefinedElement rtRedef = UMLUtil.getStereotypeApplication(uml, RTRedefinedElement.class); + result = (rtRedef != null) && (rtRedef.getRootFragment() == null); + } + + return result; + } + + public static boolean exclude(InternalUMLRTElement element) { + boolean result = false; + + if (!element.rtIsExcluded()) { + Element uml = element.rtGetElement(); + if (uml instanceof RedefinableElement) { + // RedefinableElement case (others use the false constraint convention) + RTRedefinedElement rtRedef = UMLUtil.getStereotypeApplication(uml, RTRedefinedElement.class); + if (rtRedef == null) { + rtRedef = (RTRedefinedElement) StereotypeApplicationHelper.getInstance(uml).applyStereotype( + uml, UMLRealTimePackage.Literals.RT_REDEFINED_ELEMENT); + } + if (rtRedef != null) { + if (rtRedef.getRootFragment() != null) { + rtRedef.setRootFragment(null); + } + + result = true; + + // In case it wasn't already or indirectly by the above + element.rtReify(); + } + } + } + + return result; + } + + public static boolean reinherit(InternalUMLRTElement element) { + boolean result = false; + + if (element.rtIsRedefinition() && !element.rtIsVirtual()) { + Element uml = element.rtGetElement(); + if (uml instanceof RedefinableElement) { + // RedefinableElement case (others use the false constraint convention) + InternalUMLRTElement umlRedef = ((InternalUMLRTElement) uml).rtGetRedefinedElement(); + InternalUMLRTElement root = umlRedef; + while (root.rtGetRedefinedElement() != null) { + root = root.rtGetRedefinedElement(); + } + RTRedefinedElement rtRedef = UMLUtil.getStereotypeApplication(uml, RTRedefinedElement.class); + if (rtRedef != null) { + // First ensure notification of the re-inherit + rtRedef.setRootFragment((RedefinableElement) root); + + // But don't actually need the stereotype on a virtual redefinition + destroy(rtRedef); + + result = true; + } + + // Make it purely inherited, again + element.rtVirtualize(); + } + } + + return result; + + } + + public static <R extends RedefinableElement & InternalUMLRTElement> void redefine(R element, R redefined) { + UMLRTExtensionUtil.run(element, () -> { + // First, set the UML semantics of redefinition + element.umlSetRedefinedElement(redefined); + + // Only apply this stereotype if the redefined element has it + RTRedefinedElement inherited = UMLUtil.getStereotypeApplication(redefined, RTRedefinedElement.class); + if (inherited != null) { + RTRedefinedElement stereo = UMLUtil.getStereotypeApplication(element, RTRedefinedElement.class); + if (stereo == null) { + stereo = (RTRedefinedElement) StereotypeApplicationHelper.getInstance(element).applyStereotype( + element, UMLRealTimePackage.Literals.RT_REDEFINED_ELEMENT); + } + + // This is the redefinition root + stereo.setRootFragment(inherited.getRootFragment()); + } + + // Make sure that the stereotypes end up in the right place + element.rtAdjustStereotypes(); + }); + } + + public static <R extends RedefinableElement & InternalUMLRTElement> void ensureStereotype(R element) { + UMLRTExtensionUtil.run(element, () -> { + RTRedefinedElement stereo = UMLUtil.getStereotypeApplication(element, RTRedefinedElement.class); + if (stereo == null) { + stereo = (RTRedefinedElement) StereotypeApplicationHelper.getInstance(element).applyStereotype( + element, UMLRealTimePackage.Literals.RT_REDEFINED_ELEMENT); + + // If the stereotype wasn't applied, then the element wasn't + // excluded, so we have to set the root fragment + R root = element.rtGetRedefinedElement(); + for (R redefined = root.rtGetRedefinedElement(); redefined != null; redefined = root.rtGetRedefinedElement()) { + root = redefined; + } + stereo.setRootFragment(root); + } + }); + } + + public static Element getOwner(InternalEObject element) { + EObject result = element.eInternalContainer(); + if (result instanceof ExtElement) { + result = ((ExtElement) result).getExtendedElement(); + } + return (result instanceof Element) ? (Element) result : null; + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/ValueSpecificationOperations.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/ValueSpecificationOperations.java new file mode 100644 index 000000000..1c4ae8c0a --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/operations/ValueSpecificationOperations.java @@ -0,0 +1,93 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.operations; + +import org.eclipse.emf.ecore.EReference; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTMultiplicityElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTValueSpecification; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.MultiplicityElement; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.ValueSpecification; +import org.eclipse.uml2.uml.util.UMLUtil; + +/** + * Externalized operations for {@link ValueSpecification}s + */ +public class ValueSpecificationOperations extends UMLUtil { + + // Not meant to be instantiable by clients + protected ValueSpecificationOperations() { + super(); + } + + public static void rtReify(InternalUMLRTValueSpecification valueSpecification) { + Element owner = valueSpecification.getOwner(); + if (owner instanceof MultiplicityElement) { + EReference containment = valueSpecification.eContainmentFeature(); + // This will implicitly reify the owner, too, which is good + owner.eSet(containment, valueSpecification); + valueSpecification.rtAdjustStereotypes(); + } + } + + public static void rtVirtualize(InternalUMLRTValueSpecification valueSpecification) { + Element owner = valueSpecification.getOwner(); + if (owner instanceof InternalUMLRTMultiplicityElement) { + EReference containment = valueSpecification.eContainmentFeature(); + owner.eUnset(containment); + valueSpecification.rtAdjustStereotypes(); + } + } + + @SuppressWarnings("unchecked") + public static <R extends InternalUMLRTElement> R rtGetRedefinedElement(InternalUMLRTValueSpecification valueSpecification) { + R result = null; + + Element owner = valueSpecification.getOwner(); + if ((owner instanceof MultiplicityElement) && (owner instanceof InternalUMLRTElement)) { + MultiplicityElement mult = (MultiplicityElement) valueSpecification.getOwner(); + MultiplicityElement redefined = ((InternalUMLRTElement) mult).rtGetRedefinedElement(); + if (redefined != null) { + EReference containment = valueSpecification.eContainmentFeature(); + if (containment == UMLPackage.Literals.MULTIPLICITY_ELEMENT__LOWER_VALUE) { + result = (R) redefined.getLowerValue(); + } else if (containment == UMLPackage.Literals.MULTIPLICITY_ELEMENT__UPPER_VALUE) { + result = (R) redefined.getUpperValue(); + } + } + } + + return result; + } + + public static void umlSetRedefinedElement(InternalUMLRTValueSpecification valueSpecification, InternalUMLRTElement redefined) { + if (!(redefined instanceof ValueSpecification)) { + throw new IllegalArgumentException("not a value specification: " + redefined); //$NON-NLS-1$ + } + + // Redefinition is via the containing multiplicity element + Element owner = valueSpecification.getOwner(); + if ((owner instanceof MultiplicityElement) && (owner instanceof InternalUMLRTElement)) { + MultiplicityElement mult = (MultiplicityElement) valueSpecification.getOwner(); + MultiplicityElement redefinedMult = (MultiplicityElement) redefined.rtOwner(); + + if (redefinedMult != null) { + ((InternalUMLRTElement) mult).umlSetRedefinedElement((InternalUMLRTElement) redefinedMult); + } + } + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/CachedReference.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/CachedReference.java new file mode 100644 index 000000000..1882a76e6 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/CachedReference.java @@ -0,0 +1,57 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.util; + +import java.lang.ref.SoftReference; +import java.util.function.Supplier; + +/** + * A lazily-computed wrapper for a {@link SoftReference} cache that refreshes + * the reference whenever it is discovered to have been cleared. + */ +public final class CachedReference<T> implements Supplier<T> { + + private final Supplier<T> supplier; + private Supplier<T> reference; + + /** + * Initializes me with my lazy computation. Obviously, this entire + * caching mechanism will not be useful if the {@code supplier}, itself, + * retains the reference value. + * + * @param supplier + * the lazy computation that generates the cached reference + */ + public CachedReference(Supplier<T> supplier) { + super(); + + this.supplier = supplier; + this.reference = this::compute; + } + + private T compute() { + T result = supplier.get(); + reference = new SoftReference<>(result)::get; + return result; + } + + @Override + public T get() { + T result = reference.get(); + if (result == null) { + result = compute(); + } + return result; + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/DerivedUnionEObjectEListExt.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/DerivedUnionEObjectEListExt.java new file mode 100644 index 000000000..f6027fa61 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/DerivedUnionEObjectEListExt.java @@ -0,0 +1,52 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.util; + +import static org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionHolder.UML_EXTENSION_FEATURE_BASE; + +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionHolder; +import org.eclipse.uml2.common.util.DerivedUnionEObjectEList; + +/** + * Implementation of a derived union that includes extension features. + */ +public class DerivedUnionEObjectEListExt<E> extends DerivedUnionEObjectEList<E> { + + public DerivedUnionEObjectEListExt(Class<?> dataClass, InternalEObject owner, int featureID, int[] sourceFeatureIDs) { + super(dataClass, owner, featureID, sourceFeatureIDs); + } + + public static int[] extendSubsets(int[] baseSubsets, int... extendedSubset) { + int base = baseSubsets.length; + int ext = extendedSubset.length; + + int[] result = new int[base + ext]; + System.arraycopy(baseSubsets, 0, result, 0, base); + + for (int i = 0; i < ext; i++) { + result[base + i] = UML_EXTENSION_FEATURE_BASE - extendedSubset[i]; + } + + return result; + } + + @Override + public EStructuralFeature getEStructuralFeature(int featureID) { + return (featureID <= UML_EXTENSION_FEATURE_BASE) + ? ExtensionHolder.getExtensionFeature(owner.eClass(), featureID) + : super.getEStructuralFeature(featureID); + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritableEList.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritableEList.java new file mode 100644 index 000000000..d32c55a32 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritableEList.java @@ -0,0 +1,63 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.util; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.util.InternalEList; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; + +/** + * A specialized EMF list that supports inheritance from + * a list-valued feature in a redefined element. It maintains + * corresponding redefinitions of the elements in the inherited + * list. An inheritable list does not have to inherit anything, + * in which case it behaves as a normal EMF list storing the + * mutable values of a multi-valued feature. + */ +public interface InheritableEList<E> extends InternalEList.Unsettable<E> { + /** + * Queries whether I am set, in which case I override + * any potentially {@linkplain #inherit(EList) inherited} + * values. + * + * @return whether I am explicitly set + */ + @Override + boolean isSet(); + + /** + * Unsets me, in which case I revert to + * {@linkplain #inherit(EList) inheriting} the values + * of my owner's redefined element, or else am just + * cleared out as with any normal EMF list. + */ + @Override + void unset(); + + /** + * Sets the list from which I inherit values. + * + * @param inherited + * the list from which I inherit, or {@code null} + * if I am the value of a feature of a root definition + * (there is nothing from which to inherit) + */ + void inherit(EList<E> inherited); + + /** + * If I am {@link #isSet() unset}, makes me set and ensures + * that my owner is then {@link InternalUMLRTElement#rtReify() reified}. + */ + void touch(); +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritableEObjectEList.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritableEObjectEList.java new file mode 100644 index 000000000..87bc40dca --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritableEObjectEList.java @@ -0,0 +1,164 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.util; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.notify.impl.NotificationImpl; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.util.EcoreEList; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; + +/** + * Partial implementation of an inheritable {@link EcoreEList} for the implementation + * of inheritable multi-valued reference features. It is required of subclasses to + * implement only the {@link #createRedefinition(EObject)} method to create a redefinition + * of an inherited element in the list. + * + * @see #createRedefinition(EObject) + */ +public abstract class InheritableEObjectEList<E extends EObject> extends InheritableEcoreEList<E> implements InheritableEList<E>, Adapter { + + private static final long serialVersionUID = 1L; + + public InheritableEObjectEList(InternalEObject owner, int featureID) { + super(owner, featureID); + } + + /** + * Implemented by subclasses to create a redefinition of an + * {@code inherited} element and set it as redefining that + * inherited element, as appropriate to its kind. + * + * @param inherited + * an inherited element + * @return a new element redefining it to be stored in this list + */ + protected abstract E createRedefinition(E inherited); + + @Override + protected NotificationChain setInherited(List<E> elements, NotificationChain msgs) { + if (!isEmpty()) { + clear(); + } + doAddAllUnique(elements); + + for (E next : elements) { + msgs = ((InternalEObject) next).eInverseAdd(owner, + InternalEObject.EOPPOSITE_FEATURE_BASE - getFeatureID(), + null, msgs); + } + + if (isNotificationRequired()) { + // This is like resolving a bunch of proxies, so let content adapters + // etc. discover them + for (int i = 0; i < elements.size(); i++) { + E next = elements.get(i); + NotificationImpl notif = new ENotificationImpl(owner, + Notification.RESOLVE, + getEStructuralFeature(), + next, next, i); + if (msgs == null) { + msgs = notif; + } else { + msgs.add(notif); + } + } + } + + return msgs; + } + + @Override + protected E redefineSingle(E inherited) { + return createRedefinition(inherited); + } + + @Override + protected List<E> redefineMany(List<E> inherited) { + int count = inherited.size(); + List<E> result = new ArrayList<>(count); + List<E> existing = delegateList(); + + int i; + for (i = 0; i < count; i++) { + if (i >= existing.size()) { + break; + } else { + // Reuse this one + E next = existing.get(i); + result.add(next); + + if (next instanceof InternalUMLRTElement) { + // Make it fresh + ((InternalUMLRTElement) next).rtUnsetAll(); + } + } + } + + // Fill out the rest with new elements + for (; i < count; i++) { + result.add(createRedefinition(inherited.get(i))); + } + + return result; + } + + @Override + protected void redefined(E element) { + NotificationForwarder.initialize(element); + } + + @Override + protected void unredefined(E element) { + NotificationForwarder.initialize(element); + } + + // + // Nested types + // + + /** + * A further specialization of the inheritable {@link EcoreEList} that implements + * containment references. + */ + public static abstract class Containment<E extends EObject> extends InheritableEObjectEList<E> { + private static final long serialVersionUID = 1L; + + public Containment(InternalEObject owner, int featureID) { + super(owner, featureID); + } + + @Override + protected boolean hasInverse() { + return true; + } + + @Override + protected boolean hasNavigableInverse() { + return false; + } + + @Override + protected boolean isContainment() { + return true; + } + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritableEcoreEList.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritableEcoreEList.java new file mode 100644 index 000000000..dd62bf3c0 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritableEcoreEList.java @@ -0,0 +1,367 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.util.DelegatingEcoreEList; +import org.eclipse.emf.ecore.util.EcoreEList; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.operations.RedefinableElementOperations; + +/** + * Implementation of an inheritable {@link EcoreEList} for the implementation + * of inheritable multi-valued attributes. + */ +public class InheritableEcoreEList<E> extends DelegatingEcoreEList<E> implements InheritableEList<E>, Adapter { + + private static final long serialVersionUID = 1L; + + private static final int SET_EFLAG = 0x1 << 0; + private static final int HANDLING_INHERITANCE_EFLAG = 0x1 << 1; + private static final int FEATURE_EOFFSET = 2; + + private final EList<E> content = new BasicEList<>(); + + private EList<E> inherited; + private int eFlags; + + public InheritableEcoreEList(InternalEObject owner, int featureID) { + super(owner); + + eFlags = featureID << FEATURE_EOFFSET; + } + + @Override + public int getFeatureID() { + return eFlags >> FEATURE_EOFFSET; + } + + @Override + public boolean isSet() { + return (eFlags & SET_EFLAG) != 0; + } + + @Override + public void unset() { + // Make sure that we appear to be unset before computing inherited value + eFlags = eFlags & ~SET_EFLAG; + + List<E> oldElements = new ArrayList<>(delegateList()); + + EList<E> result = RedefinableElementOperations.inheritFeature( + (InternalUMLRTElement) getEObject(), + (EStructuralFeature) getFeature()); + + if (result != this) { + // Inherit this. If it's null, that means we are the root definition + inherit(result); + } + + // inherit(...) may remove elements or clear, which makes us appear set + eFlags = eFlags & ~SET_EFLAG; + + // Adjust stereotypes of the old elements in case they need to switch resources + oldElements.stream() + .filter(InternalUMLRTElement.class::isInstance) + .map(InternalUMLRTElement.class::cast) + .forEach(InternalUMLRTElement::rtAdjustStereotypes); + } + + @Override + public void touch() { + eFlags = eFlags | SET_EFLAG; + + // Instantly disinherit + if (inherited != null) { + unadapt(inherited); + inherited = null; + } + + if (owner instanceof InternalUMLRTElement) { + InternalUMLRTElement rtOwner = (InternalUMLRTElement) owner; + if (rtOwner.rtIsVirtual()) { + rtOwner.rtReify(); + } + } + + stream() + .filter(InternalUMLRTElement.class::isInstance) + .map(InternalUMLRTElement.class::cast) + .forEach(InternalUMLRTElement::rtAdjustStereotypes); + } + + @Override + protected List<E> delegateList() { + return content; + } + + protected final void handlingInheritance(Runnable action) { + final int restore = eFlags | ~HANDLING_INHERITANCE_EFLAG; + eFlags = eFlags | HANDLING_INHERITANCE_EFLAG; + try { + if (getNotifier() instanceof InternalUMLRTElement) { + // Whatever we do here should not reify our owner + ((InternalUMLRTElement) getNotifier()).run(action); + } else { + // Just run it + action.run(); + } + } finally { + eFlags = eFlags & restore; + } + } + + @Override + public void inherit(EList<E> newInherited) { + if (!isHandlingInheritance()) { + NotificationChain msgs = basicInherit(newInherited, null); + + if ((msgs != null) && owner.eNotificationRequired()) { + msgs.dispatch(); + } + } + } + + protected NotificationChain basicInherit(EList<E> newInherited, NotificationChain msgs) { + NotificationChain[] result = { msgs }; + + if (inherited != newInherited) { + handlingInheritance(() -> { + // Stop listening to the old inherited list + if (inherited != null) { + unadapt(inherited); + } + + // Assign and listen to the new inherited list + inherited = newInherited; + if (inherited != null) { + adapt(inherited); + } + + // Create our new contents from the inherited list + if ((inherited == null) || inherited.isEmpty()) { + if (!isEmpty()) { + clear(); + } + } else { + List<E> redefinitions = redefineMany(inherited); + result[0] = setInherited(redefinitions, result[0]); + redefinitions.forEach(this::redefined); + } + }); + } + + return result[0]; + } + + protected NotificationChain setInherited(List<E> elements, NotificationChain msgs) { + // For multi-valued attributes, it is as though the value was always + // there but never previously read, so don't notify + if (!isEmpty()) { + doClear(); + } + doAddAllUnique(elements); + return msgs; + } + + final boolean isHandlingInheritance() { + return (eFlags & (SET_EFLAG | HANDLING_INHERITANCE_EFLAG)) != 0; + } + + protected void disinherit() { + if (!isHandlingInheritance()) { + // not set and not handling inheritance + NotificationChain msgs = basicInherit(null, null); + + touch(); + + if ((msgs != null) && owner.eNotificationRequired()) { + msgs.dispatch(); + } + } + } + + protected E redefineSingle(E inherited) { + return inherited; + } + + protected List<E> redefineMany(List<E> inherited) { + return inherited; + } + + protected void redefined(E element) { + // Pass + } + + protected void unredefined(E element) { + // Pass + } + + // + // Auto-disinheriting API + // + + @Override + protected E delegateSet(int index, E object) { + disinherit(); + return super.delegateSet(index, object); + } + + @Override + protected void delegateAdd(E object) { + disinherit(); + super.delegateAdd(object); + } + + @Override + protected void delegateAdd(int index, E object) { + disinherit(); + super.delegateAdd(index, object); + } + + @Override + protected E delegateRemove(int index) { + disinherit(); + return super.delegateRemove(index); + } + + @Override + protected void delegateClear() { + disinherit(); + super.delegateClear(); + } + + @Override + protected E delegateMove(int targetIndex, int sourceIndex) { + disinherit(); + return super.delegateMove(targetIndex, sourceIndex); + } + + // + // Inheritance adapter API + // + + static EObject getOwner(EList<?> list) { + return (list instanceof EStructuralFeature.Setting) + ? ((EStructuralFeature.Setting) list).getEObject() + : null; + } + + private void adapt(EList<?> inherited) { + EObject owner = getOwner(inherited); + if ((owner != null) && !owner.eAdapters().contains(this)) { + owner.eAdapters().add(this); + } + } + + private void unadapt(EList<?> inherited) { + EObject owner = getOwner(inherited); + if (owner != null) { + owner.eAdapters().remove(this); + } + } + + @Override + public void notifyChanged(Notification notification) { + if (notification.isTouch() || (notification.getFeature() != getFeature())) { + return; + } + + handlingInheritance(() -> { + switch (notification.getEventType()) { + case Notification.ADD: { + int position = notification.getPosition(); + // Create the redefinition of the added element + @SuppressWarnings("unchecked") + E added = (E) notification.getNewValue(); + E redefinition = redefineSingle(added); + add(position, redefinition); + redefined(redefinition); + break; + } + case Notification.REMOVE: { + int position = notification.getPosition(); + E redefinition = remove(position); + unredefined(redefinition); + break; + } + case Notification.ADD_MANY: { + int position = notification.getPosition(); + // Create the redefinitions of the added elements + @SuppressWarnings("unchecked") + List<E> added = (List<E>) notification.getNewValue(); + List<E> redefinitions = redefineMany(added); + addAll(position, redefinitions); + redefinitions.forEach(this::redefined); + break; + } + case Notification.REMOVE_MANY: { + if (notification.getPosition() == Notification.NO_INDEX) { + // It was a clear() + clear(); + } else { + // It was a removeAll(...) or retainAll(...) + int[] positions = (int[]) notification.getNewValue(); + // get the redefinitions of the removed elements + List<E> redefinitions = IntStream.of(positions) + .mapToObj(this::get) + .collect(Collectors.toList()); + removeAll(redefinitions); + redefinitions.forEach(this::unredefined); + } + break; + } + case Notification.SET: { + int position = notification.getPosition(); + // Create the redefinition of the added element + @SuppressWarnings("unchecked") + E added = (E) notification.getNewValue(); + E newRedefinition = redefineSingle(added); + E oldRedefinition = set(position, newRedefinition); + unredefined(oldRedefinition); + redefined(newRedefinition); + break; + } + } + }); + } + + @Override + public Notifier getTarget() { + return getOwner(inherited); + } + + @Override + public void setTarget(Notifier newTarget) { + // Don't need to track the target (we have its EList) + } + + @Override + public boolean isAdapterForType(Object type) { + return type == this; + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritableSetting.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritableSetting.java new file mode 100644 index 000000000..2685e762e --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritableSetting.java @@ -0,0 +1,44 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.util; + +import org.eclipse.emf.ecore.EStructuralFeature; + +/** + * A specialization of the Ecore feature setting protocol for single-valued + * features that support inheritance. + */ +public interface InheritableSetting<E> extends EStructuralFeature.Setting { + /** + * Obtains the (possibly inherited) value of the feature. + * + * @return the feature value, if {@linkplain EStructuralFeature.Setting#isSet() set}, + * otherwise the inherited value + * + * @see EStructuralFeature.Setting#isSet() + */ + E getInheritable(); + + /** + * Inherits the given value. + * + * @param newInherited + * the inherited value, or {@code null} if my + * {@linkplain EStructuralFeature.Setting#getEObject() owner} is + * a root definition + * + * @see EStructuralFeature.Setting#getEObject() + */ + void inherit(E newInherited); +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritableSingleContainment.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritableSingleContainment.java new file mode 100644 index 000000000..af458da0f --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritableSingleContainment.java @@ -0,0 +1,330 @@ +/***************************************************************************** + * Copyright (c) 2016, 2017 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.util; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.common.notify.impl.AdapterImpl; +import org.eclipse.emf.common.notify.impl.NotificationImpl; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.operations.RedefinableElementOperations; + +/** + * Partial implementation of an inheritable slot for the implementation + * of inheritable single-valued reference features. + */ +public abstract class InheritableSingleContainment<E extends EObject> extends AdapterImpl implements InheritableSetting<E>, Adapter { + + private static final int SET_EFLAG = 0x1 << 0; + private static final int HANDLING_INHERITANCE_EFLAG = 0x1 << 1; + private static final int FEATURE_EOFFSET = 2; + + private E inherited; + private int eFlags; + + public InheritableSingleContainment(int featureID) { + super(); + + eFlags = featureID << FEATURE_EOFFSET; + } + + @Override + public InternalUMLRTElement getEObject() { + return (InternalUMLRTElement) getTarget(); + } + + public int getFeatureID() { + return eFlags >> FEATURE_EOFFSET; + } + + @Override + public EStructuralFeature getEStructuralFeature() { + return getEObject().eClass().getEAllStructuralFeatures().get(getFeatureID()); + } + + @Override + public E getInheritable() { + E result = get(); + E inheritedResult = getEObject().inheritFeature(getEStructuralFeature()); + + if (inheritedResult != result) { + // Inherit this into our slot. If it's null, that means we are the root definition + inherit(inheritedResult); + + result = get(); + } + + return result; + } + + protected E get() { + @SuppressWarnings("unchecked") + E result = (E) get(false); + + return result; + } + + @Override + public boolean isSet() { + return (eFlags & SET_EFLAG) != 0; + } + + @Override + public void unset() { + boolean wasSet = isSet(); + E oldValue = getInheritable(); + + InternalEObject owner = getEObject(); + + // Need to record unset state before trying to derive inherited value + eFlags = eFlags & ~SET_EFLAG; + + // And ignore any possible cached value + E result = RedefinableElementOperations.inheritFeature(getEObject(), + getEStructuralFeature()); + + if (result != inherited) { + // Inherit this. If it's null, that means we are the root definition + inherit(result); + } + + // And then unset the contained object + E newValue = get(); + if (newValue instanceof InternalUMLRTElement) { + ((InternalUMLRTElement) newValue).rtUnsetAll(); + } + + if (owner.eNotificationRequired()) { + owner.eNotify(new ENotificationImpl(owner, Notification.UNSET, + getEStructuralFeature(), oldValue, newValue, wasSet)); + } + } + + protected final void handlingInheritance(Runnable action) { + final int restore = eFlags | ~HANDLING_INHERITANCE_EFLAG; + eFlags = eFlags | HANDLING_INHERITANCE_EFLAG; + try { + EObject owner = getEObject(); + if (owner instanceof InternalUMLRTElement) { + // Whatever we do here should not reify our owner + ((InternalUMLRTElement) owner).run(action); + } else { + // Just run it + action.run(); + } + } finally { + eFlags = eFlags & restore; + } + } + + @Override + public void inherit(E newInherited) { + if (inherited != newInherited) { + handlingInheritance(() -> { + InternalUMLRTElement owner = getEObject(); + + // Stop listening to the old inherited element + if (inherited != null) { + unadapt(inherited); + } + + NotificationChain msgs = null; + + E oldValue = get(); + if (oldValue != null) { + NotificationForwarder.initialize(oldValue); + + InternalEObject internalValue = (InternalEObject) oldValue; + InternalEObject oldOwner = internalValue.eInternalContainer(); + int oldFeatureID = internalValue.eContainerFeatureID(); + + msgs = internalValue.eInverseRemove(oldOwner, oldFeatureID, null, msgs); + } + + // Assign and listen to the new inherited element + inherited = newInherited; + if (inherited == null) { + msgs = basicSet(null, msgs); + } else { + adapt(inherited); + + // Create our new element from the inherited element + E redefinition = createRedefinition(inherited); + + ((InternalEObject) redefinition).eInverseAdd(owner, + InternalEObject.EOPPOSITE_FEATURE_BASE - getFeatureID(), + null, null); + + // We will make our own notification + basicSet(redefinition, null); + + NotificationForwarder.initialize(redefinition); + + if (owner.eNotificationRequired()) { + NotificationImpl msg; + + if (oldValue == null) { + // This is like resolving a proxy, so let content adapters + // etc. discover it + msg = new ENotificationImpl(owner, + Notification.RESOLVE, + getEStructuralFeature(), + redefinition, redefinition); + } else { + // The inherited value was replaced by an edit + msg = new ENotificationImpl(owner, + Notification.SET, + getEStructuralFeature(), + oldValue, redefinition); + } + + if (msgs != null) { + msgs.add(msg); + } else { + msgs = msg; + } + } + + if (msgs != null) { + msgs.dispatch(); + } + } + }); + } + } + + @Override + public void set(Object newValue) { + InternalEObject owner = getEObject(); + + boolean wasSet = isSet(); + E oldValue = get(); + + NotificationChain msgs = null; + + disinherit(); + + if (oldValue != null) { + NotificationForwarder.initialize(oldValue); + msgs = ((InternalEObject) oldValue).eInverseRemove(owner, + InternalEObject.EOPPOSITE_FEATURE_BASE - getFeatureID(), + null, msgs); + } + if (newValue != null) { + msgs = ((InternalEObject) newValue).eInverseAdd(owner, + InternalEObject.EOPPOSITE_FEATURE_BASE - getFeatureID(), + null, msgs); + NotificationForwarder.initialize(newValue); + } + + @SuppressWarnings("unchecked") + E newValue_ = (E) newValue; + msgs = basicSet(newValue_, msgs); + + if (owner.eNotificationRequired()) { + NotificationImpl setMsg = new ENotificationImpl(owner, Notification.SET, + getEStructuralFeature(), oldValue, newValue, wasSet); + if (msgs == null) { + msgs = setMsg; + } else { + msgs.add(setMsg); + } + } + + if (msgs != null) { + msgs.dispatch(); + } + } + + protected abstract NotificationChain basicSet(E newValue, NotificationChain msgs); + + protected void disinherit() { + if ((eFlags & (SET_EFLAG | HANDLING_INHERITANCE_EFLAG)) == 0) { + // not set and not handling inheritance + inherit(null); + eFlags = eFlags | SET_EFLAG; + } + } + + /** + * Creates a redefinition of an {@code inherited} element. Clients may + * extend to set it as redefining that inherited element, as appropriate + * to its kind. + * + * @param inherited + * an inherited element + * @return a new element redefining it to be stored in this list + */ + @SuppressWarnings("unchecked") + protected E createRedefinition(E inherited) { + return (E) getEObject().create(inherited.eClass()); + } + + // + // Inheritance adapter API + // + + private void adapt(E inherited) { + EObject owner = inherited.eContainer(); + if ((owner != null) && !owner.eAdapters().contains(this)) { + owner.eAdapters().add(this); + } + } + + private void unadapt(E inherited) { + EObject owner = inherited.eContainer(); + if (owner != null) { + owner.eAdapters().remove(this); + } + } + + @Override + public void notifyChanged(Notification notification) { + if (notification.isTouch() + || (notification.getNotifier() == getTarget()) + || (notification.getFeature() != getEStructuralFeature())) { + return; + } + + switch (notification.getEventType()) { + case Notification.SET: + case Notification.UNSET: + // Create the redefinition of the new element + @SuppressWarnings("unchecked") + E added = (E) notification.getNewValue(); + inherit(added); + + break; + } + } + + @Override + public void setTarget(Notifier newTarget) { + // Only track the first object we're attached to + if ((getTarget() == null) || (newTarget == null)) { + super.setTarget(newTarget); + } + } + + @Override + public boolean isAdapterForType(Object type) { + return type == getClass(); + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritanceAdapter.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritanceAdapter.java new file mode 100644 index 000000000..6fe950e8a --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritanceAdapter.java @@ -0,0 +1,776 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.util; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Queue; +import java.util.Set; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.common.notify.impl.AdapterImpl; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.util.Switch; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.Capsule; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.CapsulePart; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.Protocol; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTConnector; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTMessageSet; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTPort; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTRedefinedElement; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.util.UMLRealTimeSwitch; +import org.eclipse.papyrusrt.umlrt.profile.statemachine.UMLRTStateMachines.UMLRTStateMachinesPackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTClassifier; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Classifier; +import org.eclipse.uml2.uml.Connector; +import org.eclipse.uml2.uml.Generalization; +import org.eclipse.uml2.uml.Interface; +import org.eclipse.uml2.uml.Namespace; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.RedefinableElement; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * Partial implementation of an adapter that maintains inherited features + * for an UML-RT classifier. + */ +public abstract class InheritanceAdapter extends AdapterImpl { + InheritanceAdapter() { + super(); + } + + public static InheritanceAdapter getInstance(Notifier notifier) { + InheritanceAdapter result = (InheritanceAdapter) EcoreUtil.getExistingAdapter( + notifier, InheritanceAdapter.class); + + if (result == null) { + if (notifier instanceof UMLRTUMLResourceImpl) { + // Resources should have these + result = new InheritanceAdapter.ForResource((Resource) notifier); + result.adapt(notifier); + } else if (notifier instanceof InternalUMLRTClassifier) { + // As should capsules, protocols, and message-sets + Resource resource = ((InternalUMLRTClassifier) notifier).eResource(); + if (resource != null) { + result = getInstance(resource); + } + if (result != null) { + result.getClassifierAdapter().adapt(notifier); + } + } + } + + return result; + } + + @Override + public boolean isAdapterForType(Object type) { + return type == InheritanceAdapter.class; + } + + public boolean adapt(Notifier notifier) { + boolean result = false; + EList<Adapter> adapters = notifier.eAdapters(); + + if (!adapters.contains(this)) { + result = notifier.eAdapters().add(this); + } + + return result; + } + + public boolean unadapt(Notifier notifier) { + return notifier.eAdapters().remove(this); + } + + @Override + public final void notifyChanged(Notification msg) { + if (msg.isTouch()) { + return; + } + + handleNotification(msg); + } + + InheritanceAdapter getResourceAdapter() { + return null; + } + + InheritanceAdapter getClassifierAdapter() { + return getResourceAdapter().getClassifierAdapter(); + } + + InheritanceAdapter getGeneralizationAdapter() { + return getResourceAdapter().getGeneralizationAdapter(); + } + + InheritanceAdapter getStructureStereotypeAdapter() { + return getResourceAdapter().getStructureStereotypeAdapter(); + } + + InheritanceAdapter getStateMachineStereotypeAdapter() { + return getResourceAdapter().getStructureStereotypeAdapter(); + } + + protected abstract void handleNotification(Notification msg); + + protected void touch(Notifier notifier) { + // Pass + } + + boolean isResourceLoading() { + return getResourceAdapter().isResourceLoading(); + } + + protected boolean isUndoRedoNotification(Notification msg) { + ReificationAdapter ra = ReificationAdapter.getInstance((Notifier) msg.getNotifier()); + return (ra != null) && ra.isUndoRedoNotification(msg); + } + + boolean isStructureStereotype(EObject object) { + return object.eClass().getEPackage() == UMLRealTimePackage.eINSTANCE; + } + + boolean isStateMachineStereotype(EObject object) { + return object.eClass().getEPackage() == UMLRTStateMachinesPackage.eINSTANCE; + } + + // + // Nested types + // + + private static class ForClassifier extends InheritanceAdapter { + private final ForResource forResource; + + ForClassifier(ForResource forResource) { + super(); + + this.forResource = forResource; + } + + @Override + InheritanceAdapter getResourceAdapter() { + return forResource; + } + + @Override + InheritanceAdapter getClassifierAdapter() { + return this; + } + + @Override + public void setTarget(Notifier newTarget) { + if (newTarget instanceof InternalUMLRTClassifier) { + // Discover existing structure + InternalUMLRTClassifier specific = (InternalUMLRTClassifier) newTarget; + List<Generalization> generalizations = specific.getGeneralizations(); + if (!generalizations.isEmpty()) { + getGeneralizationAdapter().adapt(generalizations.get(0)); + } + } + } + + @Override + public void unsetTarget(Notifier oldTarget) { + if (oldTarget instanceof InternalUMLRTClassifier) { + // Forget existing structure + InternalUMLRTClassifier specific = (InternalUMLRTClassifier) oldTarget; + specific.getGeneralizations().forEach(getGeneralizationAdapter()::unadapt); + } + } + + @Override + protected void handleNotification(Notification msg) { + if ((msg.getFeature() instanceof EReference) && !isUndoRedoNotification(msg)) { + handleReference(msg, (EReference) msg.getFeature()); + } + } + + protected void handleReference(Notification msg, EReference reference) { + if (reference == UMLPackage.Literals.CLASSIFIER__GENERALIZATION) { + // We only listen to RT classifiers + InternalUMLRTClassifier specific = (InternalUMLRTClassifier) msg.getNotifier(); + + // Handle addition/removal of generalizations + switch (msg.getEventType()) { + case Notification.ADD: + // We only support single inheritance + if (specific.getGeneralizations().size() == 1) { + Generalization gen = (Generalization) msg.getNewValue(); + getGeneralizationAdapter().adapt(gen); + } + break; + case Notification.REMOVE: + // We only support single inheritance + if (specific.getGeneralizations().isEmpty()) { + Generalization gen = (Generalization) msg.getOldValue(); + getGeneralizationAdapter().unadapt(gen); + } + break; + case Notification.SET: + // We only support single inheritance + if (specific.getGeneralizations().size() == 1) { + Generalization oldGen = (Generalization) msg.getOldValue(); + Generalization newGen = (Generalization) msg.getNewValue(); + getGeneralizationAdapter().unadapt(oldGen); + getGeneralizationAdapter().adapt(newGen); + } + break; + } + } else if (reference.isContainment() + && UMLPackage.Literals.OPERATION.isSuperTypeOf(reference.getEReferenceType()) + && (msg.getNotifier() instanceof Interface)) { + + // Protocol Messages don't have a stereotype application to trigger this + switch (msg.getEventType()) { + case Notification.ADD: + case Notification.ADD_MANY: + case Notification.SET: + // Inherit the new features + touch((Notifier) msg.getNotifier()); + break; + // TODO: What about removals? + } + } + } + + @Override + protected void touch(Notifier notifier) { + if (!isResourceLoading() && (notifier instanceof InternalUMLRTClassifier)) { + InternalUMLRTClassifier root = (InternalUMLRTClassifier) notifier; + + // Beware of generalization cycles + Set<InternalUMLRTClassifier> seen = new HashSet<>(); + Queue<InternalUMLRTClassifier> breadthFirst = new ArrayDeque<>(); + + // We start at the root of this hierarchy + seen.add(root); + breadthFirst.offer(root); + + for (InternalUMLRTClassifier next = breadthFirst.poll(); next != null; next = breadthFirst.poll()) { + InternalUMLRTClassifier super_ = next; + next.rtSubtypes().forEach(sub -> { + if (seen.add(sub)) { + breadthFirst.offer(sub); + sub.rtInherit(super_); + } + }); + } + } + } + } + + private static class ForGeneralization extends InheritanceAdapter { + private final ForResource forResource; + + ForGeneralization(ForResource forResource) { + super(); + + this.forResource = forResource; + } + + @Override + InheritanceAdapter getResourceAdapter() { + return forResource; + } + + @Override + InheritanceAdapter getGeneralizationAdapter() { + return this; + } + + @Override + public void setTarget(Notifier newTarget) { + if (newTarget instanceof Generalization) { + // Handle the general of the new generalization + Generalization gen = (Generalization) newTarget; + if (isCompatible(gen.getSpecific(), gen.getGeneral())) { + handleGeneralAdded((InternalUMLRTClassifier) gen.getSpecific(), + (InternalUMLRTClassifier) gen.getGeneral()); + } + } + } + + boolean isCompatible(Classifier specific, Classifier general) { + return (specific instanceof InternalUMLRTClassifier) + && (general instanceof InternalUMLRTClassifier) + && (specific.eClass() == general.eClass()); + } + + @Override + public void unsetTarget(Notifier oldTarget) { + if (oldTarget instanceof Generalization) { + // Don't tear down structure unless the generalization is deleted + // or the general unset, which is handled elsewhere + } + } + + @Override + protected void handleNotification(Notification msg) { + if ((msg.getFeature() instanceof EReference) && !isUndoRedoNotification(msg)) { + handleReference(msg, (EReference) msg.getFeature()); + } + } + + protected void handleReference(Notification msg, EReference reference) { + if (reference == UMLPackage.Literals.GENERALIZATION__GENERAL) { + // We only listen to RT classifiers' generalizations + Generalization generalization = (Generalization) msg.getNotifier(); + InternalUMLRTClassifier specific = (InternalUMLRTClassifier) generalization.getSpecific(); + + // Handle change of general + switch (msg.getEventType()) { + case Notification.SET: + case Notification.UNSET: + Classifier oldGeneral = (Classifier) msg.getOldValue(); + if (isCompatible(specific, oldGeneral)) { + handleGeneralRemoved(specific, (InternalUMLRTClassifier) oldGeneral); + } + Classifier newGeneral = (Classifier) msg.getNewValue(); + if (isCompatible(specific, newGeneral)) { + handleGeneralAdded(specific, (InternalUMLRTClassifier) newGeneral); + } + } + } + } + + void handleGeneralAdded(InternalUMLRTClassifier specific, InternalUMLRTClassifier general) { + specific.rtInherit(general); + } + + void handleGeneralRemoved(InternalUMLRTClassifier specific, InternalUMLRTClassifier general) { + specific.rtDisinherit(general); + } + } + + private static class ForResource extends InheritanceAdapter { + private final ForClassifier forClassifier = new ForClassifier(this); + private final ForGeneralization forGeneralization = new ForGeneralization(this); + private final ForStructureStereotype forStructureStereotype = new ForStructureStereotype(this); + private final ForStateMachineStereotype forStateMachineStereotype = new ForStateMachineStereotype(this); + + ForResource(Resource resource) { + super(); + } + + @Override + InheritanceAdapter getClassifierAdapter() { + return forClassifier; + } + + @Override + InheritanceAdapter getGeneralizationAdapter() { + return forGeneralization; + } + + @Override + InheritanceAdapter getStructureStereotypeAdapter() { + return forStructureStereotype; + } + + @Override + InheritanceAdapter getStateMachineStereotypeAdapter() { + return forStateMachineStereotype; + } + + @Override + boolean isResourceLoading() { + return (target != null) && ((Resource.Internal) target).isLoading(); + } + + boolean isUMLRTStereotype(EObject object) { + EPackage ePackage = object.eClass().getEPackage(); + return (ePackage == UMLRealTimePackage.eINSTANCE) + || (ePackage == UMLRTStateMachinesPackage.eINSTANCE); + } + + @Override + public void setTarget(Notifier newTarget) { + super.setTarget(newTarget); + } + + @Override + public void unsetTarget(Notifier oldTarget) { + if (oldTarget == target) { + // Un-discover stereotype applications + Resource resource = (Resource) oldTarget; + resource.getContents().stream() + .filter(this::isUMLRTStereotype) + .forEach(stereo -> stereo.eAdapters().remove(this)); + + super.unsetTarget(oldTarget); + } + } + + @Override + protected void handleNotification(Notification msg) { + if (msg.getNotifier() instanceof Resource) { + if (msg.getFeatureID(Resource.class) == Resource.RESOURCE__CONTENTS) { + // Handle addition/removal of stereotype applications + switch (msg.getEventType()) { + case Notification.ADD: { + EObject newObject = (EObject) msg.getNewValue(); + if (isStructureStereotype(newObject)) { + getStructureStereotypeAdapter().adapt(newObject); + } else if (isStateMachineStereotype(newObject)) { + getStateMachineStereotypeAdapter().adapt(newObject); + } + break; + } + case Notification.REMOVE: { + EObject oldObject = (EObject) msg.getOldValue(); + if (isStructureStereotype(oldObject)) { + getStructureStereotypeAdapter().unadapt(oldObject); + } else if (isStateMachineStereotype(oldObject)) { + getStateMachineStereotypeAdapter().unadapt(oldObject); + } + break; + } + case Notification.SET: { + EObject oldObject = (EObject) msg.getOldValue(); + if (isStructureStereotype(oldObject)) { + getStructureStereotypeAdapter().unadapt(oldObject); + } else if (isStateMachineStereotype(oldObject)) { + getStateMachineStereotypeAdapter().unadapt(oldObject); + } + EObject newObject = (EObject) msg.getNewValue(); + if (isStructureStereotype(newObject)) { + getStructureStereotypeAdapter().adapt(newObject); + } else if (isStateMachineStereotype(newObject)) { + getStateMachineStereotypeAdapter().adapt(newObject); + } + break; + } + case Notification.ADD_MANY: + for (Object next : (Collection<?>) msg.getNewValue()) { + EObject newObject = (EObject) next; + if (isStructureStereotype(newObject)) { + getStructureStereotypeAdapter().adapt(newObject); + } else if (isStateMachineStereotype(newObject)) { + getStateMachineStereotypeAdapter().adapt(newObject); + } + } + break; + case Notification.REMOVE_MANY: + for (Object next : (Collection<?>) msg.getOldValue()) { + EObject oldObject = (EObject) next; + if (isStructureStereotype(oldObject)) { + getStructureStereotypeAdapter().unadapt(oldObject); + } else if (isStateMachineStereotype(oldObject)) { + getStateMachineStereotypeAdapter().unadapt(oldObject); + } + } + break; + } + } else if (msg.getFeatureID(Resource.class) == Resource.RESOURCE__IS_LOADED) { + if (!msg.getOldBooleanValue() && msg.getNewBooleanValue()) { + // The resource has loaded. Process its contents, now + discoverContents((Resource) msg.getNotifier()); + } + } + } + } + + void discoverContents(Resource resource) { + Switch<EObject> discoverySwitch = new UMLRealTimeSwitch<EObject>() { + @Override + public EObject caseCapsule(Capsule object) { + if (object.getBase_Class() != null) { + getClassifierAdapter().touch(object.getBase_Class()); + } + return object; + } + + @Override + public EObject caseProtocol(Protocol object) { + if (object.getBase_Collaboration() != null) { + getClassifierAdapter().touch(object.getBase_Collaboration()); + } + return object; + } + + @Override + public EObject caseRTMessageSet(RTMessageSet object) { + if (object.getBase_Interface() != null) { + getClassifierAdapter().touch(object.getBase_Interface()); + } + return object; + } + }; + + // Discovery of contents can add new stereotype applications + List<EObject> contents = new ArrayList<>(resource.getContents()); + contents.forEach(discoverySwitch::doSwitch); + + int newSize = resource.getContents().size(); + if (newSize != contents.size()) { + System.err.println("Contents changed by: " + (newSize - contents.size())); + } + } + } + + private static class ForStructureStereotype extends InheritanceAdapter { + private final ForResource forResource; + + ForStructureStereotype(ForResource forResource) { + super(); + + this.forResource = forResource; + } + + @Override + InheritanceAdapter getResourceAdapter() { + return forResource; + } + + @Override + InheritanceAdapter getStructureStereotypeAdapter() { + return this; + } + + @Override + public void setTarget(Notifier newTarget) { + if ((newTarget instanceof EObject) && !(newTarget instanceof Resource)) { + EObject added = (EObject) newTarget; + + // A new stereotype application was added + handleStereotypeAdded(added); + } + } + + @Override + public void unsetTarget(Notifier oldTarget) { + if (oldTarget instanceof EObject) { + EObject removed = (EObject) oldTarget; + + handleStereotypeRemoved(removed); + } + } + + @Override + protected void handleNotification(Notification msg) { + // Was base element reference changed? + switch (msg.getEventType()) { + case Notification.SET: + case Notification.UNSET: + if (msg.getFeature() instanceof EReference) { + EReference ref = (EReference) msg.getFeature(); + if (ref.getName().startsWith("base_")) { //$NON-NLS-1$ + EObject application = (EObject) msg.getNotifier(); + + if (msg.getOldValue() != null) { + handleStereotypeRemoved(application); + } + if (msg.getNewValue() != null) { + handleStereotypeAdded(application); + } + } else if (!isResourceLoading()) { + if (ref == UMLRealTimePackage.Literals.RT_REDEFINED_ELEMENT__ROOT_FRAGMENT) { + // Special case: for generating exclusion notifications + notifyExclusion((RTRedefinedElement) msg.getNotifier(), + (RedefinableElement) msg.getOldValue(), + (RedefinableElement) msg.getNewValue()); + } + } + break; + } + } + } + + /** + * Handle addition of a structure stereotype by + * <ul> + * <li>in the case of an UML-RT classifier (capsule/protocol), initializing its façade + * for inheritance etc.</li> + * <li>in the case of a capsule feature (port/part/connector), updating the capsule + * hierarchy to inherit it. This is necessary because the addition of the feature, + * itself, is not a sufficient trigger as it may not yet have the stereotype. + * It depends on the order of operations in the creation of the new feature</li> + * </ul> + */ + void handleStereotypeAdded(EObject stereotypeApplication) { + switch (stereotypeApplication.eClass().getClassifierID()) { + case UMLRealTimePackage.CAPSULE: { + Capsule capsule = (Capsule) stereotypeApplication; + if (capsule.getBase_Class() != null) { + // Initialize it + getClassifierAdapter().adapt(capsule.getBase_Class()); + } + break; + } + case UMLRealTimePackage.RT_PORT: { + RTPort port = (RTPort) stereotypeApplication; + Port base = port.getBase_Port(); + if ((base != null) && (base.getClass_() != null)) { + // Initialize it + getClassifierAdapter().touch(base.getClass_()); + } + break; + } + case UMLRealTimePackage.CAPSULE_PART: { + CapsulePart part = (CapsulePart) stereotypeApplication; + Property base = part.getBase_Property(); + if ((base != null) && (base.getClass_() != null)) { + // Initialize it + getClassifierAdapter().touch(base.getClass_()); + } + break; + } + case UMLRealTimePackage.RT_CONNECTOR: { + RTConnector connector = (RTConnector) stereotypeApplication; + Connector base = connector.getBase_Connector(); + if ((base != null) && (base.getNamespace() instanceof Class)) { + // Initialize it + getClassifierAdapter().touch(base.getNamespace()); + } + break; + } + case UMLRealTimePackage.PROTOCOL: { + Protocol protocol = (Protocol) stereotypeApplication; + if (protocol.getBase_Collaboration() != null) { + // Initialize it + getClassifierAdapter().adapt(protocol.getBase_Collaboration()); + } + break; + } + case UMLRealTimePackage.RT_MESSAGE_SET: { + RTMessageSet messageSet = (RTMessageSet) stereotypeApplication; + if (messageSet.getBase_Interface() != null) { + // Initialize it + getClassifierAdapter().adapt(messageSet.getBase_Interface()); + } + break; + } + // TODO etc. + } + } + + void handleStereotypeRemoved(EObject stereotypeApplication) { + // TODO: Does it make sense to handle removal of a mandatory stereotype? + } + + void notifyExclusion(RTRedefinedElement rtRedef, RedefinableElement oldRoot, RedefinableElement newRoot) { + RedefinableElement uml = rtRedef.getBase_RedefinableElement(); + if (uml != null) { + // The notifications injected here are on derived features, so + // the EMF ChangeRecorder (if any) will ignore them, which is good + // because otherwise trying to apply the change would cause trouble + + Notification exclusionMsg = null; + + if ((oldRoot == null) && (newRoot != null)) { + // Re-inherited + Namespace namespace = uml.getNamespace(); + // Notify on the namespace's excluded members + if (namespace instanceof InternalUMLRTElement) { + InternalEObject ext = (InternalEObject) namespace.eGet(ExtUMLExtPackage.Literals.ELEMENT__EXTENSION); + exclusionMsg = new ENotificationImpl(ext, Notification.REMOVE, + ExtUMLExtPackage.Literals.NAMESPACE__EXCLUDED_MEMBER, + uml, null, Notification.NO_INDEX); + if (ext == null) { + // There isn't actually an extension to forward this notification, + // so do it here + exclusionMsg = NotificationForwarder.wrap((InternalEObject) namespace, exclusionMsg); + } + } + } else if ((oldRoot != null) && (newRoot == null)) { + // Excluded + Namespace namespace = uml.getNamespace(); + // Notify on the namespace's excluded members + if (namespace instanceof InternalUMLRTElement) { + InternalEObject ext = (InternalEObject) namespace.eGet(ExtUMLExtPackage.Literals.ELEMENT__EXTENSION); + exclusionMsg = new ENotificationImpl(ext, Notification.ADD, + ExtUMLExtPackage.Literals.NAMESPACE__EXCLUDED_MEMBER, + null, uml, Notification.NO_INDEX); + if (ext == null) { + // There isn't actually an extension to forward this notification, + // so do it here + exclusionMsg = NotificationForwarder.wrap((InternalEObject) namespace, exclusionMsg); + } + } + } + + if (exclusionMsg != null) { + // And notify on the element's owner to trigger refresh + // of icons etc. in the UI + NotificationChain msgs = new ENotificationImpl((InternalEObject) uml, Notification.SET, + UMLPackage.Literals.NAMED_ELEMENT__QUALIFIED_NAME, + uml.getQualifiedName(), uml.getQualifiedName()) { + + @Override + public boolean isTouch() { + // Don't let clients filtering on isTouch() ignore this + return false; + } + }; + msgs.add(exclusionMsg); + msgs.dispatch(); + } + } + } + } + + private static class ForStateMachineStereotype extends InheritanceAdapter { + private final ForResource forResource; + + ForStateMachineStereotype(ForResource forResource) { + super(); + + this.forResource = forResource; + } + + @Override + InheritanceAdapter getResourceAdapter() { + return forResource; + } + + @Override + InheritanceAdapter getStateMachineStereotypeAdapter() { + return this; + } + + @Override + public void setTarget(Notifier newTarget) { + // TODO Handle state machine inheritance + } + + @Override + public void unsetTarget(Notifier oldTarget) { + // TODO Handle state machine inheritance + } + + @Override + protected void handleNotification(Notification msg) { + // TODO Handle state machine inheritance + } + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/NotificationForwarder.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/NotificationForwarder.java new file mode 100644 index 000000000..59d146bdc --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/NotificationForwarder.java @@ -0,0 +1,333 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.util; + +import java.util.Collection; +import java.util.function.Supplier; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationWrapper; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.common.notify.impl.AdapterImpl; +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.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.util.UMLUtil; + +/** + * An adapter on a redefining element that forwards notifications + * from the element that it redefines, for those features that + * are redefinable and not redefined. + */ +public class NotificationForwarder extends AdapterImpl { + + private final InternalUMLRTElement owner; + private final EReference redefinedElementReference; + private final Collection<? extends EStructuralFeature> inheritedFeatures; + + /** + * Initializes me. + * + * @param owner + * the redefining element + * @param redefinedElementReference + * the reference feature of the {@code owner} + * that has the redefined element at the first position + * @param inheritedFeatures + * the inherited features for which notifications should be forwarded + */ + public NotificationForwarder(InternalUMLRTElement owner, EReference redefinedElementReference, + Collection<? extends EStructuralFeature> inheritedFeatures) { + + this(owner, redefinedElementReference, inheritedFeatures, true); + } + + NotificationForwarder(InternalUMLRTElement owner, EReference redefinedElementReference, + Collection<? extends EStructuralFeature> inheritedFeatures, boolean init) { + super(); + + this.owner = owner; + this.redefinedElementReference = redefinedElementReference; + this.inheritedFeatures = inheritedFeatures; + + if (init) { + initRedefinedElement(); + } + } + + void initRedefinedElement() { + EObject redefined = getRedefinedElement(owner); + + if (redefined != target) { + if (target != null) { + target.eAdapters().remove(this); + } + if (redefined != null) { + redefined.eAdapters().add(this); + } + } + } + + final InternalUMLRTElement owner() { + return owner; + } + + <T extends EObject & InternalUMLRTElement> T getRedefinedElement(T element) { + T result = null; + + if (redefinedElementReference == null) { + // Something like a connector end that isn't (UML-ishly) redefinable + result = element.rtGetRedefinedElement(); + } else { + @SuppressWarnings("unchecked") + EList<T> redefinedElements = (EList<T>) element.eGet(redefinedElementReference); + + if (!redefinedElements.isEmpty()) { + result = redefinedElements.get(0); + } + } + + return result; + } + + final EReference redefinedElementReference() { + return redefinedElementReference; + } + + @Override + public void setTarget(Notifier newTarget) { + // This isn't the one we're interested in + if (newTarget != owner) { + super.setTarget(newTarget); + } + } + + @Override + public void unsetTarget(Notifier oldTarget) { + if ((oldTarget == owner) && (getTarget() != null)) { + // I'm decomissioned. Stop listening to the redefined element + getTarget().eAdapters().remove(this); + } + + super.unsetTarget(oldTarget); + } + + @Override + public boolean isAdapterForType(Object type) { + return type == NotificationForwarder.class; + } + + @Override + public void notifyChanged(Notification msg) { + if (msg.isTouch()) { + return; + } + + handleNotification(msg); + } + + protected void handleNotification(Notification msg) { + if (msg.getNotifier() == owner) { + if (msg.getFeature() == redefinedElementReference) { + initRedefinedElement(); + } + } else if (shouldForward()) { + if (inheritedFeatures.contains(msg.getFeature())) { + EStructuralFeature feature = (EStructuralFeature) msg.getFeature(); + + if (!owner.rtIsSet(feature)) { + forward(msg); + } + } + } + } + + public static void forward(InternalEObject forwarder, Notification msg) { + forwarder.eNotify(wrap(forwarder, msg)); + } + + public static Notification wrap(InternalEObject forwarder, Notification msg) { + return new NotificationWrapper(msg) { + @Override + public Object getNotifier() { + return forwarder; + } + }; + } + + void forward(Notification msg) { + forward(owner, msg); + } + + final boolean shouldForward() { + return owner.eNotificationRequired(); + } + + static boolean isForwarded(Notification notification) { + return (notification instanceof NotificationWrapper) + && NotificationForwarder.class.isAssignableFrom(notification.getClass().getEnclosingClass()); + } + + static NotificationForwarder getInstance(InternalUMLRTElement element) { + NotificationForwarder result = null; + + for (Adapter next : element.eAdapters()) { + if (next.isAdapterForType(NotificationForwarder.class)) { + NotificationForwarder forwarder = (NotificationForwarder) next; + if (forwarder.owner() == element) { + result = forwarder; + break; + } + } + } + + return result; + } + + /** + * Removes the notification forwarder owned by a given {@code element} + * from it, if there is any such. + * + * @param element + * a model element + * + * @return whether any notification forwarder actually was removed + */ + public static boolean unadapt(InternalUMLRTElement element) { + return element.eAdapters().removeIf(a -> a.isAdapterForType(NotificationForwarder.class) + && ((NotificationForwarder) a).owner() == element); + } + + /** + * Ensures that a notification forwarder is attached to a given {@code element} + * without any redundancy. + * + * @param element + * a model element + * @param forwarderSupplier + * in case an owned forwarder is not already attached, + * a supplier that will provide one to add + * + * @return whether any notification forwarder actually was removed + */ + public static boolean adapt(InternalUMLRTElement element, Supplier<? extends NotificationForwarder> forwarderSupplier) { + boolean result = getInstance(element) == null; + + if (result) { + element.eAdapters().add(forwarderSupplier.get()); + } + + return result; + } + + public static void initialize(Object object) { + if (object instanceof InternalUMLRTElement) { + InternalUMLRTElement element = (InternalUMLRTElement) object; + NotificationForwarder forwarder = getInstance(element); + if (forwarder != null) { + forwarder.initRedefinedElement(); + } + } + } + + // + // Nested types + // + + /** + * A specialized notification forwarder for stereotype applications that forwards + * notifications from the corresponding stereotype of the redefined base element. + */ + public static class FromStereotype extends NotificationForwarder { + private final EReference baseElementReference; + + public FromStereotype(InternalUMLRTElement owner, + EReference baseElementReference, + EReference redefinedElementReference, + Collection<? extends EStructuralFeature> inheritedFeatures) { + + super(owner, redefinedElementReference, inheritedFeatures, false); + + this.baseElementReference = baseElementReference; + + initRedefinedElement(); + } + + @Override + <T extends EObject & InternalUMLRTElement> T getRedefinedElement(T element) { + T result = null; + + if (element instanceof Element) { + result = super.getRedefinedElement(element); + } else { + // It's a stereotype application + Element baseElement = (Element) element.eGet(baseElementReference); + if (baseElement instanceof InternalUMLRTElement) { + // Get the redefined of the base element + baseElement = (Element) getRedefinedElement((InternalUMLRTElement) baseElement); + if (baseElement != null) { + // And get the stereotype application + @SuppressWarnings("unchecked") + Class<? extends EObject> stereotype = (Class<? extends EObject>) owner().eClass().getInstanceClass(); + + @SuppressWarnings("unchecked") + T redefined = (T) UMLUtil.getStereotypeApplication(baseElement, stereotype); + result = redefined; + } + } + } + + return result; + } + + @Override + public void setTarget(Notifier newTarget) { + // Our main target is the base element's redefined element's stereotype + if (!(newTarget instanceof Element)) { + super.setTarget(newTarget); + } + } + + @Override + protected void handleNotification(Notification msg) { + if (msg.getFeature() == baseElementReference) { + switch (msg.getEventType()) { + case Notification.SET: + case Notification.UNSET: + // Need to track redefinition changes in my base element + if (msg.getOldValue() != null) { + ((EObject) msg.getOldValue()).eAdapters().remove(this); + } + if (msg.getNewValue() != null) { + ((EObject) msg.getNewValue()).eAdapters().add(this); + } + + // Look at the base element's redefinition + initRedefinedElement(); + break; + } + } else if (msg.getFeature() == redefinedElementReference()) { + // Base element's redefinition has changed + initRedefinedElement(); + } else { + super.handleNotification(msg); + } + } + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/RedefinedElementsList.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/RedefinedElementsList.java new file mode 100644 index 000000000..b7f1c54ad --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/RedefinedElementsList.java @@ -0,0 +1,32 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.util; + +import org.eclipse.emf.common.util.EList; + +/** + * A specialized {@link EList} protocol for lists that implement the + * primary redefinition feature of a model element. + */ +public interface RedefinedElementsList<E> extends EList<E> { + + /** + * Sets the single redefined element, as per UML-RT semantics. + * + * @param redefinedElement + * my redefined element, or {@code null} if I should have none + */ + void setRedefinedElement(E redefinedElement); + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/RedefinedElementsListImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/RedefinedElementsListImpl.java new file mode 100644 index 000000000..beb944aa4 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/RedefinedElementsListImpl.java @@ -0,0 +1,93 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.util; + +import java.util.Collection; +import java.util.function.Consumer; + +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.util.EObjectResolvingEList; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; + +/** + * A specialized reference list for the elements redefined by a model element, + * which notifies the owner when its redefinition state changes. + */ +public class RedefinedElementsListImpl<E> extends EObjectResolvingEList<E> implements RedefinedElementsList<E> { + + private static final long serialVersionUID = 1L; + + private final Consumer<? super E> onRedefinition; + + public RedefinedElementsListImpl(Class<?> dataClass, InternalUMLRTElement owner, int featureID) { + this(dataClass, owner, featureID, null); + } + + public RedefinedElementsListImpl(Class<?> dataClass, InternalUMLRTElement owner, int featureID, + Consumer<? super E> onRedefinition) { + + super(dataClass, owner, featureID); + + this.onRedefinition = onRedefinition; + } + + @Override + public void setRedefinedElement(E redefinedElement) { + if (redefinedElement == null) { + if (!isEmpty()) { + clear(); + } + } else if (isEmpty()) { + add(redefinedElement); + } else { + set(0, redefinedElement); + } + } + + @Override + protected void didAdd(int index, E newObject) { + super.didAdd(index, newObject); + + InternalUMLRTElement owner = (InternalUMLRTElement) getEObject(); + if ((size() == 1) && (NotificationForwarder.getInstance(owner) == null)) { + // Now we are redefining an element, we need to forward notifications + Collection<? extends EStructuralFeature> inherited = owner.rtInheritedFeatures(); + + NotificationForwarder.adapt(owner, + () -> new NotificationForwarder(owner, + (EReference) getEStructuralFeature(), inherited)); + + if (onRedefinition != null) { + onRedefinition.accept(newObject); + } + } + } + + @Override + protected void didRemove(int index, E oldObject) { + super.didRemove(index, oldObject); + + if (size() == 0) { + // Now we are un-redefining an element, we no longer need to + // forward notifications + NotificationForwarder.unadapt((InternalUMLRTElement) getEObject()); + + if (onRedefinition != null) { + onRedefinition.accept(null); + } + } + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/ReificationAdapter.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/ReificationAdapter.java new file mode 100644 index 000000000..d29158e7e --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/ReificationAdapter.java @@ -0,0 +1,419 @@ +/***************************************************************************** + * Copyright (c) 2016, 2017 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.util; + +import static org.eclipse.papyrusrt.umlrt.uml.internal.util.NotificationForwarder.isForwarded; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.WeakHashMap; +import java.util.concurrent.Callable; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Predicate; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.common.util.WrappedException; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.util.EContentAdapter; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTFactory; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTNamedElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionResource; +import org.eclipse.papyrusrt.umlrt.uml.util.ReificationListener; +import org.eclipse.papyrusrt.umlrt.uml.util.UMLRTResourcesUtil; +import org.eclipse.uml2.uml.NamedElement; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.UMLPlugin; + +/** + * An adapter that detects changes to an implicit element and automatically + * reifies it. + */ +public class ReificationAdapter extends EContentAdapter { + + private static final Object TYPE = new Object(); + + // Re-entrant auto-reification suppression for all model elements + // touched during the scope of some action + private final AtomicInteger doNotReify = new AtomicInteger(); + private final Map<NamedElement, Boolean> awaitingReification = new WeakHashMap<>(); + private final Map<NamedElement, Object> listeners = new HashMap<>(); + + private Predicate<? super Notification> undoRedoRecognizer; + + /** + * Initializes me. + */ + public ReificationAdapter() { + super(); + + setUndoRedoRecognizer(null); + } + + public static final ReificationAdapter getInstance(Notifier notifier) { + // Easiest case + ReificationAdapter result = (ReificationAdapter) EcoreUtil.getExistingAdapter(notifier, TYPE); + + if ((result == null) && (notifier instanceof InternalUMLRTElement)) { + // Work a bit harder + ExtensionResource extent = ExtensionResource.getExtensionExtent((InternalUMLRTElement) notifier); + if (extent != null) { + result = extent.getReificationAdapter(); + } + } + + return result; + } + + public static final ReificationAdapter getInstance(ResourceSet resourceSet) { + ReificationAdapter result = (ReificationAdapter) EcoreUtil.getExistingAdapter(resourceSet, TYPE); + if (result == null) { + result = new ReificationAdapter(); + result.addAdapter(resourceSet); + } + return result; + } + + @Override + public boolean isAdapterForType(Object type) { + return type == TYPE; + } + + @Override + public void basicSetTarget(Notifier newTarget) { + // Don't track my targets + } + + @Override + public void notifyChanged(Notification msg) { + // Ignore forwards + if (isForwarded(msg)) { + return; + } + + // Handle propagation to contents + super.notifyChanged(msg); + + if (!msg.isTouch() && (msg.getNotifier() instanceof InternalUMLRTElement)) { + InternalUMLRTElement element = (InternalUMLRTElement) msg.getNotifier(); + if (element.rtIsVirtual()) { + if (!isBaseElementReference(msg.getFeature()) && !isForwarded(msg)) { + // Any real change to my element reifies it, unless + // we have recorded a do-not-reify action for it. + // Note that the stereotype-application events injected by + // Papyrus are not real changes to the element, nor are + // events forwarded from inherited features + int eventType = msg.getEventType(); + if ((eventType >= 0) && (eventType < Notification.EVENT_TYPE_COUNT)) { + if (doNotReify.get() <= 0) { + element.rtReify(); + } + } + } + } + } + } + + @Override + protected void setTarget(EObject target) { + super.setTarget(target); + + if (target instanceof ExtElement) { + // Adding an extension + addAdapter(((ExtElement) target).getExtendedElement()); + } + } + + @Override + protected void unsetTarget(EObject target) { + super.unsetTarget(target); + + if (target instanceof ExtElement) { + // Removing an extension + removeAdapter(((ExtElement) target).getExtendedElement()); + } + } + + @Override + protected void removeAdapter(Notifier notifier, boolean checkContainer, boolean checkResource) { + // We virtual elements have eContainer and eInternalContainer not in + // agreement, so we always have to check the container + super.removeAdapter(notifier, + checkContainer || (notifier instanceof InternalUMLRTElement), + checkResource); + } + + @Override + protected void handleContainment(Notification notification) { + // Don't propagate to contents of extended elements in the model + Object notifier = notification.getNotifier(); + + // Check resource first because CDOResources are EObjects + if (notifier instanceof Resource) { + super.handleContainment(notification); + } else if (notifier instanceof InternalEObject) { + if (((InternalEObject) notifier).eInternalResource() instanceof ExtensionResource) { + super.handleContainment(notification); + + if (notifier instanceof ExtElement) { + // An extension element changed. Did we virtualize UML elements? + EReference reference = (EReference) notification.getFeature(); + + if (UMLPackage.Literals.NAMED_ELEMENT.isSuperTypeOf(reference.getEReferenceType())) { + // Added/removed something + switch (notification.getEventType()) { + case Notification.ADD: + notifyReification((NamedElement) notification.getNewValue(), false); + break; + case Notification.ADD_MANY: + @SuppressWarnings("unchecked") + Collection<? extends NamedElement> added = (Collection<? extends NamedElement>) notification.getNewValue(); + added.stream().forEach(e -> notifyReification(e, false)); + break; + case Notification.REMOVE: + awaitingReification.put((NamedElement) notification.getOldValue(), true); + break; + case Notification.REMOVE_MANY: + @SuppressWarnings("unchecked") + Collection<? extends NamedElement> removed = (Collection<? extends NamedElement>) notification.getOldValue(); + removed.stream().forEach(e -> awaitingReification.put(e, true)); + break; + case Notification.SET: + case Notification.UNSET: + // Reference lists don't allow nulls, but scalar + // containments references do + if (notification.getOldValue() != null) { + awaitingReification.put((NamedElement) notification.getOldValue(), true); + } + if (notification.getNewValue() != null) { + notifyReification((NamedElement) notification.getNewValue(), false); + } + break; + } + } + } + } else if (notifier instanceof InternalUMLRTElement) { + // A real model element changed. Did we reify UML elements? + EReference reference = (EReference) notification.getFeature(); + if (UMLPackage.Literals.NAMED_ELEMENT.isSuperTypeOf(reference.getEReferenceType())) { + switch (notification.getEventType()) { + case Notification.ADD: + notifyReification((NamedElement) notification.getNewValue(), true); + break; + case Notification.ADD_MANY: + @SuppressWarnings("unchecked") + Collection<? extends NamedElement> added = (Collection<? extends NamedElement>) notification.getNewValue(); + added.stream().forEach(e -> notifyReification(e, true)); + break; + case Notification.SET: + case Notification.UNSET: + // Reference lists don't allow nulls, but scalar + // containments references do + if (notification.getNewValue() != null) { + notifyReification((NamedElement) notification.getNewValue(), true); + } + break; + } + } + } + } else { + super.handleContainment(notification); + } + } + + @Override + public void addAdapter(Notifier notifier) { + // We only track the contents of the extension extent and selected elements in the model + if (!(notifier instanceof Resource) || notifier instanceof ExtensionResource) { + ListIterator<Adapter> adapters = notifier.eAdapters().listIterator(); + boolean more = adapters.hasNext(); + while (more) { + Adapter next = adapters.next(); + if (next == this) { + break; + } else if (next instanceof ReificationAdapter) { + // Replace it (it is left over from another extension extent) + adapters.set(this); + break; + } + + more = adapters.hasNext(); + if (!more) { + // Add me now + adapters.add(this); + break; + } + } + } + } + + private void notifyReification(NamedElement element, boolean reified) { + if (reified) { + removeAdapter(element); + if (awaitingReification.remove(element) == null) { + // An element is not reified that never was virtual + return; + } + } else { + // Listen for changes that trigger reification + addAdapter(element); + } + + List<ReificationListener> listeners = getListeners(element); + if ((listeners != null) && !listeners.isEmpty()) { + UMLRTNamedElement facade = UMLRTFactory.create(element); + if (facade != null) { + // This is safe against comodification + listeners.forEach(l -> { + try { + l.reificationStateChanged(facade, reified); + } catch (Exception e) { + // TODO: Need our own EMFPlugin? + UMLPlugin.INSTANCE.log(e); + } + }); + } + } + } + + public void run(Runnable action) { + disableAutoReification(); + + try { + action.run(); + } finally { + enableAutoReification(); + } + } + + public <V> V run(Callable<V> action) { + V result; + + disableAutoReification(); + + try { + result = action.call(); + } catch (Exception e) { + throw new WrappedException(e); + } finally { + enableAutoReification(); + } + + return result; + } + + public void disableAutoReification() { + doNotReify.incrementAndGet(); + } + + public void enableAutoReification() { + doNotReify.decrementAndGet(); + } + + protected boolean isBaseElementReference(Object feature) { + boolean result = false; + + if (feature instanceof EReference) { + EReference reference = (EReference) feature; + result = (reference.getName() != null) + && reference.getName().startsWith("base_") + && UMLPackage.Literals.ELEMENT.isSuperTypeOf(reference.getEReferenceType()) + && !UMLPackage.Literals.ELEMENT.isSuperTypeOf(reference.getEContainingClass()); + } + + return result; + } + + public void addListener(NamedElement element, ReificationListener listener) { + Object existing = listeners.get(element); + if (existing == null) { + listeners.put(element, listener); + } else if (existing != listener) { + if (existing instanceof List<?>) { + @SuppressWarnings("unchecked") + CopyOnWriteArrayList<ReificationListener> list = (CopyOnWriteArrayList<ReificationListener>) existing; + list.addIfAbsent(listener); + } else { + CopyOnWriteArrayList<ReificationListener> list = new CopyOnWriteArrayList<>( + new ReificationListener[] { (ReificationListener) existing, listener }); + listeners.put(element, list); + } + } + } + + public void removeListener(NamedElement element, ReificationListener listener) { + Object existing = listeners.get(element); + if (existing != null) { + if (existing == listener) { + listeners.remove(element); + } else if (existing instanceof List<?>) { + ((List<?>) existing).remove(listener); + } + } + } + + @SuppressWarnings("unchecked") + private List<ReificationListener> getListeners(NamedElement element) { + Object result = listeners.get(element); + + return (result == null) + ? null + : (result instanceof List<?>) + ? (List<ReificationListener>) result + : Collections.singletonList((ReificationListener) result); + } + + /** + * Some adapters in the UML-RT Façade API react to changes in the model to maintain + * a correct (for UML-RT) semantic structure in the UML model, but those adaptations + * are best avoided when changes result from undo/redo of recorded commands. This + * API provides the façade API with the means to recognize changes that are triggered + * by undo or redo (such as in a transactional editing domain). + * + * @param undoRedoRecognizer + * a predicate that matches notifications triggered by undo/redo + * + * @see UMLRTResourcesUtil#setUndoRedoRecognizer(ResourceSet, Predicate) + */ + public final void setUndoRedoRecognizer(Predicate<? super Notification> undoRedoRecognizer) { + this.undoRedoRecognizer = (undoRedoRecognizer == null) + ? __ -> false + : undoRedoRecognizer; + } + + /** + * Queries whether a {@code notification} was triggered by undo or redo + * of an editing command. + * + * @param notification + * a notification + * @return whether it signals an undo or redo of an edit + */ + public boolean isUndoRedoNotification(Notification notification) { + return undoRedoRecognizer.test(notification); + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/SubsetSupersetRedefinedElementsList.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/SubsetSupersetRedefinedElementsList.java new file mode 100644 index 000000000..338f9258d --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/SubsetSupersetRedefinedElementsList.java @@ -0,0 +1,94 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.util; + +import java.util.Collection; +import java.util.function.Consumer; + +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.uml2.common.util.SubsetSupersetEObjectResolvingEList; + +/** + * A specialized subset reference list for the elements redefined by a model element, + * which notifies the owner when its redefinition state changes. + */ +public class SubsetSupersetRedefinedElementsList<E> extends SubsetSupersetEObjectResolvingEList<E> implements RedefinedElementsList<E> { + + private static final long serialVersionUID = 1L; + + private final Consumer<? super E> onRedefinition; + + public SubsetSupersetRedefinedElementsList(Class<?> dataClass, InternalUMLRTElement owner, int featureID, int[] supersetFeatureIDs, int[] subsetFeatureIDs) { + this(dataClass, owner, featureID, supersetFeatureIDs, subsetFeatureIDs, null); + } + + public SubsetSupersetRedefinedElementsList(Class<?> dataClass, InternalUMLRTElement owner, int featureID, int[] supersetFeatureIDs, int[] subsetFeatureIDs, + Consumer<? super E> onRedefinition) { + + super(dataClass, owner, featureID, supersetFeatureIDs, subsetFeatureIDs); + + this.onRedefinition = onRedefinition; + } + + @Override + public void setRedefinedElement(E redefinedElement) { + if (redefinedElement == null) { + if (!isEmpty()) { + clear(); + } + } else if (isEmpty()) { + add(redefinedElement); + } else { + set(0, redefinedElement); + } + } + + @Override + protected void didAdd(int index, E newObject) { + super.didAdd(index, newObject); + + if ((size() == 1) && (EcoreUtil.getExistingAdapter(getEObject(), NotificationForwarder.class) == null)) { + // Now we are redefining an element, we need to forward notifications + InternalUMLRTElement owner = (InternalUMLRTElement) getEObject(); + Collection<? extends EStructuralFeature> inherited = owner.rtInheritedFeatures(); + + NotificationForwarder.adapt(owner, + () -> new NotificationForwarder(owner, + (EReference) getEStructuralFeature(), inherited)); + + if (onRedefinition != null) { + onRedefinition.accept(newObject); + } + } + } + + @Override + protected void didRemove(int index, E oldObject) { + super.didRemove(index, oldObject); + + if (size() == 0) { + // Now we are un-redefining an element, we no longer need to + // forward notifications + NotificationForwarder.unadapt((InternalUMLRTElement) getEObject()); + + if (onRedefinition != null) { + onRedefinition.accept(null); + } + } + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/UMLRTUMLResourceFactoryImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/UMLRTUMLResourceFactoryImpl.java new file mode 100644 index 000000000..56f77854c --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/UMLRTUMLResourceFactoryImpl.java @@ -0,0 +1,55 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.util; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EFactory; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.uml2.uml.internal.resource.UMLResourceFactoryImpl; +import org.eclipse.uml2.uml.resource.UMLResource; + +/** + * Custom UML resource factory that ensures usage of {@link EFactory} instances + * registered locally in the resource set when instantiating elements from the + * feature type in case that that XMI Type is implied. + */ +public class UMLRTUMLResourceFactoryImpl extends UMLResourceFactoryImpl { + + public static final UMLResource.Factory INSTANCE = new UMLRTUMLResourceFactoryImpl(); + + protected UMLRTUMLResourceFactoryImpl() { + super(); + } + + @Override + public Resource createResourceGen(URI uri) { + UMLResource result; + + // FIXME: Require a content-type based on the UML-RT profile + String uriString = uri.toString(); + if (uriString.startsWith(UMLResource.LIBRARIES_PATHMAP) + || uriString.startsWith(UMLResource.PROFILES_PATHMAP) + || uriString.startsWith(UMLResource.METAMODELS_PATHMAP) + || uriString.startsWith("pathmap://UML_RT_PROFILE/") //$NON-NLS-1$ + || uriString.startsWith("platform:/plugin/org.eclipse.uml2")) { //$NON-NLS-1$ + result = (UMLResource) super.createResourceGen(uri); + } else { + result = new UMLRTUMLResourceImpl(uri); + result.setEncoding(UMLResource.DEFAULT_ENCODING); + } + + return result; + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/UMLRTUMLResourceImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/UMLRTUMLResourceImpl.java new file mode 100644 index 000000000..ac9df9c60 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/UMLRTUMLResourceImpl.java @@ -0,0 +1,116 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.internal.util; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EFactory; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.EcorePackage; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.util.ExtendedMetaData; +import org.eclipse.emf.ecore.xmi.XMLLoad; +import org.eclipse.uml2.uml.internal.resource.UMLHandler; +import org.eclipse.uml2.uml.internal.resource.UMLLoadImpl; +import org.eclipse.uml2.uml.internal.resource.UMLResourceImpl; +import org.xml.sax.helpers.DefaultHandler; + +/** + * Custom UML resource that ensures usage of {@link EFactory} instances + * registered locally in the resource set when instantiating elements + * from the feature type in case that that XMI Type is implied. + */ +class UMLRTUMLResourceImpl extends UMLResourceImpl { + UMLRTUMLResourceImpl(URI uri) { + super(uri); + + InheritanceAdapter.getInstance(this).adapt(this); + } + + @Override + protected XMLLoad createXMLLoad() { + return new UMLLoadImpl(createXMLHelper()) { + @Override + protected DefaultHandler makeDefaultHandler() { + return new UMLHandler(resource, helper, options) { + @Override + protected EObject createObjectFromFeatureType(EObject peekObject, EStructuralFeature feature) { + String typeName = null; + EFactory factory = null; + EClassifier eType = (feature == null) ? null : feature.getEType(); + EObject obj = null; + + if (eType != null) { + boolean isUnspecifiedFeature = (extendedMetaData != null) + && (eType == EcorePackage.Literals.EOBJECT) + && (extendedMetaData.getFeatureKind(feature) != ExtendedMetaData.UNSPECIFIED_FEATURE); + + if (useNewMethods) { + if (isUnspecifiedFeature) { + eType = anyType; + typeName = extendedMetaData.getName(anyType); + factory = getEFactory(anyType); + } else { + factory = getEFactory(eType); + typeName = (extendedMetaData == null) ? eType.getName() : extendedMetaData.getName(eType); + } + + obj = createObject(factory, eType, false); + } else { + if (isUnspecifiedFeature) { + typeName = extendedMetaData.getName(anyType); + factory = getEFactory(anyType); + } else { + EClass eClass = (EClass) eType; + typeName = extendedMetaData == null ? eClass.getName() : extendedMetaData.getName(eClass); + factory = getEFactory(eClass); + } + obj = createObjectFromFactory(factory, typeName); + } + } + + obj = validateCreateObjectFromFactory(factory, typeName, obj, feature); + + if (obj != null) { + setFeatureValue(peekObject, feature, obj); + } + + processObject(obj); + return obj; + } + }; + } + }; + } + + EFactory getEFactory(EClassifier eClassifier) { + EFactory result; + + ResourceSet rset = getResourceSet(); + if (rset != null) { + EPackage ePackage = eClassifier.getEPackage(); + result = rset.getPackageRegistry().getEFactory(ePackage.getNsURI()); + if (result == null) { + result = ePackage.getEFactoryInstance(); + } + } else { + result = eClassifier.getEPackage().getEFactoryInstance(); + } + + return result; + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/InheritanceKind.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/InheritanceKind.java new file mode 100644 index 000000000..d5301e702 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/InheritanceKind.java @@ -0,0 +1,89 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.util; + +import java.util.Comparator; + +import org.eclipse.papyrusrt.umlrt.uml.UMLRTNamedElement; +import org.eclipse.uml2.uml.Element; + +/** + * Enumeration of the possible inheritance states of an element in an UML-RT model. + */ +public enum InheritanceKind { + /** The element is inherited from another namespace and not redefined. */ + INHERITED, + /** The element is inherited from another namespace and is locally redefined. */ + REDEFINED, + /** The element is inherited from another namespace and is locally redefined as excluded. */ + EXCLUDED, + /** The element is a local owned definition, not redefining any inherited element. */ + NONE; + + /** + * Queries the inheritance kind of an {@link element}. + * + * @param element + * an element in the UML-RT model + * + * @return its inheritance kind: never {@code null}, but maybe {@link #NONE} + */ + public static InheritanceKind of(Element element) { + InheritanceKind result = NONE; + + if (UMLRTExtensionUtil.isInherited(element)) { + if (UMLRTExtensionUtil.isVirtualElement(element)) { + result = INHERITED; + } else if (UMLRTExtensionUtil.isExcluded(element)) { + result = EXCLUDED; + } else { + result = REDEFINED; + } + } + + return result; + } + + /** + * Queries the inheritance kind of an {@link element}. + * + * @param element + * an element in the UML-RT model + * + * @return its inheritance kind: never {@code null}, but maybe {@link #NONE} + */ + public static InheritanceKind of(UMLRTNamedElement element) { + return of(element.toUML()); + } + + /** + * Obtains a comparator that sorts model elements by inheritance kind, + * in the order of the kind values. + * + * @return an inheritance kind comparator + */ + public static Comparator<Element> comparator() { + return Comparator.comparing(InheritanceKind::of); + } + + /** + * Obtains a comparator that sorts model elements by inheritance kind, + * in the order of the kind values. + * + * @return an inheritance kind comparator + */ + public static Comparator<UMLRTNamedElement> facadeComparator() { + return Comparator.comparing(UMLRTNamedElement::toUML, comparator()); + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/Pair.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/Pair.java new file mode 100644 index 000000000..bf61992e5 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/Pair.java @@ -0,0 +1,619 @@ +/***************************************************************************** + * Copyright (c) 2016, 2017 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.util; + +import java.io.Serializable; +import java.lang.reflect.Array; +import java.util.Collection; +import java.util.Collections; +import java.util.ConcurrentModificationException; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.RandomAccess; +import java.util.function.IntConsumer; +import java.util.function.IntSupplier; + +/** + * An ordered collection of two elements. It does not support null values. + */ +public class Pair<E> implements List<E>, RandomAccess, Cloneable, Serializable { + + private static final long serialVersionUID = 1L; + + private E first; + private E second; + + private transient int modificationCount; + + /** + * Initializes me. + */ + public Pair(E first, E second) { + super(); + + this.first = Objects.requireNonNull(first, "first"); //$NON-NLS-1$ + this.second = Objects.requireNonNull(second, "first"); //$NON-NLS-1$ + } + + public static <E, T extends E, U extends E> Pair<E> of(T first, U second) { + return new Pair<>(first, second); + } + + public E setFirst(E newFirst) { + E result = first; + first = Objects.requireNonNull(newFirst, "newFirst"); //$NON-NLS-1$ + modificationCount = modificationCount + 1; + return result; + } + + public E setSecond(E newSecond) { + E result = second; + second = Objects.requireNonNull(newSecond, "newSecond"); //$NON-NLS-1$ + modificationCount = modificationCount + 1; + return result; + } + + @Override + public int hashCode() { + return Objects.hash(first, second); + } + + @Override + public boolean equals(Object obj) { + boolean result; + + if (obj == null) { + result = false; + } else if (obj == this) { + result = true; + } else if (obj instanceof List<?>) { + List<?> other = (List<?>) obj; + result = (other.size() == 2) && first.equals(other.get(0)) && second.equals(other.get(1)); + } else { + result = false; + } + + return result; + } + + @Override + public int size() { + return 2; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public boolean contains(Object o) { + return first.equals(o) || second.equals(o); + } + + void checkModificationCount(int expected) { + if (modificationCount != expected) { + throw new ConcurrentModificationException(); + } + } + + int getModificationCount() { + return modificationCount; + } + + @Override + public Iterator<E> iterator() { + return new Itr<>(this, modificationCount, this::checkModificationCount); + } + + @Override + public Object[] toArray() { + return new Object[] { first, second }; + } + + @SuppressWarnings("unchecked") + @Override + public <T> T[] toArray(T[] a) { + if (a.length >= 2) { + a[0] = (T) first; + a[1] = (T) second; + if (a.length > 2) { + a[2] = null; + } + } else { + a = (T[]) Array.newInstance(a.getClass().getComponentType(), 2); + toArray(a); + } + + return a; + } + + @Override + public boolean add(E e) { + throw new UnsupportedOperationException("add"); //$NON-NLS-1$ + } + + @Override + public boolean remove(Object o) { + throw new UnsupportedOperationException("remove"); //$NON-NLS-1$ + } + + @Override + public boolean containsAll(Collection<?> c) { + // Can't short-circuit on collections of more than 2 elements + // because they could have duplicates to the point of having + // 2 or fewer distinct elements + + for (Object next : c) { + if (!contains(next)) { + return false; + } + } + return true; + } + + @Override + public boolean addAll(Collection<? extends E> c) { + throw new UnsupportedOperationException("addAll"); //$NON-NLS-1$ + } + + @Override + public boolean addAll(int index, Collection<? extends E> c) { + throw new UnsupportedOperationException("addAll"); //$NON-NLS-1$ + } + + @Override + public boolean removeAll(Collection<?> c) { + throw new UnsupportedOperationException("removeAll"); //$NON-NLS-1$ + } + + @Override + public boolean retainAll(Collection<?> c) { + throw new UnsupportedOperationException("retainAll"); //$NON-NLS-1$ + } + + @Override + public void clear() { + throw new UnsupportedOperationException("clear"); //$NON-NLS-1$ + } + + @Override + public E get(int index) { + switch (index) { + case 0: + return first; + case 1: + return second; + default: + throw new IndexOutOfBoundsException(String.valueOf(index)); + } + } + + @Override + public E set(int index, E element) { + E result; + + switch (index) { + case 0: + result = first; + first = element; + break; + case 1: + result = second; + second = element; + break; + default: + throw new IndexOutOfBoundsException(String.valueOf(index)); + } + + return result; + } + + @Override + public void add(int index, E element) { + throw new UnsupportedOperationException("add"); //$NON-NLS-1$ + } + + @Override + public E remove(int index) { + throw new UnsupportedOperationException("remove"); //$NON-NLS-1$ + } + + @Override + public int indexOf(Object o) { + return first.equals(o) ? 0 : second.equals(o) ? 1 : -1; + } + + @Override + public int lastIndexOf(Object o) { + return second.equals(o) ? 1 : first.equals(o) ? 0 : -1; + } + + @Override + public ListIterator<E> listIterator() { + return listIterator(0); + } + + @Override + public ListIterator<E> listIterator(int index) { + return new ListItr<>(this, index, this::checkModificationCount, this::getModificationCount); + } + + @Override + public List<E> subList(int fromIndex, int toIndex) { + if ((fromIndex < 0) || (fromIndex > 2)) { + throw new IndexOutOfBoundsException("fromIndex: " + fromIndex); + } + if ((toIndex < fromIndex) || (toIndex > 2)) { + throw new IndexOutOfBoundsException("toIndex: " + toIndex); + } + + return (fromIndex == toIndex) + // Cannot add/remove anyways, so may as well be immutable + ? Collections.emptyList() + : ((toIndex - fromIndex) == 2) + // That's the whole range + ? this + // All that's left is a singleton + : new SingletonSublist<>(this, fromIndex, this::checkModificationCount, this::getModificationCount); + } + + // + // Nested types + // + + /** + * A simple iterator for fixed-size lists that does not support removing. + */ + private static class Itr<E> implements Iterator<E> { + private final List<E> list; + private final int expectedModCount; + private final IntConsumer checkModificationCount; + private int cursor; + + Itr(List<E> list, int expectedModCount, IntConsumer checkModificationCount) { + this.list = list; + this.expectedModCount = expectedModCount; + this.checkModificationCount = checkModificationCount; + } + + @Override + public boolean hasNext() { + return cursor < 2; + } + + @Override + public E next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + + checkModificationCount.accept(expectedModCount); + + E result = list.get(cursor); + cursor = cursor + 1; + return result; + } + } + + /** + * A simple list iterator for fixed-size lists that supports setting a position but not adding nor removing. + */ + private static class ListItr<E> implements ListIterator<E> { + private final List<E> list; + private final IntConsumer checkModificationCount; + private final IntSupplier getModificationCount; + private int expectedModCount; + private int cursor; + private boolean forward; + private E lastReturned; + + ListItr(List<E> list, int index, IntConsumer checkModificationCount, IntSupplier getModificationCount) { + if ((index < 0) || (index > list.size())) { + throw new IndexOutOfBoundsException(String.valueOf(index)); + } + + this.list = list; + this.cursor = index; + this.checkModificationCount = checkModificationCount; + this.getModificationCount = getModificationCount; + + this.expectedModCount = getModificationCount.getAsInt(); + } + + @Override + public boolean hasNext() { + return cursor < list.size(); + } + + @Override + public boolean hasPrevious() { + return cursor > 0; + } + + @Override + public E next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + + checkModificationCount.accept(expectedModCount); + + E result = list.get(cursor); + cursor = cursor + 1; + lastReturned = result; + forward = true; + return result; + } + + @Override + public E previous() { + if (!hasPrevious()) { + throw new NoSuchElementException(); + } + + checkModificationCount.accept(expectedModCount); + + cursor = cursor - 1; + E result = list.get(cursor); + lastReturned = result; + forward = false; + return result; + } + + @Override + public int nextIndex() { + return cursor; + } + + @Override + public int previousIndex() { + return cursor - 1; + } + + @Override + public void set(E e) { + if (lastReturned == null) { + throw new IllegalStateException("no next nor previous returned"); //$NON-NLS-1$ + } + + int size = list.size(); + if (cursor == 0) { + if (forward) { + // Cannot have gone forwards to 0 + throw new IllegalStateException("no next nor previous returned"); //$NON-NLS-1$ + } else { + list.set(cursor, e); + } + } else if (cursor < size) { + if (forward) { + list.set(cursor - 1, e); + } else { + list.set(cursor, e); + } + } else if (cursor == size) { + if (forward) { + list.set(cursor - 1, e); + } else { + // Cannot have gone backwards to 2 + throw new IllegalStateException("no next nor previous returned"); //$NON-NLS-1$ + } + } else { + throw new IllegalStateException("invalid cursor: " + cursor); //$NON-NLS-1$ + } + + expectedModCount = getModificationCount.getAsInt(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException("remove"); //$NON-NLS-1$ + } + + @Override + public void add(E e) { + throw new UnsupportedOperationException("add"); //$NON-NLS-1$ + } + } + + /** + * A simple sublist of a pair, of fixed size one. + */ + private static class SingletonSublist<E> implements List<E> { + private final List<E> list; + private final IntConsumer checkModificationCount; + private final IntSupplier getModificationCount; + private final int index; + + SingletonSublist(List<E> list, int index, IntConsumer checkModificationCount, IntSupplier getModificationCount) { + this.list = list; + this.index = index; + this.checkModificationCount = checkModificationCount; + this.getModificationCount = getModificationCount; + } + + @Override + public int hashCode() { + return get(0).hashCode(); + } + + @Override + public boolean equals(Object obj) { + boolean result; + + if (obj == null) { + result = false; + } else if (obj == this) { + result = true; + } else if (obj instanceof List<?>) { + List<?> other = (List<?>) obj; + result = (other.size() == 1) && get(0).equals(other.get(0)); + } else { + result = false; + } + + return result; + } + + @Override + public int size() { + return 1; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public boolean contains(Object o) { + return get(0).equals(o); + } + + @Override + public Iterator<E> iterator() { + return new Itr<>(this, getModificationCount.getAsInt(), checkModificationCount); + } + + @Override + public Object[] toArray() { + return new Object[] { get(0) }; + } + + @SuppressWarnings("unchecked") + @Override + public <T> T[] toArray(T[] a) { + if (a.length >= 1) { + a[0] = (T) get(0); + if (a.length > 1) { + a[1] = null; + } + } else { + a = (T[]) Array.newInstance(a.getClass().getComponentType(), 1); + a[0] = (T) get(0); + } + + return a; + } + + @Override + public boolean add(E e) { + throw new UnsupportedOperationException("add"); + } + + @Override + public boolean remove(Object o) { + throw new UnsupportedOperationException("remove"); + } + + @Override + public boolean containsAll(Collection<?> c) { + E element = get(0); + for (Object next : c) { + if (!element.equals(next)) { + return false; + } + } + return true; + } + + @Override + public boolean addAll(Collection<? extends E> c) { + throw new UnsupportedOperationException("addAll"); + } + + @Override + public boolean addAll(int index, Collection<? extends E> c) { + throw new UnsupportedOperationException("addAll"); + } + + @Override + public boolean removeAll(Collection<?> c) { + throw new UnsupportedOperationException("removeAll"); + } + + @Override + public boolean retainAll(Collection<?> c) { + throw new UnsupportedOperationException("retainAll"); + } + + @Override + public void clear() { + throw new UnsupportedOperationException("clear"); + } + + @Override + public E get(int index) { + if (index != 0) { + throw new IndexOutOfBoundsException(String.valueOf(index)); + } + return list.get(this.index); + } + + @Override + public E set(int index, E element) { + if (index != 0) { + throw new IndexOutOfBoundsException(String.valueOf(index)); + } + return list.set(this.index, element); + } + + @Override + public void add(int index, E element) { + throw new UnsupportedOperationException("add"); + } + + @Override + public E remove(int index) { + throw new UnsupportedOperationException("remove"); + } + + @Override + public int indexOf(Object o) { + return get(0).equals(o) ? 0 : -1; + } + + @Override + public int lastIndexOf(Object o) { + return get(0).equals(o) ? 0 : -1; + } + + @Override + public ListIterator<E> listIterator() { + return listIterator(0); + } + + @Override + public ListIterator<E> listIterator(int index) { + return new ListItr<>(this, index, checkModificationCount, getModificationCount); + } + + @Override + public List<E> subList(int fromIndex, int toIndex) { + if ((fromIndex < 0) || (fromIndex > 1)) { + throw new IndexOutOfBoundsException("fromIndex: " + fromIndex); + } + if ((toIndex < fromIndex) || (toIndex > 1)) { + throw new IndexOutOfBoundsException("toIndex: " + toIndex); + } + + return (fromIndex == toIndex) + ? Collections.emptyList() // Cannot add/remove anyways, so may as well be immutable + : this; // That's the whole range + } + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/ReificationListener.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/ReificationListener.java new file mode 100644 index 000000000..8805adb45 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/ReificationListener.java @@ -0,0 +1,35 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.util; + +import org.eclipse.papyrusrt.umlrt.uml.UMLRTNamedElement; + +/** + * Call-back that signals reification (or un-reification) of an element. + */ +public interface ReificationListener { + /** + * Notifies the receiver that an {@code element} has been {@code reified} + * or unreified (which usually only happens in the case of undo). + * This notification is sent immediately upon the change in the {@code element}'s + * reiication state; it is not delayed in any way as perhaps by a transaction. + * + * @param element + * an UML-RT façade element + * @param reified + * {@code true} if it changed from virtual to real state; + * {@code false} if it changed from real to virtual state + */ + void reificationStateChanged(UMLRTNamedElement element, boolean reified); +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/UMLRTExtensionUtil.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/UMLRTExtensionUtil.java new file mode 100644 index 000000000..79da9aa3e --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/UMLRTExtensionUtil.java @@ -0,0 +1,223 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.util; + +import java.util.Collections; +import java.util.List; + +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTNamedElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * Utilities for working with the UML-RT extension of the UML metamodel. + */ +public class UMLRTExtensionUtil { + + /** + * Not instantiable by clients. + */ + private UMLRTExtensionUtil() { + super(); + } + + /** + * Queries whether an UML {@code element} supports the extension + * facility for UML-RT semantics. + * + * @param element + * a model element + * + * @return whether it implements the UML-RT extensions + */ + public static boolean hasUMLRTExtension(Element element) { + return element instanceof InternalUMLRTElement; + } + + /** + * Queries whether an {@code element} is a virtual model element, + * not actually present in the model but implied via the UML-RT + * semantics of inheritance and incremental redefinition. + * + * @param element + * an element + * @return whether it is a virtual element + * + * @see #isRedefinition(Element) + * @see #isExcluded(Element) + */ + public static boolean isVirtualElement(Element element) { + return (element instanceof InternalUMLRTElement) + && ((InternalUMLRTElement) element).rtIsVirtual(); + } + + /** + * Queries whether an {@code element} is a redefinition of an + * inherited element and is not redefined in order to exclude + * the element. + * + * @param element + * an element + * @return whether it is a redefinition + * + * @see #isVirtualElement(Element) + * @see #isExcluded(Element) + */ + public static boolean isRedefinition(Element element) { + boolean result = false; + + if (element instanceof InternalUMLRTElement) { + InternalUMLRTElement rt = (InternalUMLRTElement) element; + + result = rt.rtIsRedefinition() && !rt.rtIsExcluded() && !rt.rtIsVirtual(); + } + + return result; + } + + /** + * Queries whether an {@code element} is an exclusion of an + * inherited element. + * + * @param element + * an element + * @return whether it is an exclusion + * + * @see #isVirtualElement(Element) + * @see #isRedefinition(Element) + */ + public static boolean isExcluded(Element element) { + return (element instanceof InternalUMLRTElement) + && ((InternalUMLRTElement) element).rtIsExcluded(); + } + + /** + * Queries whether an {@code element} is some kind of inherited + * element, whether {@link #isVirtualElement(Element) virtual}, + * {@link #isRedefinition(Element) redefined}, or + * {@link #isExcluded(Element) excluded}. + * + * @param element + * an element + * @return whether it is an inherited element + * + * @see #isRedefinition(Element) + * @see #isExcluded(Element) + */ + public static boolean isInherited(Element element) { + return (element instanceof InternalUMLRTElement) + && ((InternalUMLRTElement) element).rtIsRedefinition(); + } + + /** + * Queries whether an {@code element} is a virtual model element, + * not actually present in the model but implied via the UML-RT + * semantics of inheritance and incremental redefinition. + * + * @param element + * an element + * @return whether it is a virtual element + */ + public static boolean isVirtualElement(UMLRTNamedElement element) { + return isVirtualElement(element.toUML()); + } + + /** + * Runs an {@code action} that modifies some {@code element} without + * affecting its {@linkplain #isVirtualElement(Element) real/virtual state}. + * + * @param element + * a model element + * @param action + * an action that modifies it in some way + */ + public static void run(Element element, Runnable action) { + InternalUMLRTElement context = null; + + if (element instanceof InternalUMLRTElement) { + context = (InternalUMLRTElement) element; + } + + if (context == null) { + // Just run the action + action.run(); + } else { + context.run(action); + } + } + + /** + * Runs an {@code action} that modifies some façade {@code element} without + * affecting its {@linkplain #isVirtualElement(UMLRTNamedElement) real/virtual state}. + * + * @param element + * a model element + * @param action + * an action that modifies it in some way + */ + public static void run(UMLRTNamedElement element, Runnable action) { + run(element.toUML(), action); + } + + /** + * For a given UML metamodel feature, obtains the corresponding extension feature, if any, + * that stores "shadows" defined locally in an element for inherited elements or values. + * + * @param umlFeature + * a feature in the UML metamodel + * + * @return the corresponding extension feature, or {@code null} if there is none + * + * @see #getUMLRTSupersetOf(EStructuralFeature) + */ + public static EStructuralFeature getExtensionFeature(EStructuralFeature umlFeature) { + EStructuralFeature result = null; + + if (umlFeature == UMLPackage.Literals.ENCAPSULATED_CLASSIFIER__OWNED_PORT) { + result = ExtUMLExtPackage.Literals.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT; + } else if (umlFeature == UMLPackage.Literals.STRUCTURED_CLASSIFIER__OWNED_ATTRIBUTE) { + result = ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE; + } else if (umlFeature == UMLPackage.Literals.STRUCTURED_CLASSIFIER__OWNED_CONNECTOR) { + result = ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR; + } else if (umlFeature == UMLPackage.Literals.CLASS__OWNED_OPERATION) { + result = ExtUMLExtPackage.Literals.CLASS__IMPLICIT_OPERATION; + } else if (umlFeature == UMLPackage.Literals.INTERFACE__OWNED_OPERATION) { + result = ExtUMLExtPackage.Literals.INTERFACE__IMPLICIT_OPERATION; + } + + return result; + } + + /** + * For a given UML metamodel feature, obtains all of the features that logically + * implement it in the extended UML-RT semantics, including extension features, if any. + * + * @param umlFeature + * a feature in the UML metamodel + * + * @return the collection of features that the façade API presents as the logical + * extension of the UML feature, including at least the original {@code umlFeature} + * in the first position + * + * @see #getExtensionFeature(EStructuralFeature) + */ + public static List<? extends EStructuralFeature> getUMLRTSupersetOf(EStructuralFeature umlFeature) { + EStructuralFeature extension = getExtensionFeature(umlFeature); + + return (extension == null) ? Collections.singletonList(umlFeature) : new Pair<>(umlFeature, extension); + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/UMLRTResourcesUtil.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/UMLRTResourcesUtil.java new file mode 100644 index 000000000..22ffb31a6 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/UMLRTResourcesUtil.java @@ -0,0 +1,365 @@ +/***************************************************************************** + * Copyright (c) 2012, 2016 CEA, Obeo, Christian W. Damus, and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Kenn Hussey (CEA) - initial API and implementation + * Kenn Hussey (CEA) - 389542, 399544, 425846, 418466, 429352 + * Mikael Barbero (Obeo) - 414572 + * Christian W. Damus (CEA) - 414572, 401682 + * Christian W. Damus - bug 467545 adapt from UMLResourcesUtil class + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.util; + +import java.net.URL; +import java.util.Map; +import java.util.function.Predicate; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.URIConverter; +import org.eclipse.papyrusrt.umlrt.profile.Activator; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage; +import org.eclipse.papyrusrt.umlrt.profile.statemachine.UMLRTStateMachines.UMLRTStateMachinesPackage; +import org.eclipse.papyrusrt.umlrt.profile.util.UMLRTResource; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.UMLRTUMLFactoryImpl; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.UMLRTUMLRealTimeFactoryImpl; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.ReificationAdapter; +import org.eclipse.papyrusrt.umlrt.uml.internal.util.UMLRTUMLResourceFactoryImpl; +import org.eclipse.uml2.uml.UMLFactory; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.UMLPlugin; +import org.eclipse.uml2.uml.resource.UMLResource; +import org.eclipse.uml2.uml.resources.util.UMLResourcesUtil; +import org.eclipse.uml2.uml.util.UMLUtil.StereotypeApplicationHelper; + +/** + * Static utilities for the configuration of resource sets to work with UML-RT + * models in a stand-alone (Eclipse-free) context. + */ +public class UMLRTResourcesUtil { + + /** + * Not instantiable by clients. + */ + private UMLRTResourcesUtil() { + super(); + } + + public static ResourceSet init(ResourceSet resourceSet) { + // Basic UML set-up + UMLResourcesUtil.initLocalRegistries(resourceSet); + + // And overlay UML-RT specifics + initLocalRegistries(resourceSet); + + // And ensure that stereotype application creation goes through the + // resource-set-registered factory + initLocalStereotypeApplicationHelper(resourceSet); + + return resourceSet; + } + + /** + * Adds registrations to EMF's and UML2's global registries that enable + * working with UML-RT models. To apply the same registrations only locally on + * a resource set (e.g., for isolation from other EMF-based code in the same + * class loader), use the {@link #initLocalRegistries(ResourceSet)} method, + * instead. + * + * @see #initLocalRegistries(ResourceSet) + */ + public static void initGlobalRegistries() { + UMLResourcesUtil.initGlobalRegistries(); + + initPackageRegistry(EPackage.Registry.INSTANCE); + initEPackageNsURIToProfileLocationMap(UMLPlugin.getEPackageNsURIToProfileLocationMap()); + initURIConverterURIMap(URIConverter.URI_MAP); + initResourceFactoryRegistry(Resource.Factory.Registry.INSTANCE); + } + + public static void initLocalRegistries(ResourceSet resourceSet) { + initPackageRegistry(resourceSet.getPackageRegistry()); + + // there is no local registry for this + initEPackageNsURIToProfileLocationMap(UMLPlugin.getEPackageNsURIToProfileLocationMap()); + + initURIConverterURIMap(resourceSet.getURIConverter().getURIMap()); + + // there are no UML-RT-specific content handlers + + initResourceFactoryRegistry(resourceSet.getResourceFactoryRegistry()); + } + + public static void initLocalStereotypeApplicationHelper(ResourceSet resourceSet) { + StereotypeApplicationHelper wrapper = new UMLRTStereotypeApplicationHelper( + StereotypeApplicationHelper.getInstance(resourceSet)); + + StereotypeApplicationHelper.setInstance(resourceSet, wrapper); + } + + /** + * Adds packages required for working with UML-RT models to the specified + * registry. + * + * @param packageRegistry + * a package registry, perhaps local to a resource set or perhaps + * the global registry + * + * @return the same {@code packageRegistry}, augmented + */ + public static EPackage.Registry initPackageRegistry(EPackage.Registry packageRegistry) { + packageRegistry.put(UMLRealTimePackage.eNS_URI, UMLRealTimePackage.eINSTANCE); + packageRegistry.put(UMLRTStateMachinesPackage.eNS_URI, UMLRTStateMachinesPackage.eINSTANCE); + packageRegistry.put(ExtUMLExtPackage.eNS_URI, ExtUMLExtPackage.eINSTANCE); + + installUMLRTFactory(packageRegistry); + + return packageRegistry; + } + + /** + * Adds resource factories required for working with UML-RT models to the + * specified registry. + * + * @param resourceFactoryRegistry + * a resource-factory registry, perhaps local to a resource set + * or perhaps the global registry + * + * @return the same {@code resourceFactoryRegistry} + */ + public static Resource.Factory.Registry initResourceFactoryRegistry(Resource.Factory.Registry resourceFactoryRegistry) { + installUMLRTResourceFactory(resourceFactoryRegistry); + return resourceFactoryRegistry; + } + + /** + * Adds profile namespace URI mappings required for working with UML-RT models + * to the specified map. These include at least mappings for the + * UML-RT profiles. + * + * @param ePackageNsURIToProfileLocationMap + * a profile location map, perhaps local to a resource set or + * perhaps the global location map + * + * @return the same {@code ePackageNsURIToProfileLocationMap}, augmented + */ + public static Map<String, URI> initEPackageNsURIToProfileLocationMap(Map<String, URI> ePackageNsURIToProfileLocationMap) { + ePackageNsURIToProfileLocationMap.put(UMLRealTimePackage.eNS_URI, + URI.createURI("pathmap://UML_RT_PROFILE/uml-rt.profile.uml#_1h74oEeVEeO0lv5O1DTHOQ")); //$NON-NLS-1$ + + ePackageNsURIToProfileLocationMap.put(UMLRTStateMachinesPackage.eNS_URI, + URI.createURI("pathmap://UML_RT_PROFILE/UMLRealTimeSM-addendum.profile.uml#_KLcn0FDtEeOA4ecmvfqvaw")); //$NON-NLS-1$ + + ePackageNsURIToProfileLocationMap.put(ExtUMLExtPackage.eNS_URI, + URI.createURI("pathmap://UML_RT_UML/uml-ext.metamodel.uml#_0")); //$NON-NLS-1$ + + return ePackageNsURIToProfileLocationMap; + } + + /** + * Adds resource URI mappings required for working with UML-RT models to the + * specified map. These include at least mappings for the UML-RT + * model libraries, metamodels, and profiles. + * + * @param uriMap + * a URI map, perhaps local to a resource set or perhaps the + * global URI map + * + * @return the same {@code uriMap}, augmented + */ + public static Map<URI, URI> initURIConverterURIMap(Map<URI, URI> uriMap) { + URI baseURI = getBaseResourceURI(UMLRTResource.class, UMLRTResource.PROFILE_PATH, "umlProfile"); //$NON-NLS-1$ + + mapUMLRTResourceURIs(uriMap, "pathmap://UML_RT_PROFILE/", //$NON-NLS-1$ + baseURI.appendSegment("umlProfile")); //$NON-NLS-1$ + + baseURI = getBaseResourceURI(UMLRTResourcesUtil.class, "pathmap://UML_RT_UML/uml-ext.metamodel.uml", "model"); //$NON-NLS-1$//$NON-NLS-2$ + + mapUMLRTResourceURIs(uriMap, "pathmap://UML_RT_UML/", //$NON-NLS-1$ + baseURI.appendSegment("model")); //$NON-NLS-1$ + + return uriMap; + } + + private static URI getBaseResourceURI(Class<?> context, String prototypeURI, String folder) { + // The UML-Ext metamodel is in my bundle + URI uri = URI.createURI(prototypeURI); // $NON-NLS-1$ + URL resultURL = context.getClassLoader().getResource( + String.format("%s/%s", folder, uri.lastSegment())); //$NON-NLS-1$ + + URI result; + + if (resultURL != null) { + // remove the /<folder>/<model-name>.uml segments of the resource + // we found + result = URI.createURI(resultURL.toExternalForm(), true) + .trimSegments(2); + } else { + // probably, we're not running with JARs, so assume the source + // project folder layout + resultURL = context.getResource(context.getSimpleName() + ".class"); //$NON-NLS-1$ + + String baseURL = resultURL.toExternalForm(); + baseURL = baseURL.substring(0, baseURL.lastIndexOf("/bin/")); //$NON-NLS-1$ + result = URI.createURI(baseURL, true); + } + + return result; + } + + private static void mapUMLRTResourceURIs(Map<URI, URI> uriMap, String uri, URI location) { + URI prefix = URI.createURI(uri); + + // ensure trailing separator (make it a "URI prefix") + if (!prefix.hasTrailingPathSeparator()) { + prefix = prefix.appendSegment(""); //$NON-NLS-1$ + } + + // same with the location + if (!location.hasTrailingPathSeparator()) { + location = location.appendSegment(""); //$NON-NLS-1$ + } + + uriMap.put(prefix, location); + + // and platform URIs, too + String folder = location.segment(location.segmentCount() - 2); + String platformURI = String.format("%s/%s/", Activator.PLUGIN_ID, folder); + uriMap.put(URI.createPlatformPluginURI(platformURI, true), location); + uriMap.put(URI.createPlatformResourceURI(platformURI, true), location); + } + + /** + * Installs the {@link UMLFactory} and {@link UMLResource.Factory} for + * UML-RT semantics in the context of a resource set. + * + * @param resourceSet + * a resource set + * @return the same {@code resourceSet}, augmented + * + * @see #installUMLRTFactory(org.eclipse.emf.ecore.EPackage.Registry) + * @see #installUMLRTResourceFactory(org.eclipse.emf.ecore.resource.Resource.Factory.Registry) + */ + public static ResourceSet installUMLRTFactory(ResourceSet resourceSet) { + installUMLRTFactory(resourceSet.getPackageRegistry()); + installUMLRTResourceFactory(resourceSet.getResourceFactoryRegistry()); + return resourceSet; + } + + /** + * Installs the {@link UMLFactory} for UML-RT semantics into a package + * registry, which may be specific to a resource set or (please, only + * in a stand-alone application) the global registry. + * + * @param packageRegistry + * a package registry + */ + public static void installUMLRTFactory(EPackage.Registry packageRegistry) { + // Our shim for the UML package with its custom factory + UMLPackage umlPackage = UMLRTUMLFactoryImpl.eINSTANCE.getUMLPackage(); + installUMLFactory(packageRegistry, umlPackage); + + // And same for the UMLRealTime profile package + UMLRealTimePackage umlRealTimePackage = UMLRTUMLRealTimeFactoryImpl.eINSTANCE.getUMLRealTimePackage(); + packageRegistry.put(UMLRealTimePackage.eNS_URI, umlRealTimePackage); + } + + private static void installUMLFactory(EPackage.Registry packageRegistry, UMLPackage umlPackage) { + packageRegistry.put(UMLPackage.eNS_URI, umlPackage); + + // And any other namespace URIs under which it was registered + for (Map.Entry<String, Object> next : packageRegistry.entrySet()) { + if (next.getValue() instanceof UMLPackage) { + next.setValue(umlPackage); + } + } + } + + /** + * Installs the {@link UMLResource.Factory} for UML-RT semantics into a resource + * factory registry, which may be specific to a resource set or (please, only + * in a stand-alone application) the global registry. + * + * @param resourceFactoryRegistry + * a resource factory registry + */ + public static void installUMLRTResourceFactory(Resource.Factory.Registry resourceFactoryRegistry) { + installUMLResourceFactory(resourceFactoryRegistry, UMLRTUMLResourceFactoryImpl.INSTANCE); + } + + private static void installUMLResourceFactory(Resource.Factory.Registry resourceFactoryRegistry, UMLResource.Factory umlResourceFactory) { + Map<String, Object> extensionToFactoryMap = resourceFactoryRegistry.getExtensionToFactoryMap(); + extensionToFactoryMap.put(UMLResource.FILE_EXTENSION, umlResourceFactory); + + Map<String, Object> contentTypeToFactoryMap = resourceFactoryRegistry.getContentTypeToFactoryMap(); + contentTypeToFactoryMap.put(UMLResource.UML_CONTENT_TYPE_IDENTIFIER, umlResourceFactory); + } + + /** + * Restores the {@link UMLFactory} and {@link UMLResource.Factory} for + * standard UML semantics in the context of a resource set. + * + * @param resourceSet + * a resource set + * @return the same {@code resourceSet}, augmented + * + * @see #uninstallUMLRTFactory(org.eclipse.emf.ecore.EPackage.Registry) + * @see #uninstallUMLRTResourceFactory(org.eclipse.emf.ecore.resource.Resource.Factory.Registry) + */ + public static ResourceSet uninstallUMLRTFactory(ResourceSet resourceSet) { + uninstallUMLRTFactory(resourceSet.getPackageRegistry()); + uninstallUMLRTResourceFactory(resourceSet.getResourceFactoryRegistry()); + return resourceSet; + } + + /** + * Restores the {@link UMLFactory} for standard UML semantics in a package + * registry, which may be specific to a resource set or may be the + * global registry. + * + * @param packageRegistry + * a package registry + */ + public static void uninstallUMLRTFactory(EPackage.Registry packageRegistry) { + packageRegistry.put(UMLRealTimePackage.eNS_URI, UMLRealTimePackage.eINSTANCE); + installUMLFactory(packageRegistry, UMLPackage.eINSTANCE); + } + + /** + * Restores the {@link UMLResource.Factory} for standard UML semantics into + * a resource factory registry, which may be specific to a resource set or + * may be the global registry. + * + * @param resourceFactoryRegistry + * a resource factory registry + */ + public static void uninstallUMLRTResourceFactory(Resource.Factory.Registry resourceFactoryRegistry) { + installUMLResourceFactory(resourceFactoryRegistry, UMLResource.Factory.INSTANCE); + } + + /** + * Some adapters in the UML-RT Façade API react to changes in the model to maintain + * a correct (for UML-RT) semantic structure in the UML model, but those adaptations + * are best avoided when changes result from undo/redo of recorded commands. This + * API provides the façade API with the means to recognize changes that are triggered + * by undo or redo (such as in a transactional editing domain). + * + * @param resourceSet + * a resource set to configure for UML-RT editing + * @param undoRedoRecognizer + * a predicate that matches notifications triggered by undo/redo + */ + public static void setUndoRedoRecognizer(ResourceSet resourceSet, Predicate<? super Notification> undoRedoRecognizer) { + ReificationAdapter.getInstance(resourceSet).setUndoRedoRecognizer(undoRedoRecognizer); + } +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/UMLRTStereotypeApplicationHelper.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/UMLRTStereotypeApplicationHelper.java new file mode 100644 index 000000000..4c71c4221 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/UMLRTStereotypeApplicationHelper.java @@ -0,0 +1,108 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.util; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EFactory; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage; +import org.eclipse.uml2.common.util.CacheAdapter; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.util.UMLUtil; +import org.eclipse.uml2.uml.util.UMLUtil.StereotypeApplicationHelper; + +/** + * A wrapper for a {@link ResourceSet}'s stereotype-application helper + * that ensures creation of the {@link UMLRealTimePackage} factory implementation + * for the <em>UMLRealTime</em> profile that supports incremental redefinition + * according to UML-RT semantics. + */ +public class UMLRTStereotypeApplicationHelper extends StereotypeApplicationHelper { + + private final StereotypeApplicationHelper delegate; + + /** + * Initializes me with the helper that I wrap. + * + * @param delegate + * the wrapped helper + */ + public UMLRTStereotypeApplicationHelper(StereotypeApplicationHelper delegate) { + super(); + + this.delegate = delegate; + } + + @Override + public boolean addToContainmentList(Element element, EObject stereotypeApplication) { + return delegate.addToContainmentList(element, stereotypeApplication); + } + + @Override + public boolean removeFromContainmentList(Element element, EObject stereotypeApplication) { + return delegate.removeFromContainmentList(element, stereotypeApplication); + } + + @Override + public EObject applyStereotype(Element element, EClass definition) { + EObject result; + + if (definition.getEPackage() != UMLRealTimePackage.eINSTANCE) { + result = delegate.applyStereotype(element, definition); + } else { + // Use the factory registered locally in the resource set, if possible + EFactory factory = getEFactory(element, definition); + result = factory.create(definition); + + CacheAdapter.getInstance().adapt(result); + + addToContainmentList(element, result); + UMLUtil.setBaseElement(result, element); + } + + return result; + } + + /** + * Obtains the best factory for instantiation of the given stereotype {@code definition}. + * For all but class from the {@link UMLRealTimePackage}, this will be the pakage's + * static factory. For <em>UMLRealTime</em> stereotypes, it is the factory registered + * in the resource set's package registry. + * + * @param element + * an element in the context of some resource set + * @param definition + * the stereotype definition to instantiate + * + * @return the best factory for the job + */ + protected EFactory getEFactory(Element element, EClass definition) { + EFactory result; + + // Get the registered factory, if possible + EPackage ePackage = definition.getEPackage(); + Resource resource = element.eResource(); + ResourceSet rset = (resource == null) ? null : resource.getResourceSet(); + result = (rset == null) ? null : rset.getPackageRegistry().getEFactory(ePackage.getNsURI()); + if (result == null) { + result = ePackage.getEFactoryInstance(); + } + + return result; + } + +} diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/UMLRTSwitch.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/UMLRTSwitch.java new file mode 100644 index 000000000..ba641c987 --- /dev/null +++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/util/UMLRTSwitch.java @@ -0,0 +1,150 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.util; + +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsulePart; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTClassifier; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTConnector; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTModel; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTNamedElement; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPort; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocol; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocolMessage; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTReplicatedElement; + +/** + * An EMF-style switch pattern on the types of UML-RT Façade objects. + */ +public class UMLRTSwitch<T> { + + /** + * Initializes me. + */ + public UMLRTSwitch() { + super(); + } + + /** + * Performs a switch on the type of the {@code object}, with preference + * to more specific types in the hierarchy. + * + * @param object + * an object to switch on + * + * @return the result of the most specific case that provides one, or else {@code null} + */ + public T doSwitch(Object object) { + T result = null; + + if ((result == null) && (object instanceof UMLRTPort)) { + result = casePort((UMLRTPort) object); + } + + if ((result == null) && (object instanceof UMLRTCapsulePart)) { + result = caseCapsulePart((UMLRTCapsulePart) object); + } + + if ((result == null) && (object instanceof UMLRTReplicatedElement)) { + result = caseReplicatedElement((UMLRTReplicatedElement) object); + } + + if ((result == null) && (object instanceof UMLRTConnector)) { + result = caseConnector((UMLRTConnector) object); + } + + if ((result == null) && (object instanceof UMLRTCapsule)) { + result = caseCapsule((UMLRTCapsule) object); + } + + if ((result == null) && (object instanceof UMLRTProtocol)) { + result = caseProtocol((UMLRTProtocol) object); + } + + if ((result == null) && (object instanceof UMLRTClassifier)) { + result = caseClassifier((UMLRTClassifier) object); + } + + if ((result == null) && (object instanceof UMLRTProtocolMessage)) { + result = caseProtocolMessage((UMLRTProtocolMessage) object); + } + + if ((result == null) && (object instanceof UMLRTPackage)) { + result = casePackage((UMLRTPackage) object); + } + + if ((result == null) && (object instanceof UMLRTNamedElement)) { + result = caseNamedElement((UMLRTNamedElement) object); + } + + if ((result == null) && (object instanceof UMLRTModel)) { + result = caseModel((UMLRTModel) object); + } + + if (result == null) { + result = defaultCase(object); + } + + return result; + } + + public T defaultCase(Object object) { + return null; + } + + public T caseNamedElement(UMLRTNamedElement object) { + return null; + } + + public T caseReplicatedElement(UMLRTReplicatedElement object) { + return null; + } + + public T caseClassifier(UMLRTClassifier object) { + return null; + } + + public T caseCapsule(UMLRTCapsule object) { + return null; + } + + public T caseCapsulePart(UMLRTCapsulePart object) { + return null; + } + + public T caseConnector(UMLRTConnector object) { + return null; + } + + public T casePort(UMLRTPort object) { + return null; + } + + public T caseProtocol(UMLRTProtocol object) { + return null; + } + + public T caseProtocolMessage(UMLRTProtocolMessage object) { + return null; + } + + public T casePackage(UMLRTPackage object) { + return null; + } + + public T caseModel(UMLRTModel object) { + return null; + } +} diff --git a/plugins/umlrt/profile/pom.xml b/plugins/umlrt/profile/pom.xml index 6a6a28c55..4cf9150b3 100644 --- a/plugins/umlrt/profile/pom.xml +++ b/plugins/umlrt/profile/pom.xml @@ -13,10 +13,7 @@ <packaging>pom</packaging> <modules> <module>org.eclipse.papyrusrt.umlrt.profile</module> - - - - + <module>org.eclipse.papyrusrt.umlrt.uml</module> </modules> </project> diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/.checkstyle b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/.checkstyle new file mode 100644 index 000000000..f479982cb --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/.checkstyle @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false"> + <fileset name="all" enabled="true" check-config-name="Papyrus-RT" local="false"> + <file-match-pattern match-pattern="." include-pattern="true"/> + </fileset> +</fileset-config> diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/.classpath b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/.classpath new file mode 100644 index 000000000..20647de5f --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/.classpath @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"> + <accessrules> + <accessrule kind="accessible" pattern="org/eclipse/papyrusrt/umlrt/uml/internal/**"/> + </accessrules> + </classpathentry> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/.project b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/.project new file mode 100644 index 000000000..95ddaf34e --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/.project @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.papyrusrt.umlrt.uml.tests</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>net.sf.eclipsecs.core.CheckstyleBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.m2e.core.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.m2e.core.maven2Nature</nature> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>net.sf.eclipsecs.core.CheckstyleNature</nature> + </natures> +</projectDescription> diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/.settings/org.eclipse.core.resources.prefs b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 000000000..99f26c020 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/<project>=UTF-8 diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/.settings/org.eclipse.jdt.core.prefs b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..9b6d675fd --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,297 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +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.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +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_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +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_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +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_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=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_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_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +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_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_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=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.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=260 +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_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=false +org.eclipse.jdt.core.formatter.indentation.size=4 +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=do not 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_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=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_binary_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_superinterfaces=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_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_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_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_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=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_binary_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_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_superinterfaces=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_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_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_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_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_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=false +org.eclipse.jdt.core.formatter.join_wrapped_lines=false +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_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=260 +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_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=5 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=tab +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=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/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/.settings/org.eclipse.jdt.ui.prefs b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..b22a3a0ce --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,127 @@ +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.always_use_blocks=true +cleanup.always_use_parentheses_in_expressions=false +cleanup.always_use_this_for_non_static_field_access=false +cleanup.always_use_this_for_non_static_method_access=false +cleanup.convert_functional_interfaces=false +cleanup.convert_to_enhanced_for_loop=false +cleanup.correct_indentation=false +cleanup.format_source_code=false +cleanup.format_source_code_changes_only=false +cleanup.insert_inferred_type_arguments=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.never_use_blocks=false +cleanup.never_use_parentheses_in_expressions=true +cleanup.organize_imports=false +cleanup.qualify_static_field_accesses_with_declaring_class=false +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=true +cleanup.qualify_static_method_accesses_with_declaring_class=false +cleanup.remove_private_constructors=true +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_casts=true +cleanup.remove_unnecessary_nls_tags=true +cleanup.remove_unused_imports=true +cleanup.remove_unused_local_variables=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.sort_members=false +cleanup.sort_members_all=false +cleanup.use_anonymous_class_creation=false +cleanup.use_blocks=true +cleanup.use_blocks_only_for_return_and_throw=false +cleanup.use_lambda=true +cleanup.use_parentheses_in_expressions=false +cleanup.use_this_for_non_static_field_access=false +cleanup.use_this_for_non_static_field_access_only_if_necessary=true +cleanup.use_this_for_non_static_method_access=false +cleanup.use_this_for_non_static_method_access_only_if_necessary=true +cleanup.use_type_arguments=false +cleanup_profile=_Papyrus +cleanup_settings_version=2 +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=_Papyrus +formatter_settings_version=12 +org.eclipse.jdt.ui.ignorelowercasenames=true +org.eclipse.jdt.ui.importorder=java;javax;org;com; +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=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="false" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * Constructor.\n *\n * ${tags}\n */</template><template autoinsert\="false" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/*****************************************************************************\n * Copyright (c) ${year} CEA LIST and others.\n * \n * All rights reserved. This program and the accompanying materials\n * are made available under the terms of the Eclipse Public License v1.0\n * which accompanies this distribution, and is available at\n * http\://www.eclipse.org/legal/epl-v10.html\n *\n * Contributors\:\n * CEA LIST - Initial API and implementation\n * \n *****************************************************************************/\n</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/**\n * ${see_to_overridden}\n *\n * ${tags}\n */</template><template autoinsert\="false" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${see_to_target}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates> +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_missing_override_annotations_interface_methods=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_functional_interfaces=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=true +sp_cleanup.format_source_code_changes_only=false +sp_cleanup.insert_inferred_type_arguments=false +sp_cleanup.make_local_variable_final=true +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_type_abstract_if_missing_method=false +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=true +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_redundant_type_arguments=true +sp_cleanup.remove_trailing_whitespaces=false +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=false +sp_cleanup.remove_unused_imports=false +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_anonymous_class_creation=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_lambda=true +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +sp_cleanup.use_type_arguments=false diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/META-INF/MANIFEST.MF b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/META-INF/MANIFEST.MF new file mode 100644 index 000000000..90551e71e --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/META-INF/MANIFEST.MF @@ -0,0 +1,14 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: PapyrusRT UML Implementation for UML-RT Tests +Bundle-SymbolicName: org.eclipse.papyrusrt.umlrt.uml.tests +Bundle-Version: 0.8.0.qualifier +Bundle-Vendor: Eclipse Modeling Project +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Require-Bundle: org.eclipse.emf.ecore;bundle-version="2.11.0", + org.junit;bundle-version="4.12.0", + org.eclipse.uml2.uml;bundle-version="5.1.0", + org.eclipse.papyrusrt.umlrt.uml;bundle-version="0.8.0", + org.eclipse.emf.ecore.change;bundle-version="2.11.0", + org.eclipse.emf.edit;bundle-version="2.12.0", + org.eclipse.uml2.uml.edit;bundle-version="5.2.1" diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/about.html b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/about.html new file mode 100644 index 000000000..dd3c089a9 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/about.html @@ -0,0 +1,28 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/> +<title>About</title> +</head> +<body lang="EN-US"> +<h2>About This Content</h2> + +<p>November 14, 2008</p> +<h3>License</h3> + +<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>. +For purposes of the EPL, "Program" will mean the Content.</p> + +<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p> + +</body> +</html>
\ No newline at end of file diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/build.properties b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/build.properties new file mode 100644 index 000000000..46d4ee3ed --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/build.properties @@ -0,0 +1,19 @@ +# +# Copyright (c) 2016 Christian W. Damus and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Christian W. Damus - initial API and implementation +# + +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + about.html,\ + resources/ +src.includes = about.html diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/org.eclipse.papyrusrt.umlrt.uml.tests.launch b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/org.eclipse.papyrusrt.umlrt.uml.tests.launch new file mode 100644 index 000000000..ba4ea4a9d --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/org.eclipse.papyrusrt.umlrt.uml.tests.launch @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<launchConfiguration type="org.eclipse.jdt.junit.launchconfig"> +<listAttribute key="com.mountainminds.eclemma.core.SCOPE_IDS"> +<listEntry value="=org.eclipse.papyrusrt.umlrt.uml/src"/> +<listEntry value="=org.eclipse.papyrusrt.umlrt.uml/src-gen"/> +</listAttribute> +<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> +<listEntry value="/org.eclipse.papyrusrt.umlrt.uml.tests"/> +</listAttribute> +<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> +<listEntry value="4"/> +</listAttribute> +<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value="=org.eclipse.papyrusrt.umlrt.uml.tests"/> +<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/> +<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/> +<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/> +<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/> +<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/> +<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.papyrusrt.umlrt.uml.tests"/> +<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea"/> +</launchConfiguration> diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/pom.xml b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/pom.xml new file mode 100644 index 000000000..d466c2efb --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/pom.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.eclipse.papyrusrt</groupId> + <artifactId>org.eclipse.papyrusrt.profile.tests</artifactId> + <version>0.8.0-SNAPSHOT</version> + </parent> + + <artifactId>org.eclipse.papyrusrt.umlrt.uml.tests</artifactId> + <packaging>eclipse-test-plugin</packaging> + + <build> + <plugins> + <plugin> + <groupId>org.eclipse.tycho</groupId> + <artifactId>tycho-surefire-plugin</artifactId> + <version>0.25.0</version> + <configuration> + <useUIHarness>false</useUIHarness> + <useUIThread>false</useUIThread> + <testFailureIgnore>true</testFailureIgnore> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/connectors.di b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/connectors.di new file mode 100644 index 000000000..bf9abab34 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/connectors.di @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/> diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/connectors.notation b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/connectors.notation new file mode 100644 index 000000000..708c3577a --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/connectors.notation @@ -0,0 +1,315 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:configuration="http://www.eclipse.org/papyrus/infra/viewpoints/configuration" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/viewpoints/policy/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML"> + <notation:Diagram xmi:id="_cZ1jkKaqEeaVuqljGw-fqQ" type="CompositeStructure" measurementUnit="Pixel"> + <children xmi:type="notation:Shape" xmi:id="_caQaUKaqEeaVuqljGw-fqQ" type="Class_Shape"> + <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_VG04ELp2EeaV0fVWRP8bJg" source="PapyrusCSSForceValue"> + <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_VG04Ebp2EeaV0fVWRP8bJg" key="mutable" value="true"/> + </eAnnotations> + <children xmi:type="notation:DecorationNode" xmi:id="_caTdoKaqEeaVuqljGw-fqQ" type="Class_NameLabel"/> + <children xmi:type="notation:DecorationNode" xmi:id="_caTdoaaqEeaVuqljGw-fqQ" type="Class_FloatingNameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_caTdoqaqEeaVuqljGw-fqQ" y="5"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_caUEsKaqEeaVuqljGw-fqQ" type="Class_StructureCompartment"> + <children xmi:type="notation:Shape" xmi:id="_cjYwQLp2EeaV0fVWRP8bJg" type="Property_Shape"> + <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_d7dWcLp2EeaV0fVWRP8bJg" source="PapyrusCSSForceValue"> + <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_d7dWcbp2EeaV0fVWRP8bJg" key="mutable" value="true"/> + </eAnnotations> + <children xmi:type="notation:DecorationNode" xmi:id="_cjZXULp2EeaV0fVWRP8bJg" type="Property_NameLabel"/> + <children xmi:type="notation:DecorationNode" xmi:id="_cjZXUbp2EeaV0fVWRP8bJg" type="Property_FloatingNameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_cjZXUrp2EeaV0fVWRP8bJg" y="5"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_cjZXU7p2EeaV0fVWRP8bJg" type="Property_StructureCompartment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_cjZXVLp2EeaV0fVWRP8bJg"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_cjZXVbp2EeaV0fVWRP8bJg"/> + </children> + <children xmi:type="notation:DecorationNode" xmi:id="_cjh6MLp2EeaV0fVWRP8bJg" type="StereotypeLabel"> + <styles xmi:type="notation:StringValueStyle" xmi:id="_cjh6Mbp2EeaV0fVWRP8bJg" name="stereotype" stringValue="UMLRealTime::CapsulePart"/> + <element xmi:type="uml:Stereotype" href="pathmap://UML_RT_PROFILE/uml-rt.profile.uml#_EQwT4EhOEeO0lv5O1DTHOQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_cjh6Mrp2EeaV0fVWRP8bJg"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_cjihQLp2EeaV0fVWRP8bJg" type="StereotypeBrace"> + <styles xmi:type="notation:TitleStyle" xmi:id="_cjihQbp2EeaV0fVWRP8bJg"/> + <styles xmi:type="notation:StringValueStyle" xmi:id="_cjihQrp2EeaV0fVWRP8bJg" name="stereotype" stringValue="UMLRealTime::CapsulePart"/> + <element xmi:type="uml:Stereotype" href="pathmap://UML_RT_PROFILE/uml-rt.profile.uml#_EQwT4EhOEeO0lv5O1DTHOQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_cjihQ7p2EeaV0fVWRP8bJg"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_cjihRLp2EeaV0fVWRP8bJg" type="compartment_shape_display"> + <styles xmi:type="notation:TitleStyle" xmi:id="_cjihRbp2EeaV0fVWRP8bJg"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_cjihRrp2EeaV0fVWRP8bJg"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_cjjvYLp2EeaV0fVWRP8bJg" type="StereotypeCompartment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_cjjvYbp2EeaV0fVWRP8bJg"/> + <styles xmi:type="notation:StringValueStyle" xmi:id="_cjjvYrp2EeaV0fVWRP8bJg" name="stereotype" stringValue="UMLRealTime::CapsulePart"/> + <element xmi:type="uml:Stereotype" href="pathmap://UML_RT_PROFILE/uml-rt.profile.uml#_EQwT4EhOEeO0lv5O1DTHOQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_cjjvY7p2EeaV0fVWRP8bJg"/> + </children> + <children xmi:type="notation:Shape" xmi:id="_d5mVQLp2EeaV0fVWRP8bJg" type="Port_Shape"> + <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_d7d9gLp2EeaV0fVWRP8bJg" source="PapyrusCSSForceValue"> + <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_d7d9gbp2EeaV0fVWRP8bJg" key="mutable" value="true"/> + </eAnnotations> + <children xmi:type="notation:DecorationNode" xmi:id="_d5mVQrp2EeaV0fVWRP8bJg" type="Port_NameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_d5mVQ7p2EeaV0fVWRP8bJg" x="25" y="3"/> + </children> + <children xmi:type="notation:DecorationNode" xmi:id="_d5mVRLp2EeaV0fVWRP8bJg" type="Port_StereotypeLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_d5mVRbp2EeaV0fVWRP8bJg" x="25" y="-10"/> + </children> + <element xmi:type="uml:Port" href="connectors.uml#_dVF6ALp2EeaV0fVWRP8bJg"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_d5mVQbp2EeaV0fVWRP8bJg" x="-5" y="16" width="11" height="11"/> + </children> + <element xmi:type="uml:Property" href="connectors.uml#_cisMsLp2EeaV0fVWRP8bJg"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_cjYwQbp2EeaV0fVWRP8bJg" x="125" y="46"/> + </children> + <children xmi:type="notation:Shape" xmi:id="_cjjIULp2EeaV0fVWRP8bJg" type="StereotypeComment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_cjjIUbp2EeaV0fVWRP8bJg"/> + <styles xmi:type="notation:EObjectValueStyle" xmi:id="_cjjIU7p2EeaV0fVWRP8bJg" name="BASE_ELEMENT"> + <eObjectValue xmi:type="uml:Property" href="connectors.uml#_cisMsLp2EeaV0fVWRP8bJg"/> + </styles> + <element xsi:nil="true"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_cjjIUrp2EeaV0fVWRP8bJg" x="325" y="46"/> + </children> + <children xmi:type="notation:Shape" xmi:id="_d5p_oLp2EeaV0fVWRP8bJg" type="StereotypeComment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_d5p_obp2EeaV0fVWRP8bJg"/> + <styles xmi:type="notation:EObjectValueStyle" xmi:id="_d5p_o7p2EeaV0fVWRP8bJg" name="BASE_ELEMENT"> + <eObjectValue xmi:type="uml:Port" href="connectors.uml#_dVF6ALp2EeaV0fVWRP8bJg"/> + </styles> + <element xsi:nil="true"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_d5p_orp2EeaV0fVWRP8bJg" x="194" y="-6"/> + </children> + <styles xmi:type="notation:TitleStyle" xmi:id="_caUEsaaqEeaVuqljGw-fqQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_caUEsqaqEeaVuqljGw-fqQ"/> + </children> + <children xmi:type="notation:DecorationNode" xmi:id="_VB7xALp2EeaV0fVWRP8bJg" type="StereotypeLabel"> + <styles xmi:type="notation:StringValueStyle" xmi:id="_VB7xAbp2EeaV0fVWRP8bJg" name="stereotype" stringValue="UMLRealTime::Capsule"/> + <element xmi:type="uml:Stereotype" href="pathmap://UML_RT_PROFILE/uml-rt.profile.uml#_hcMIwEhNEeO0lv5O1DTHOQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_VB7xArp2EeaV0fVWRP8bJg"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_VB8YELp2EeaV0fVWRP8bJg" type="StereotypeBrace"> + <styles xmi:type="notation:TitleStyle" xmi:id="_VB8YEbp2EeaV0fVWRP8bJg"/> + <styles xmi:type="notation:StringValueStyle" xmi:id="_VB8YErp2EeaV0fVWRP8bJg" name="stereotype" stringValue="UMLRealTime::Capsule"/> + <element xmi:type="uml:Stereotype" href="pathmap://UML_RT_PROFILE/uml-rt.profile.uml#_hcMIwEhNEeO0lv5O1DTHOQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_VB8YE7p2EeaV0fVWRP8bJg"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_VB8_ILp2EeaV0fVWRP8bJg" type="compartment_shape_display"> + <styles xmi:type="notation:TitleStyle" xmi:id="_VB8_Ibp2EeaV0fVWRP8bJg"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_VB8_Irp2EeaV0fVWRP8bJg"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_VB9mOrp2EeaV0fVWRP8bJg" type="StereotypeCompartment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_VB9mO7p2EeaV0fVWRP8bJg"/> + <styles xmi:type="notation:StringValueStyle" xmi:id="_VB-NQLp2EeaV0fVWRP8bJg" name="stereotype" stringValue="UMLRealTime::Capsule"/> + <element xmi:type="uml:Stereotype" href="pathmap://UML_RT_PROFILE/uml-rt.profile.uml#_hcMIwEhNEeO0lv5O1DTHOQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_VB-NQbp2EeaV0fVWRP8bJg"/> + </children> + <children xmi:type="notation:Shape" xmi:id="_VB-0ULp2EeaV0fVWRP8bJg" type="Port_Shape"> + <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_VG04Erp2EeaV0fVWRP8bJg" source="PapyrusCSSForceValue"> + <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_VG04E7p2EeaV0fVWRP8bJg" key="mutable" value="true"/> + </eAnnotations> + <children xmi:type="notation:DecorationNode" xmi:id="_VB-0Urp2EeaV0fVWRP8bJg" type="Port_NameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_VB-0U7p2EeaV0fVWRP8bJg" x="25" y="3"/> + </children> + <children xmi:type="notation:DecorationNode" xmi:id="_VB-0VLp2EeaV0fVWRP8bJg" type="Port_StereotypeLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_VB-0Vbp2EeaV0fVWRP8bJg" x="25" y="-10"/> + </children> + <element xmi:type="uml:Port" href="connectors.uml#_uFmasKaqEeaVuqljGw-fqQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_VB-0Ubp2EeaV0fVWRP8bJg" x="-8" y="117" width="16" height="16"/> + </children> + <children xmi:type="notation:Shape" xmi:id="_VB_bYLp2EeaV0fVWRP8bJg" type="Port_Shape"> + <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_VG04FLp2EeaV0fVWRP8bJg" source="PapyrusCSSForceValue"> + <details xmi:type="ecore:EStringToStringMapEntry" xmi:id="_VG04Fbp2EeaV0fVWRP8bJg" key="mutable" value="true"/> + </eAnnotations> + <children xmi:type="notation:DecorationNode" xmi:id="_VB_bYrp2EeaV0fVWRP8bJg" type="Port_NameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_VB_bY7p2EeaV0fVWRP8bJg" x="25" y="3"/> + </children> + <children xmi:type="notation:DecorationNode" xmi:id="_VB_bZLp2EeaV0fVWRP8bJg" type="Port_StereotypeLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_VB_bZbp2EeaV0fVWRP8bJg" x="25" y="-10"/> + </children> + <element xmi:type="uml:Port" href="connectors.uml#_0JPYIKaqEeaVuqljGw-fqQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_VB_bYbp2EeaV0fVWRP8bJg" x="-8" y="140" width="16" height="16"/> + </children> + <element xmi:type="uml:Class" href="connectors.uml#_cUZp8KaqEeaVuqljGw-fqQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_caQaUaaqEeaVuqljGw-fqQ" x="40" y="40" width="500" height="250"/> + </children> + <children xmi:type="notation:Shape" xmi:id="_VB8_I7p2EeaV0fVWRP8bJg" type="StereotypeComment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_VB8_JLp2EeaV0fVWRP8bJg"/> + <styles xmi:type="notation:EObjectValueStyle" xmi:id="_VB8_Jrp2EeaV0fVWRP8bJg" name="BASE_ELEMENT"> + <eObjectValue xmi:type="uml:Class" href="connectors.uml#_cUZp8KaqEeaVuqljGw-fqQ"/> + </styles> + <element xsi:nil="true"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_VB8_Jbp2EeaV0fVWRP8bJg" x="240" y="40"/> + </children> + <children xmi:type="notation:Shape" xmi:id="_VCCesrp2EeaV0fVWRP8bJg" type="StereotypeComment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_VCCes7p2EeaV0fVWRP8bJg"/> + <styles xmi:type="notation:EObjectValueStyle" xmi:id="_VCCetbp2EeaV0fVWRP8bJg" name="BASE_ELEMENT"> + <eObjectValue xmi:type="uml:Port" href="connectors.uml#_uFmasKaqEeaVuqljGw-fqQ"/> + </styles> + <element xsi:nil="true"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_VCCetLp2EeaV0fVWRP8bJg" x="192" y="-8"/> + </children> + <children xmi:type="notation:Shape" xmi:id="_VCGJIbp2EeaV0fVWRP8bJg" type="StereotypeComment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_VCGJIrp2EeaV0fVWRP8bJg"/> + <styles xmi:type="notation:EObjectValueStyle" xmi:id="_VCGJJLp2EeaV0fVWRP8bJg" name="BASE_ELEMENT"> + <eObjectValue xmi:type="uml:Port" href="connectors.uml#_0JPYIKaqEeaVuqljGw-fqQ"/> + </styles> + <element xsi:nil="true"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_VCGJI7p2EeaV0fVWRP8bJg" x="192" y="-8"/> + </children> + <children xmi:type="notation:Shape" xmi:id="_euCC4Lp2EeaV0fVWRP8bJg" type="StereotypeComment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_euCC4bp2EeaV0fVWRP8bJg"/> + <styles xmi:type="notation:EObjectValueStyle" xmi:id="_euCC47p2EeaV0fVWRP8bJg" name="BASE_ELEMENT"> + <eObjectValue xmi:type="uml:Connector" href="connectors.uml#_etrdkLp2EeaV0fVWRP8bJg"/> + </styles> + <element xsi:nil="true"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_euCC4rp2EeaV0fVWRP8bJg" x="192" y="17"/> + </children> + <styles xmi:type="notation:StringValueStyle" xmi:id="_cZ1jkaaqEeaVuqljGw-fqQ" name="diagram_compatibility_version" stringValue="1.2.0"/> + <styles xmi:type="notation:DiagramStyle" xmi:id="_cZ1jkqaqEeaVuqljGw-fqQ"/> + <styles xmi:type="style:PapyrusViewStyle" xmi:id="_cZ1jk6aqEeaVuqljGw-fqQ"> + <owner xmi:type="uml:Class" href="connectors.uml#_cUZp8KaqEeaVuqljGw-fqQ"/> + <configuration xmi:type="configuration:PapyrusDiagram" href="platform:/plugin/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/configuration/UMLRT.configuration#_Z79eQHcZEeSnWeKqQOfW2A"/> + </styles> + <element xmi:type="uml:Class" href="connectors.uml#_cUZp8KaqEeaVuqljGw-fqQ"/> + <edges xmi:type="notation:Connector" xmi:id="_VB9mMLp2EeaV0fVWRP8bJg" type="StereotypeCommentLink" source="_caQaUKaqEeaVuqljGw-fqQ" target="_VB8_I7p2EeaV0fVWRP8bJg"> + <styles xmi:type="notation:FontStyle" xmi:id="_VB9mMbp2EeaV0fVWRP8bJg"/> + <styles xmi:type="notation:EObjectValueStyle" xmi:id="_VB9mNbp2EeaV0fVWRP8bJg" name="BASE_ELEMENT"> + <eObjectValue xmi:type="uml:Class" href="connectors.uml#_cUZp8KaqEeaVuqljGw-fqQ"/> + </styles> + <element xsi:nil="true"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_VB9mMrp2EeaV0fVWRP8bJg" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_VB9mM7p2EeaV0fVWRP8bJg"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_VB9mNLp2EeaV0fVWRP8bJg"/> + </edges> + <edges xmi:type="notation:Connector" xmi:id="_VCCetrp2EeaV0fVWRP8bJg" type="StereotypeCommentLink" source="_VB-0ULp2EeaV0fVWRP8bJg" target="_VCCesrp2EeaV0fVWRP8bJg"> + <styles xmi:type="notation:FontStyle" xmi:id="_VCCet7p2EeaV0fVWRP8bJg"/> + <styles xmi:type="notation:EObjectValueStyle" xmi:id="_VCCeu7p2EeaV0fVWRP8bJg" name="BASE_ELEMENT"> + <eObjectValue xmi:type="uml:Port" href="connectors.uml#_uFmasKaqEeaVuqljGw-fqQ"/> + </styles> + <element xsi:nil="true"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_VCCeuLp2EeaV0fVWRP8bJg" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_VCCeubp2EeaV0fVWRP8bJg"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_VCCeurp2EeaV0fVWRP8bJg"/> + </edges> + <edges xmi:type="notation:Connector" xmi:id="_VCGwILp2EeaV0fVWRP8bJg" type="StereotypeCommentLink" source="_VB_bYLp2EeaV0fVWRP8bJg" target="_VCGJIbp2EeaV0fVWRP8bJg"> + <styles xmi:type="notation:FontStyle" xmi:id="_VCGwIbp2EeaV0fVWRP8bJg"/> + <styles xmi:type="notation:EObjectValueStyle" xmi:id="_VCGwJbp2EeaV0fVWRP8bJg" name="BASE_ELEMENT"> + <eObjectValue xmi:type="uml:Port" href="connectors.uml#_0JPYIKaqEeaVuqljGw-fqQ"/> + </styles> + <element xsi:nil="true"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_VCGwIrp2EeaV0fVWRP8bJg" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_VCGwI7p2EeaV0fVWRP8bJg"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_VCGwJLp2EeaV0fVWRP8bJg"/> + </edges> + <edges xmi:type="notation:Connector" xmi:id="_cjjIVLp2EeaV0fVWRP8bJg" type="StereotypeCommentLink" source="_cjYwQLp2EeaV0fVWRP8bJg" target="_cjjIULp2EeaV0fVWRP8bJg"> + <styles xmi:type="notation:FontStyle" xmi:id="_cjjIVbp2EeaV0fVWRP8bJg"/> + <styles xmi:type="notation:EObjectValueStyle" xmi:id="_cjjIWbp2EeaV0fVWRP8bJg" name="BASE_ELEMENT"> + <eObjectValue xmi:type="uml:Property" href="connectors.uml#_cisMsLp2EeaV0fVWRP8bJg"/> + </styles> + <element xsi:nil="true"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_cjjIVrp2EeaV0fVWRP8bJg" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_cjjIV7p2EeaV0fVWRP8bJg"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_cjjIWLp2EeaV0fVWRP8bJg"/> + </edges> + <edges xmi:type="notation:Connector" xmi:id="_d5p_pLp2EeaV0fVWRP8bJg" type="StereotypeCommentLink" source="_d5mVQLp2EeaV0fVWRP8bJg" target="_d5p_oLp2EeaV0fVWRP8bJg"> + <styles xmi:type="notation:FontStyle" xmi:id="_d5p_pbp2EeaV0fVWRP8bJg"/> + <styles xmi:type="notation:EObjectValueStyle" xmi:id="_d5p_qbp2EeaV0fVWRP8bJg" name="BASE_ELEMENT"> + <eObjectValue xmi:type="uml:Port" href="connectors.uml#_dVF6ALp2EeaV0fVWRP8bJg"/> + </styles> + <element xsi:nil="true"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_d5p_prp2EeaV0fVWRP8bJg" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_d5p_p7p2EeaV0fVWRP8bJg"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_d5p_qLp2EeaV0fVWRP8bJg"/> + </edges> + <edges xmi:type="notation:Connector" xmi:id="_et0AcLp2EeaV0fVWRP8bJg" type="Connector_Edge" source="_VB-0ULp2EeaV0fVWRP8bJg" target="_d5mVQLp2EeaV0fVWRP8bJg"> + <children xmi:type="notation:DecorationNode" xmi:id="_et0ngLp2EeaV0fVWRP8bJg" type="Connector_StereotypeLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_et0ngbp2EeaV0fVWRP8bJg" y="60"/> + </children> + <children xmi:type="notation:DecorationNode" xmi:id="_et0ngrp2EeaV0fVWRP8bJg" type="Connector_NameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_et0ng7p2EeaV0fVWRP8bJg" y="-20"/> + </children> + <styles xmi:type="notation:FontStyle" xmi:id="_et0Acbp2EeaV0fVWRP8bJg"/> + <element xmi:type="uml:Connector" href="connectors.uml#_etrdkLp2EeaV0fVWRP8bJg"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_et0Acrp2EeaV0fVWRP8bJg" points="[48, 163, -643984, -643984]$[171, 128, -643984, -643984]"/> + </edges> + <edges xmi:type="notation:Connector" xmi:id="_euCC5Lp2EeaV0fVWRP8bJg" type="StereotypeCommentLink" source="_et0AcLp2EeaV0fVWRP8bJg" target="_euCC4Lp2EeaV0fVWRP8bJg"> + <styles xmi:type="notation:FontStyle" xmi:id="_euCC5bp2EeaV0fVWRP8bJg"/> + <styles xmi:type="notation:EObjectValueStyle" xmi:id="_euCC6bp2EeaV0fVWRP8bJg" name="BASE_ELEMENT"> + <eObjectValue xmi:type="uml:Connector" href="connectors.uml#_etrdkLp2EeaV0fVWRP8bJg"/> + </styles> + <element xsi:nil="true"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_euCC5rp2EeaV0fVWRP8bJg" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_euCC57p2EeaV0fVWRP8bJg"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_euCC6Lp2EeaV0fVWRP8bJg"/> + </edges> + </notation:Diagram> + <notation:Diagram xmi:id="_eOk3oKaqEeaVuqljGw-fqQ" type="CompositeStructure" measurementUnit="Pixel"> + <children xmi:type="notation:Shape" xmi:id="_eOlesKaqEeaVuqljGw-fqQ" type="Class_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_eOlesqaqEeaVuqljGw-fqQ" type="Class_NameLabel"/> + <children xmi:type="notation:DecorationNode" xmi:id="_eOles6aqEeaVuqljGw-fqQ" type="Class_FloatingNameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_eOletKaqEeaVuqljGw-fqQ" y="5"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_eOletaaqEeaVuqljGw-fqQ" type="Class_StructureCompartment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_eOletqaqEeaVuqljGw-fqQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_eOlet6aqEeaVuqljGw-fqQ"/> + </children> + <element xmi:type="uml:Class" href="connectors.uml#_eOTK0KaqEeaVuqljGw-fqQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_eOlesaaqEeaVuqljGw-fqQ" x="40" y="40" width="500" height="250"/> + </children> + <styles xmi:type="notation:StringValueStyle" xmi:id="_eOk3oaaqEeaVuqljGw-fqQ" name="diagram_compatibility_version" stringValue="1.2.0"/> + <styles xmi:type="notation:DiagramStyle" xmi:id="_eOk3oqaqEeaVuqljGw-fqQ"/> + <styles xmi:type="style:PapyrusViewStyle" xmi:id="_eOk3o6aqEeaVuqljGw-fqQ"> + <owner xmi:type="uml:Class" href="connectors.uml#_eOTK0KaqEeaVuqljGw-fqQ"/> + <configuration xmi:type="configuration:PapyrusDiagram" href="platform:/plugin/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/configuration/UMLRT.configuration#_Z79eQHcZEeSnWeKqQOfW2A"/> + </styles> + <element xmi:type="uml:Class" href="connectors.uml#_eOTK0KaqEeaVuqljGw-fqQ"/> + </notation:Diagram> + <notation:Diagram xmi:id="_go16oKaqEeaVuqljGw-fqQ" type="CompositeStructure" measurementUnit="Pixel"> + <children xmi:type="notation:Shape" xmi:id="_go2hsKaqEeaVuqljGw-fqQ" type="Class_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_go2hsqaqEeaVuqljGw-fqQ" type="Class_NameLabel"/> + <children xmi:type="notation:DecorationNode" xmi:id="_go2hs6aqEeaVuqljGw-fqQ" type="Class_FloatingNameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_go2htKaqEeaVuqljGw-fqQ" y="5"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_go2htaaqEeaVuqljGw-fqQ" type="Class_StructureCompartment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_go2htqaqEeaVuqljGw-fqQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_go2ht6aqEeaVuqljGw-fqQ"/> + </children> + <element xmi:type="uml:Class" href="connectors.uml#_golb8KaqEeaVuqljGw-fqQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_go2hsaaqEeaVuqljGw-fqQ" x="40" y="40" width="500" height="250"/> + </children> + <styles xmi:type="notation:StringValueStyle" xmi:id="_go16oaaqEeaVuqljGw-fqQ" name="diagram_compatibility_version" stringValue="1.2.0"/> + <styles xmi:type="notation:DiagramStyle" xmi:id="_go16oqaqEeaVuqljGw-fqQ"/> + <styles xmi:type="style:PapyrusViewStyle" xmi:id="_go16o6aqEeaVuqljGw-fqQ"> + <owner xmi:type="uml:Class" href="connectors.uml#_golb8KaqEeaVuqljGw-fqQ"/> + <configuration xmi:type="configuration:PapyrusDiagram" href="platform:/plugin/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/configuration/UMLRT.configuration#_Z79eQHcZEeSnWeKqQOfW2A"/> + </styles> + <element xmi:type="uml:Class" href="connectors.uml#_golb8KaqEeaVuqljGw-fqQ"/> + </notation:Diagram> + <notation:Diagram xmi:id="_bbqTMLp2EeaV0fVWRP8bJg" type="CompositeStructure" measurementUnit="Pixel"> + <children xmi:type="notation:Shape" xmi:id="_bbq6QLp2EeaV0fVWRP8bJg" type="Class_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_bbq6Qrp2EeaV0fVWRP8bJg" type="Class_NameLabel"/> + <children xmi:type="notation:DecorationNode" xmi:id="_bbq6Q7p2EeaV0fVWRP8bJg" type="Class_FloatingNameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_bbq6RLp2EeaV0fVWRP8bJg" y="5"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_bbq6Rbp2EeaV0fVWRP8bJg" type="Class_StructureCompartment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_bbq6Rrp2EeaV0fVWRP8bJg"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_bbq6R7p2EeaV0fVWRP8bJg"/> + </children> + <children xmi:type="notation:Shape" xmi:id="_d5j5ALp2EeaV0fVWRP8bJg" type="Port_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_d5j5Arp2EeaV0fVWRP8bJg" type="Port_NameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_d5j5A7p2EeaV0fVWRP8bJg" x="25" y="3"/> + </children> + <children xmi:type="notation:DecorationNode" xmi:id="_d5j5BLp2EeaV0fVWRP8bJg" type="Port_StereotypeLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_d5j5Bbp2EeaV0fVWRP8bJg" x="25" y="-10"/> + </children> + <element xmi:type="uml:Port" href="connectors.uml#_dVF6ALp2EeaV0fVWRP8bJg"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_d5j5Abp2EeaV0fVWRP8bJg" y="105" width="16" height="16"/> + </children> + <element xmi:type="uml:Class" href="connectors.uml#_bZqvILp2EeaV0fVWRP8bJg"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_bbq6Qbp2EeaV0fVWRP8bJg" x="40" y="40" width="500" height="250"/> + </children> + <styles xmi:type="notation:StringValueStyle" xmi:id="_bbqTMbp2EeaV0fVWRP8bJg" name="diagram_compatibility_version" stringValue="1.2.0"/> + <styles xmi:type="notation:DiagramStyle" xmi:id="_bbqTMrp2EeaV0fVWRP8bJg"/> + <styles xmi:type="style:PapyrusViewStyle" xmi:id="_bbqTM7p2EeaV0fVWRP8bJg"> + <owner xmi:type="uml:Class" href="connectors.uml#_bZqvILp2EeaV0fVWRP8bJg"/> + <configuration xmi:type="configuration:PapyrusDiagram" href="platform:/plugin/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/configuration/UMLRT.configuration#_Z79eQHcZEeSnWeKqQOfW2A"/> + </styles> + <element xmi:type="uml:Class" href="connectors.uml#_bZqvILp2EeaV0fVWRP8bJg"/> + </notation:Diagram> +</xmi:XMI> diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/connectors.uml b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/connectors.uml new file mode 100644 index 000000000..2a4a2acac --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/connectors.uml @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:UMLRealTime="http://www.eclipse.org/papyrus/umlrt" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML"> + <uml:Model xmi:id="_upCUYKapEeaVuqljGw-fqQ" name="connectors"> + <packageImport xmi:id="_4tIaoK5sEeab8Ykik38t7Q"> + <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/> + </packageImport> + <packagedElement xmi:type="uml:Class" xmi:id="_cUZp8KaqEeaVuqljGw-fqQ" name="RootCapsule" isActive="true"> + <ownedAttribute xmi:type="uml:Port" xmi:id="_uFmasKaqEeaVuqljGw-fqQ" name="protocol1" visibility="public" type="_ufaB0KaqEeaVuqljGw-fqQ" isOrdered="true" aggregation="composite"/> + <ownedAttribute xmi:type="uml:Port" xmi:id="_0JPYIKaqEeaVuqljGw-fqQ" name="protocol2" visibility="public" type="_0h-oQKaqEeaVuqljGw-fqQ" isOrdered="true" aggregation="composite" isBehavior="true"> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="_Lp1UoKarEeaVuqljGw-fqQ" value="4"/> + <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="_MY-5oKarEeaVuqljGw-fqQ" value="4"/> + </ownedAttribute> + <ownedAttribute xmi:id="_cisMsLp2EeaV0fVWRP8bJg" name="nestedCapsule" visibility="protected" type="_bZqvILp2EeaV0fVWRP8bJg" isOrdered="true" aggregation="composite"/> + <ownedConnector xmi:id="_etrdkLp2EeaV0fVWRP8bJg" name="connector1"> + <end xmi:id="_etsrsLp2EeaV0fVWRP8bJg" role="_uFmasKaqEeaVuqljGw-fqQ"/> + <end xmi:id="_etsrsbp2EeaV0fVWRP8bJg" partWithPort="_cisMsLp2EeaV0fVWRP8bJg" role="_dVF6ALp2EeaV0fVWRP8bJg"/> + </ownedConnector> + </packagedElement> + <packagedElement xmi:type="uml:Class" xmi:id="_eOTK0KaqEeaVuqljGw-fqQ" name="Subcapsule" isActive="true"> + <generalization xmi:id="_2gbR8KaqEeaVuqljGw-fqQ" general="_cUZp8KaqEeaVuqljGw-fqQ"/> + </packagedElement> + <packagedElement xmi:type="uml:Class" xmi:id="_golb8KaqEeaVuqljGw-fqQ" name="Subsubcapsule" isActive="true"> + <generalization xmi:id="_4D3aoKaqEeaVuqljGw-fqQ" general="_eOTK0KaqEeaVuqljGw-fqQ"/> + </packagedElement> + <packagedElement xmi:type="uml:Package" xmi:id="_ufb3AKaqEeaVuqljGw-fqQ" name="Protocol1"> + <packagedElement xmi:type="uml:Collaboration" xmi:id="_ufaB0KaqEeaVuqljGw-fqQ" name="Protocol1"> + <interfaceRealization xmi:id="_ufgIcKaqEeaVuqljGw-fqQ" client="_ufaB0KaqEeaVuqljGw-fqQ" supplier="_ufeTQKaqEeaVuqljGw-fqQ" contract="_ufeTQKaqEeaVuqljGw-fqQ"/> + <interfaceRealization xmi:id="_ufmPEKaqEeaVuqljGw-fqQ" client="_ufaB0KaqEeaVuqljGw-fqQ" supplier="_ufkZ4KaqEeaVuqljGw-fqQ" contract="_ufkZ4KaqEeaVuqljGw-fqQ"/> + </packagedElement> + <packagedElement xmi:type="uml:Interface" xmi:id="_ufeTQKaqEeaVuqljGw-fqQ" name="Protocol1"> + <ownedOperation xmi:id="_l58soK5lEeab8Ykik38t7Q" name="greet"> + <ownedParameter xmi:id="_0QqTgK5lEeab8Ykik38t7Q" name="data"> + <type xmi:type="uml:PrimitiveType" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#String"/> + </ownedParameter> + </ownedOperation> + </packagedElement> + <packagedElement xmi:type="uml:Interface" xmi:id="_ufhWkKaqEeaVuqljGw-fqQ" name="Protocol1~"/> + <packagedElement xmi:type="uml:Usage" xmi:id="_ufjLwKaqEeaVuqljGw-fqQ" client="_ufaB0KaqEeaVuqljGw-fqQ" supplier="_ufhWkKaqEeaVuqljGw-fqQ"/> + <packagedElement xmi:type="uml:AnyReceiveEvent" xmi:id="_ufjy0KaqEeaVuqljGw-fqQ" name="*"/> + <packagedElement xmi:type="uml:Interface" xmi:id="_ufkZ4KaqEeaVuqljGw-fqQ" name="Protocol1IO"/> + <packagedElement xmi:type="uml:Usage" xmi:id="_ufm2IKaqEeaVuqljGw-fqQ" client="_ufaB0KaqEeaVuqljGw-fqQ" supplier="_ufkZ4KaqEeaVuqljGw-fqQ"/> + <packagedElement xmi:type="uml:CallEvent" xmi:id="_l6EocK5lEeab8Ykik38t7Q" operation="_l58soK5lEeab8Ykik38t7Q"/> + </packagedElement> + <packagedElement xmi:type="uml:Package" xmi:id="_0iAdcKaqEeaVuqljGw-fqQ" name="Protocol2"> + <packagedElement xmi:type="uml:Collaboration" xmi:id="_0h-oQKaqEeaVuqljGw-fqQ" name="Protocol2"> + <interfaceRealization xmi:id="_0iEH0KaqEeaVuqljGw-fqQ" client="_0h-oQKaqEeaVuqljGw-fqQ" supplier="_0iCSoKaqEeaVuqljGw-fqQ" contract="_0iCSoKaqEeaVuqljGw-fqQ"/> + <interfaceRealization xmi:id="_0i0VwKaqEeaVuqljGw-fqQ" client="_0h-oQKaqEeaVuqljGw-fqQ" supplier="_0iHyMKaqEeaVuqljGw-fqQ" contract="_0iHyMKaqEeaVuqljGw-fqQ"/> + </packagedElement> + <packagedElement xmi:type="uml:Interface" xmi:id="_0iCSoKaqEeaVuqljGw-fqQ" name="Protocol2"/> + <packagedElement xmi:type="uml:Interface" xmi:id="_0iEu4KaqEeaVuqljGw-fqQ" name="Protocol2~"/> + <packagedElement xmi:type="uml:Usage" xmi:id="_0iGkEKaqEeaVuqljGw-fqQ" client="_0h-oQKaqEeaVuqljGw-fqQ" supplier="_0iEu4KaqEeaVuqljGw-fqQ"/> + <packagedElement xmi:type="uml:AnyReceiveEvent" xmi:id="_0iHLIKaqEeaVuqljGw-fqQ" name="*"/> + <packagedElement xmi:type="uml:Interface" xmi:id="_0iHyMKaqEeaVuqljGw-fqQ" name="Protocol2IO"/> + <packagedElement xmi:type="uml:Usage" xmi:id="_0i080KaqEeaVuqljGw-fqQ" client="_0h-oQKaqEeaVuqljGw-fqQ" supplier="_0iHyMKaqEeaVuqljGw-fqQ"/> + </packagedElement> + <packagedElement xmi:type="uml:Package" xmi:id="_YbdjIK31Eeab8Ykik38t7Q" name="nested"/> + <packagedElement xmi:type="uml:Class" xmi:id="_bZqvILp2EeaV0fVWRP8bJg" name="NestedCapsule" isActive="true"> + <ownedAttribute xmi:type="uml:Port" xmi:id="_dVF6ALp2EeaV0fVWRP8bJg" name="protocol1" visibility="public" type="_ufaB0KaqEeaVuqljGw-fqQ" isOrdered="true" aggregation="composite" isBehavior="true"/> + </packagedElement> + <profileApplication xmi:id="_usQngKapEeaVuqljGw-fqQ"> + <eAnnotations xmi:id="_usWHEKapEeaVuqljGw-fqQ" source="http://www.eclipse.org/uml2/2.0.0/UML"> + <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/papyrus/umlrt#/"/> + </eAnnotations> + <appliedProfile href="pathmap://UML_RT_PROFILE/uml-rt.profile.uml#_1h74oEeVEeO0lv5O1DTHOQ"/> + </profileApplication> + </uml:Model> + <UMLRealTime:Capsule xmi:id="_caZkQKaqEeaVuqljGw-fqQ" base_Class="_cUZp8KaqEeaVuqljGw-fqQ"/> + <UMLRealTime:Capsule xmi:id="_eOms0KaqEeaVuqljGw-fqQ" base_Class="_eOTK0KaqEeaVuqljGw-fqQ"/> + <UMLRealTime:Capsule xmi:id="_go3IwKaqEeaVuqljGw-fqQ" base_Class="_golb8KaqEeaVuqljGw-fqQ"/> + <UMLRealTime:RTPort xmi:id="_uFo28KaqEeaVuqljGw-fqQ" base_Port="_uFmasKaqEeaVuqljGw-fqQ"/> + <UMLRealTime:ProtocolContainer xmi:id="_ufdFIKaqEeaVuqljGw-fqQ" base_Package="_ufb3AKaqEeaVuqljGw-fqQ"/> + <UMLRealTime:RTMessageSet xmi:id="_uffhYKaqEeaVuqljGw-fqQ" base_Interface="_ufeTQKaqEeaVuqljGw-fqQ"/> + <UMLRealTime:RTMessageSet xmi:id="_ufh9oKaqEeaVuqljGw-fqQ" base_Interface="_ufhWkKaqEeaVuqljGw-fqQ" rtMsgKind="out"/> + <UMLRealTime:RTMessageSet xmi:id="_ufloAKaqEeaVuqljGw-fqQ" base_Interface="_ufkZ4KaqEeaVuqljGw-fqQ" rtMsgKind="inOut"/> + <UMLRealTime:Protocol xmi:id="_ufndMKaqEeaVuqljGw-fqQ" base_Collaboration="_ufaB0KaqEeaVuqljGw-fqQ"/> + <UMLRealTime:RTPort xmi:id="_0JRNUKaqEeaVuqljGw-fqQ" base_Port="_0JPYIKaqEeaVuqljGw-fqQ"/> + <UMLRealTime:ProtocolContainer xmi:id="_0iBrkKaqEeaVuqljGw-fqQ" base_Package="_0iAdcKaqEeaVuqljGw-fqQ"/> + <UMLRealTime:RTMessageSet xmi:id="_0iDgwKaqEeaVuqljGw-fqQ" base_Interface="_0iCSoKaqEeaVuqljGw-fqQ"/> + <UMLRealTime:RTMessageSet xmi:id="_0iF9AKaqEeaVuqljGw-fqQ" base_Interface="_0iEu4KaqEeaVuqljGw-fqQ" rtMsgKind="out"/> + <UMLRealTime:RTMessageSet xmi:id="_0iIZQKaqEeaVuqljGw-fqQ" base_Interface="_0iHyMKaqEeaVuqljGw-fqQ" rtMsgKind="inOut"/> + <UMLRealTime:Protocol xmi:id="_0i080aaqEeaVuqljGw-fqQ" base_Collaboration="_0h-oQKaqEeaVuqljGw-fqQ"/> + <UMLRealTime:Capsule xmi:id="_bbrhULp2EeaV0fVWRP8bJg" base_Class="_bZqvILp2EeaV0fVWRP8bJg"/> + <UMLRealTime:CapsulePart xmi:id="_cita0Lp2EeaV0fVWRP8bJg" base_Property="_cisMsLp2EeaV0fVWRP8bJg"/> + <UMLRealTime:RTPort xmi:id="_dVHIILp2EeaV0fVWRP8bJg" base_Port="_dVF6ALp2EeaV0fVWRP8bJg"/> + <UMLRealTime:RTConnector xmi:id="_etsrsrp2EeaV0fVWRP8bJg" base_Connector="_etrdkLp2EeaV0fVWRP8bJg"/> +</xmi:XMI> diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/parts.di b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/parts.di new file mode 100644 index 000000000..bf9abab34 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/parts.di @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/> diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/parts.notation b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/parts.notation new file mode 100644 index 000000000..0be8cef45 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/parts.notation @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:configuration="http://www.eclipse.org/papyrus/infra/viewpoints/configuration" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/viewpoints/policy/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML"> + <notation:Diagram xmi:id="_9qO_UK3TEeab8Ykik38t7Q" type="CompositeStructure" measurementUnit="Pixel"> + <children xmi:type="notation:Shape" xmi:id="_9qp2EK3TEeab8Ykik38t7Q" type="Class_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_9qsSUK3TEeab8Ykik38t7Q" type="Class_NameLabel"/> + <children xmi:type="notation:DecorationNode" xmi:id="_9qsSUa3TEeab8Ykik38t7Q" type="Class_FloatingNameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_9qsSUq3TEeab8Ykik38t7Q" y="5"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_9qs5YK3TEeab8Ykik38t7Q" type="Class_StructureCompartment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_9qs5Ya3TEeab8Ykik38t7Q"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_9qs5Yq3TEeab8Ykik38t7Q"/> + </children> + <element xmi:type="uml:Class" href="parts.uml#_9mXL8K3TEeab8Ykik38t7Q"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_9qp2Ea3TEeab8Ykik38t7Q" x="40" y="40" width="500" height="250"/> + </children> + <styles xmi:type="notation:StringValueStyle" xmi:id="_9qO_Ua3TEeab8Ykik38t7Q" name="diagram_compatibility_version" stringValue="1.2.0"/> + <styles xmi:type="notation:DiagramStyle" xmi:id="_9qO_Uq3TEeab8Ykik38t7Q"/> + <styles xmi:type="style:PapyrusViewStyle" xmi:id="_9qO_U63TEeab8Ykik38t7Q"> + <owner xmi:type="uml:Class" href="parts.uml#_9mXL8K3TEeab8Ykik38t7Q"/> + <configuration xmi:type="configuration:PapyrusDiagram" href="platform:/plugin/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/configuration/UMLRT.configuration#_Z79eQHcZEeSnWeKqQOfW2A"/> + </styles> + <element xmi:type="uml:Class" href="parts.uml#_9mXL8K3TEeab8Ykik38t7Q"/> + </notation:Diagram> + <notation:Diagram xmi:id="_Bw0aMK3UEeab8Ykik38t7Q" type="CompositeStructure" measurementUnit="Pixel"> + <children xmi:type="notation:Shape" xmi:id="_Bw1BQK3UEeab8Ykik38t7Q" type="Class_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_Bw1oUK3UEeab8Ykik38t7Q" type="Class_NameLabel"/> + <children xmi:type="notation:DecorationNode" xmi:id="_Bw1oUa3UEeab8Ykik38t7Q" type="Class_FloatingNameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_Bw1oUq3UEeab8Ykik38t7Q" y="5"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_Bw1oU63UEeab8Ykik38t7Q" type="Class_StructureCompartment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_Bw1oVK3UEeab8Ykik38t7Q"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Bw1oVa3UEeab8Ykik38t7Q"/> + </children> + <element xmi:type="uml:Class" href="parts.uml#_BwitYK3UEeab8Ykik38t7Q"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Bw1BQa3UEeab8Ykik38t7Q" x="40" y="40" width="500" height="250"/> + </children> + <styles xmi:type="notation:StringValueStyle" xmi:id="_Bw0aMa3UEeab8Ykik38t7Q" name="diagram_compatibility_version" stringValue="1.2.0"/> + <styles xmi:type="notation:DiagramStyle" xmi:id="_Bw0aMq3UEeab8Ykik38t7Q"/> + <styles xmi:type="style:PapyrusViewStyle" xmi:id="_Bw0aM63UEeab8Ykik38t7Q"> + <owner xmi:type="uml:Class" href="parts.uml#_BwitYK3UEeab8Ykik38t7Q"/> + <configuration xmi:type="configuration:PapyrusDiagram" href="platform:/plugin/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/configuration/UMLRT.configuration#_Z79eQHcZEeSnWeKqQOfW2A"/> + </styles> + <element xmi:type="uml:Class" href="parts.uml#_BwitYK3UEeab8Ykik38t7Q"/> + </notation:Diagram> + <notation:Diagram xmi:id="_DuoxwK3UEeab8Ykik38t7Q" type="CompositeStructure" measurementUnit="Pixel"> + <children xmi:type="notation:Shape" xmi:id="_DupY0K3UEeab8Ykik38t7Q" type="Class_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_DupY0q3UEeab8Ykik38t7Q" type="Class_NameLabel"/> + <children xmi:type="notation:DecorationNode" xmi:id="_DupY063UEeab8Ykik38t7Q" type="Class_FloatingNameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_DupY1K3UEeab8Ykik38t7Q" y="5"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_DupY1a3UEeab8Ykik38t7Q" type="Class_StructureCompartment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_DupY1q3UEeab8Ykik38t7Q"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_DupY163UEeab8Ykik38t7Q"/> + </children> + <element xmi:type="uml:Class" href="parts.uml#_Dub9cK3UEeab8Ykik38t7Q"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_DupY0a3UEeab8Ykik38t7Q" x="40" y="40" width="500" height="250"/> + </children> + <styles xmi:type="notation:StringValueStyle" xmi:id="_Duoxwa3UEeab8Ykik38t7Q" name="diagram_compatibility_version" stringValue="1.2.0"/> + <styles xmi:type="notation:DiagramStyle" xmi:id="_Duoxwq3UEeab8Ykik38t7Q"/> + <styles xmi:type="style:PapyrusViewStyle" xmi:id="_Duoxw63UEeab8Ykik38t7Q"> + <owner xmi:type="uml:Class" href="parts.uml#_Dub9cK3UEeab8Ykik38t7Q"/> + <configuration xmi:type="configuration:PapyrusDiagram" href="platform:/plugin/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/configuration/UMLRT.configuration#_Z79eQHcZEeSnWeKqQOfW2A"/> + </styles> + <element xmi:type="uml:Class" href="parts.uml#_Dub9cK3UEeab8Ykik38t7Q"/> + </notation:Diagram> + <notation:Diagram xmi:id="_FO2nUK3UEeab8Ykik38t7Q" type="CompositeStructure" measurementUnit="Pixel"> + <children xmi:type="notation:Shape" xmi:id="_FO4cgK3UEeab8Ykik38t7Q" type="Class_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_FO4cgq3UEeab8Ykik38t7Q" type="Class_NameLabel"/> + <children xmi:type="notation:DecorationNode" xmi:id="_FO4cg63UEeab8Ykik38t7Q" type="Class_FloatingNameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_FO4chK3UEeab8Ykik38t7Q" y="5"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_FO5DkK3UEeab8Ykik38t7Q" type="Class_StructureCompartment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_FO5Dka3UEeab8Ykik38t7Q"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_FO5Dkq3UEeab8Ykik38t7Q"/> + </children> + <element xmi:type="uml:Class" href="parts.uml#_FOroMK3UEeab8Ykik38t7Q"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_FO4cga3UEeab8Ykik38t7Q" x="40" y="40" width="500" height="250"/> + </children> + <styles xmi:type="notation:StringValueStyle" xmi:id="_FO2nUa3UEeab8Ykik38t7Q" name="diagram_compatibility_version" stringValue="1.2.0"/> + <styles xmi:type="notation:DiagramStyle" xmi:id="_FO2nUq3UEeab8Ykik38t7Q"/> + <styles xmi:type="style:PapyrusViewStyle" xmi:id="_FO2nU63UEeab8Ykik38t7Q"> + <owner xmi:type="uml:Class" href="parts.uml#_FOroMK3UEeab8Ykik38t7Q"/> + <configuration xmi:type="configuration:PapyrusDiagram" href="platform:/plugin/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/configuration/UMLRT.configuration#_Z79eQHcZEeSnWeKqQOfW2A"/> + </styles> + <element xmi:type="uml:Class" href="parts.uml#_FOroMK3UEeab8Ykik38t7Q"/> + </notation:Diagram> + <notation:Diagram xmi:id="_OOUcsK3UEeab8Ykik38t7Q" type="CompositeStructure" measurementUnit="Pixel"> + <children xmi:type="notation:Shape" xmi:id="_OOUctK3UEeab8Ykik38t7Q" type="Class_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_OOVDwK3UEeab8Ykik38t7Q" type="Class_NameLabel"/> + <children xmi:type="notation:DecorationNode" xmi:id="_OOVDwa3UEeab8Ykik38t7Q" type="Class_FloatingNameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_OOVDwq3UEeab8Ykik38t7Q" y="5"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_OOVDw63UEeab8Ykik38t7Q" type="Class_StructureCompartment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_OOVDxK3UEeab8Ykik38t7Q"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OOVDxa3UEeab8Ykik38t7Q"/> + </children> + <element xmi:type="uml:Class" href="parts.uml#_OOKEoK3UEeab8Ykik38t7Q"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_OOUcta3UEeab8Ykik38t7Q" x="40" y="40" width="500" height="250"/> + </children> + <styles xmi:type="notation:StringValueStyle" xmi:id="_OOUcsa3UEeab8Ykik38t7Q" name="diagram_compatibility_version" stringValue="1.2.0"/> + <styles xmi:type="notation:DiagramStyle" xmi:id="_OOUcsq3UEeab8Ykik38t7Q"/> + <styles xmi:type="style:PapyrusViewStyle" xmi:id="_OOUcs63UEeab8Ykik38t7Q"> + <owner xmi:type="uml:Class" href="parts.uml#_OOKEoK3UEeab8Ykik38t7Q"/> + <configuration xmi:type="configuration:PapyrusDiagram" href="platform:/plugin/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/configuration/UMLRT.configuration#_Z79eQHcZEeSnWeKqQOfW2A"/> + </styles> + <element xmi:type="uml:Class" href="parts.uml#_OOKEoK3UEeab8Ykik38t7Q"/> + </notation:Diagram> +</xmi:XMI> diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/parts.uml b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/parts.uml new file mode 100644 index 000000000..7bfb4c396 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/parts.uml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:UMLRealTime="http://www.eclipse.org/papyrus/umlrt" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML"> + <uml:Model xmi:id="_77Y34K3TEeab8Ykik38t7Q" name="parts"> + <packagedElement xmi:type="uml:Class" xmi:id="_9mXL8K3TEeab8Ykik38t7Q" name="RootCapsule" isActive="true"> + <ownedAttribute xmi:id="_Bd2a4K3UEeab8Ykik38t7Q" name="capsule2" visibility="protected" type="_BwitYK3UEeab8Ykik38t7Q" isOrdered="true" aggregation="composite"/> + <ownedAttribute xmi:id="_DhOn4K3UEeab8Ykik38t7Q" name="capsule3" visibility="protected" type="_Dub9cK3UEeab8Ykik38t7Q" isOrdered="true" aggregation="composite"> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="_tThaIK3UEeab8Ykik38t7Q" value="4"/> + <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="_t_WlYK3UEeab8Ykik38t7Q" value="4"/> + </ownedAttribute> + </packagedElement> + <packagedElement xmi:type="uml:Class" xmi:id="_BwitYK3UEeab8Ykik38t7Q" name="Capsule2" isActive="true"/> + <packagedElement xmi:type="uml:Class" xmi:id="_Dub9cK3UEeab8Ykik38t7Q" name="Capsule3" isActive="true"/> + <packagedElement xmi:type="uml:Class" xmi:id="_FOroMK3UEeab8Ykik38t7Q" name="Subcapsule" isActive="true"> + <generalization xmi:id="_H3CKgK3UEeab8Ykik38t7Q" general="_9mXL8K3TEeab8Ykik38t7Q"/> + <ownedAttribute xmi:id="_L2fpsK3UEeab8Ykik38t7Q" isOrdered="true" aggregation="composite" redefinedProperty="_Bd2a4K3UEeab8Ykik38t7Q"/> + <ownedAttribute xmi:id="_L2gQwK3UEeab8Ykik38t7Q" name="subpart" type="_wYHzkK3UEeab8Ykik38t7Q" isOrdered="true" aggregation="composite" redefinedProperty="_DhOn4K3UEeab8Ykik38t7Q"/> + </packagedElement> + <packagedElement xmi:type="uml:Class" xmi:id="_wYHzkK3UEeab8Ykik38t7Q" name="Capsule4" isActive="true"> + <generalization xmi:id="_x-G58K3UEeab8Ykik38t7Q" general="_Dub9cK3UEeab8Ykik38t7Q"/> + </packagedElement> + <packagedElement xmi:type="uml:Class" xmi:id="_OOKEoK3UEeab8Ykik38t7Q" name="Subsubcapsule" isActive="true"> + <generalization xmi:id="_RyvlsK3UEeab8Ykik38t7Q" general="_FOroMK3UEeab8Ykik38t7Q"/> + <ownedAttribute xmi:id="_TLYzoK3UEeab8Ykik38t7Q" isOrdered="true" aggregation="composite" redefinedProperty="_L2fpsK3UEeab8Ykik38t7Q"/> + <ownedAttribute xmi:id="_TLZasK3UEeab8Ykik38t7Q" isOrdered="true" aggregation="composite" redefinedProperty="_L2gQwK3UEeab8Ykik38t7Q"> + <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="_8SabUK3UEeab8Ykik38t7Q" value="6"/> + </ownedAttribute> + </packagedElement> + <profileApplication xmi:id="_77xSYK3TEeab8Ykik38t7Q"> + <eAnnotations xmi:id="_77zHkK3TEeab8Ykik38t7Q" source="http://www.eclipse.org/uml2/2.0.0/UML"> + <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/papyrus/umlrt#/"/> + </eAnnotations> + <appliedProfile href="pathmap://UML_RT_PROFILE/uml-rt.profile.uml#_1h74oEeVEeO0lv5O1DTHOQ"/> + </profileApplication> + </uml:Model> + <UMLRealTime:Capsule xmi:id="_9qwjwK3TEeab8Ykik38t7Q" base_Class="_9mXL8K3TEeab8Ykik38t7Q"/> + <UMLRealTime:CapsulePart xmi:id="_BeFEYK3UEeab8Ykik38t7Q" base_Property="_Bd2a4K3UEeab8Ykik38t7Q"/> + <UMLRealTime:Capsule xmi:id="_Bw2PYK3UEeab8Ykik38t7Q" base_Class="_BwitYK3UEeab8Ykik38t7Q"/> + <UMLRealTime:CapsulePart xmi:id="_DhQdEK3UEeab8Ykik38t7Q" base_Property="_DhOn4K3UEeab8Ykik38t7Q"/> + <UMLRealTime:Capsule xmi:id="_Dup_4K3UEeab8Ykik38t7Q" base_Class="_Dub9cK3UEeab8Ykik38t7Q"/> + <UMLRealTime:Capsule xmi:id="_FO5Dk63UEeab8Ykik38t7Q" base_Class="_FOroMK3UEeab8Ykik38t7Q"/> + <UMLRealTime:CapsulePart xmi:id="_L2g30K3UEeab8Ykik38t7Q" base_Property="_L2fpsK3UEeab8Ykik38t7Q"/> + <UMLRealTime:CapsulePart xmi:id="_L2he4K3UEeab8Ykik38t7Q" base_Property="_L2gQwK3UEeab8Ykik38t7Q"/> + <UMLRealTime:Capsule xmi:id="_OOVq0K3UEeab8Ykik38t7Q" base_Class="_OOKEoK3UEeab8Ykik38t7Q"/> + <UMLRealTime:CapsulePart xmi:id="_TLZasa3UEeab8Ykik38t7Q" base_Property="_TLYzoK3UEeab8Ykik38t7Q"/> + <UMLRealTime:CapsulePart xmi:id="_TLaBwK3UEeab8Ykik38t7Q" base_Property="_TLZasK3UEeab8Ykik38t7Q"/> + <UMLRealTime:RTRedefinedElement xmi:id="_YDej8K3UEeab8Ykik38t7Q" base_RedefinableElement="_L2fpsK3UEeab8Ykik38t7Q" rootFragment="_Bd2a4K3UEeab8Ykik38t7Q"/> + <UMLRealTime:RTRedefinedElement xmi:id="_c_B38K3UEeab8Ykik38t7Q" base_RedefinableElement="_L2gQwK3UEeab8Ykik38t7Q" rootFragment="_DhOn4K3UEeab8Ykik38t7Q"/> + <UMLRealTime:Capsule xmi:id="_wYOhQK3UEeab8Ykik38t7Q" base_Class="_wYHzkK3UEeab8Ykik38t7Q"/> + <UMLRealTime:RTRedefinedElement xmi:id="_IbklgK3VEeab8Ykik38t7Q" base_RedefinableElement="_TLYzoK3UEeab8Ykik38t7Q" rootFragment="_Bd2a4K3UEeab8Ykik38t7Q"/> + <UMLRealTime:RTRedefinedElement xmi:id="_LFrbUK3VEeab8Ykik38t7Q" base_RedefinableElement="_TLZasK3UEeab8Ykik38t7Q" rootFragment="_DhOn4K3UEeab8Ykik38t7Q"/> +</xmi:XMI> diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/ports.di b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/ports.di new file mode 100644 index 000000000..bf9abab34 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/ports.di @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/> diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/ports.notation b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/ports.notation new file mode 100644 index 000000000..98ba51356 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/ports.notation @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:configuration="http://www.eclipse.org/papyrus/infra/viewpoints/configuration" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/viewpoints/policy/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML"> + <notation:Diagram xmi:id="_cZ1jkKaqEeaVuqljGw-fqQ" type="CompositeStructure" measurementUnit="Pixel"> + <children xmi:type="notation:Shape" xmi:id="_caQaUKaqEeaVuqljGw-fqQ" type="Class_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_caTdoKaqEeaVuqljGw-fqQ" type="Class_NameLabel"/> + <children xmi:type="notation:DecorationNode" xmi:id="_caTdoaaqEeaVuqljGw-fqQ" type="Class_FloatingNameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_caTdoqaqEeaVuqljGw-fqQ" y="5"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_caUEsKaqEeaVuqljGw-fqQ" type="Class_StructureCompartment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_caUEsaaqEeaVuqljGw-fqQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_caUEsqaqEeaVuqljGw-fqQ"/> + </children> + <element xmi:type="uml:Class" href="ports.uml#_cUZp8KaqEeaVuqljGw-fqQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_caQaUaaqEeaVuqljGw-fqQ" x="40" y="40" width="500" height="250"/> + </children> + <styles xmi:type="notation:StringValueStyle" xmi:id="_cZ1jkaaqEeaVuqljGw-fqQ" name="diagram_compatibility_version" stringValue="1.2.0"/> + <styles xmi:type="notation:DiagramStyle" xmi:id="_cZ1jkqaqEeaVuqljGw-fqQ"/> + <styles xmi:type="style:PapyrusViewStyle" xmi:id="_cZ1jk6aqEeaVuqljGw-fqQ"> + <owner xmi:type="uml:Class" href="ports.uml#_cUZp8KaqEeaVuqljGw-fqQ"/> + <configuration xmi:type="configuration:PapyrusDiagram" href="platform:/plugin/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/configuration/UMLRT.configuration#_Z79eQHcZEeSnWeKqQOfW2A"/> + </styles> + <element xmi:type="uml:Class" href="ports.uml#_cUZp8KaqEeaVuqljGw-fqQ"/> + </notation:Diagram> + <notation:Diagram xmi:id="_eOk3oKaqEeaVuqljGw-fqQ" type="CompositeStructure" measurementUnit="Pixel"> + <children xmi:type="notation:Shape" xmi:id="_eOlesKaqEeaVuqljGw-fqQ" type="Class_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_eOlesqaqEeaVuqljGw-fqQ" type="Class_NameLabel"/> + <children xmi:type="notation:DecorationNode" xmi:id="_eOles6aqEeaVuqljGw-fqQ" type="Class_FloatingNameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_eOletKaqEeaVuqljGw-fqQ" y="5"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_eOletaaqEeaVuqljGw-fqQ" type="Class_StructureCompartment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_eOletqaqEeaVuqljGw-fqQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_eOlet6aqEeaVuqljGw-fqQ"/> + </children> + <element xmi:type="uml:Class" href="ports.uml#_eOTK0KaqEeaVuqljGw-fqQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_eOlesaaqEeaVuqljGw-fqQ" x="40" y="40" width="500" height="250"/> + </children> + <styles xmi:type="notation:StringValueStyle" xmi:id="_eOk3oaaqEeaVuqljGw-fqQ" name="diagram_compatibility_version" stringValue="1.2.0"/> + <styles xmi:type="notation:DiagramStyle" xmi:id="_eOk3oqaqEeaVuqljGw-fqQ"/> + <styles xmi:type="style:PapyrusViewStyle" xmi:id="_eOk3o6aqEeaVuqljGw-fqQ"> + <owner xmi:type="uml:Class" href="ports.uml#_eOTK0KaqEeaVuqljGw-fqQ"/> + <configuration xmi:type="configuration:PapyrusDiagram" href="platform:/plugin/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/configuration/UMLRT.configuration#_Z79eQHcZEeSnWeKqQOfW2A"/> + </styles> + <element xmi:type="uml:Class" href="ports.uml#_eOTK0KaqEeaVuqljGw-fqQ"/> + </notation:Diagram> + <notation:Diagram xmi:id="_go16oKaqEeaVuqljGw-fqQ" type="CompositeStructure" measurementUnit="Pixel"> + <children xmi:type="notation:Shape" xmi:id="_go2hsKaqEeaVuqljGw-fqQ" type="Class_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_go2hsqaqEeaVuqljGw-fqQ" type="Class_NameLabel"/> + <children xmi:type="notation:DecorationNode" xmi:id="_go2hs6aqEeaVuqljGw-fqQ" type="Class_FloatingNameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_go2htKaqEeaVuqljGw-fqQ" y="5"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_go2htaaqEeaVuqljGw-fqQ" type="Class_StructureCompartment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_go2htqaqEeaVuqljGw-fqQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_go2ht6aqEeaVuqljGw-fqQ"/> + </children> + <element xmi:type="uml:Class" href="ports.uml#_golb8KaqEeaVuqljGw-fqQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_go2hsaaqEeaVuqljGw-fqQ" x="40" y="40" width="500" height="250"/> + </children> + <styles xmi:type="notation:StringValueStyle" xmi:id="_go16oaaqEeaVuqljGw-fqQ" name="diagram_compatibility_version" stringValue="1.2.0"/> + <styles xmi:type="notation:DiagramStyle" xmi:id="_go16oqaqEeaVuqljGw-fqQ"/> + <styles xmi:type="style:PapyrusViewStyle" xmi:id="_go16o6aqEeaVuqljGw-fqQ"> + <owner xmi:type="uml:Class" href="ports.uml#_golb8KaqEeaVuqljGw-fqQ"/> + <configuration xmi:type="configuration:PapyrusDiagram" href="platform:/plugin/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/configuration/UMLRT.configuration#_Z79eQHcZEeSnWeKqQOfW2A"/> + </styles> + <element xmi:type="uml:Class" href="ports.uml#_golb8KaqEeaVuqljGw-fqQ"/> + </notation:Diagram> +</xmi:XMI> diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/ports.uml b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/ports.uml new file mode 100644 index 000000000..a299224b4 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/inheritance/ports.uml @@ -0,0 +1,94 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:UMLRealTime="http://www.eclipse.org/papyrus/umlrt" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML"> + <uml:Model xmi:id="_upCUYKapEeaVuqljGw-fqQ" name="ports"> + <packageImport xmi:id="_4tIaoK5sEeab8Ykik38t7Q"> + <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/> + </packageImport> + <packagedElement xmi:type="uml:Class" xmi:id="_cUZp8KaqEeaVuqljGw-fqQ" name="RootCapsule" isActive="true"> + <ownedAttribute xmi:type="uml:Port" xmi:id="_uFmasKaqEeaVuqljGw-fqQ" name="protocol1" visibility="public" type="_ufaB0KaqEeaVuqljGw-fqQ" isOrdered="true" aggregation="composite" isBehavior="true"/> + <ownedAttribute xmi:type="uml:Port" xmi:id="_0JPYIKaqEeaVuqljGw-fqQ" name="protocol2" visibility="public" type="_0h-oQKaqEeaVuqljGw-fqQ" isOrdered="true" aggregation="composite" isBehavior="true"> + <lowerValue xmi:type="uml:LiteralInteger" xmi:id="_Lp1UoKarEeaVuqljGw-fqQ" value="4"/> + <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="_MY-5oKarEeaVuqljGw-fqQ" value="4"/> + </ownedAttribute> + </packagedElement> + <packagedElement xmi:type="uml:Class" xmi:id="_eOTK0KaqEeaVuqljGw-fqQ" name="Subcapsule" isActive="true"> + <generalization xmi:id="_2gbR8KaqEeaVuqljGw-fqQ" general="_cUZp8KaqEeaVuqljGw-fqQ"/> + <ownedAttribute xmi:type="uml:Port" xmi:id="_AZbXYKarEeaVuqljGw-fqQ" isOrdered="true" aggregation="composite" redefinedProperty="_uFmasKaqEeaVuqljGw-fqQ" redefinedPort="_uFmasKaqEeaVuqljGw-fqQ"/> + <ownedAttribute xmi:type="uml:Port" xmi:id="_AZbXYaarEeaVuqljGw-fqQ" name="subport" type="_ufeTQKaqEeaVuqljGw-fqQ" isOrdered="true" aggregation="composite" redefinedProperty="_0JPYIKaqEeaVuqljGw-fqQ" redefinedPort="_0JPYIKaqEeaVuqljGw-fqQ"/> + </packagedElement> + <packagedElement xmi:type="uml:Class" xmi:id="_golb8KaqEeaVuqljGw-fqQ" name="Subsubcapsule" isActive="true"> + <generalization xmi:id="_4D3aoKaqEeaVuqljGw-fqQ" general="_eOTK0KaqEeaVuqljGw-fqQ"/> + <ownedAttribute xmi:type="uml:Port" xmi:id="_QxE7QKarEeaVuqljGw-fqQ" isOrdered="true" aggregation="composite" redefinedProperty="_AZbXYKarEeaVuqljGw-fqQ" redefinedPort="_AZbXYKarEeaVuqljGw-fqQ"/> + <ownedAttribute xmi:type="uml:Port" xmi:id="_QxE7QaarEeaVuqljGw-fqQ" isOrdered="true" aggregation="composite" redefinedProperty="_AZbXYaarEeaVuqljGw-fqQ" redefinedPort="_AZbXYaarEeaVuqljGw-fqQ"> + <upperValue xmi:type="uml:LiteralUnlimitedNatural" xmi:id="_tBKFsKarEeaVuqljGw-fqQ" value="6"/> + </ownedAttribute> + </packagedElement> + <packagedElement xmi:type="uml:Package" xmi:id="_ufb3AKaqEeaVuqljGw-fqQ" name="Protocol1"> + <packagedElement xmi:type="uml:Collaboration" xmi:id="_ufaB0KaqEeaVuqljGw-fqQ" name="Protocol1"> + <interfaceRealization xmi:id="_ufgIcKaqEeaVuqljGw-fqQ" client="_ufaB0KaqEeaVuqljGw-fqQ" supplier="_ufeTQKaqEeaVuqljGw-fqQ" contract="_ufeTQKaqEeaVuqljGw-fqQ"/> + <interfaceRealization xmi:id="_ufmPEKaqEeaVuqljGw-fqQ" client="_ufaB0KaqEeaVuqljGw-fqQ" supplier="_ufkZ4KaqEeaVuqljGw-fqQ" contract="_ufkZ4KaqEeaVuqljGw-fqQ"/> + </packagedElement> + <packagedElement xmi:type="uml:Interface" xmi:id="_ufeTQKaqEeaVuqljGw-fqQ" name="Protocol1"> + <ownedOperation xmi:id="_l58soK5lEeab8Ykik38t7Q" name="greet"> + <ownedParameter xmi:id="_0QqTgK5lEeab8Ykik38t7Q" name="data"> + <type xmi:type="uml:PrimitiveType" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#String"/> + </ownedParameter> + </ownedOperation> + </packagedElement> + <packagedElement xmi:type="uml:Interface" xmi:id="_ufhWkKaqEeaVuqljGw-fqQ" name="Protocol1~"/> + <packagedElement xmi:type="uml:Usage" xmi:id="_ufjLwKaqEeaVuqljGw-fqQ" client="_ufaB0KaqEeaVuqljGw-fqQ" supplier="_ufhWkKaqEeaVuqljGw-fqQ"/> + <packagedElement xmi:type="uml:AnyReceiveEvent" xmi:id="_ufjy0KaqEeaVuqljGw-fqQ" name="*"/> + <packagedElement xmi:type="uml:Interface" xmi:id="_ufkZ4KaqEeaVuqljGw-fqQ" name="Protocol1IO"/> + <packagedElement xmi:type="uml:Usage" xmi:id="_ufm2IKaqEeaVuqljGw-fqQ" client="_ufaB0KaqEeaVuqljGw-fqQ" supplier="_ufkZ4KaqEeaVuqljGw-fqQ"/> + <packagedElement xmi:type="uml:CallEvent" xmi:id="_l6EocK5lEeab8Ykik38t7Q" operation="_l58soK5lEeab8Ykik38t7Q"/> + </packagedElement> + <packagedElement xmi:type="uml:Package" xmi:id="_0iAdcKaqEeaVuqljGw-fqQ" name="Protocol2"> + <packagedElement xmi:type="uml:Collaboration" xmi:id="_0h-oQKaqEeaVuqljGw-fqQ" name="Protocol2"> + <interfaceRealization xmi:id="_0iEH0KaqEeaVuqljGw-fqQ" client="_0h-oQKaqEeaVuqljGw-fqQ" supplier="_0iCSoKaqEeaVuqljGw-fqQ" contract="_0iCSoKaqEeaVuqljGw-fqQ"/> + <interfaceRealization xmi:id="_0i0VwKaqEeaVuqljGw-fqQ" client="_0h-oQKaqEeaVuqljGw-fqQ" supplier="_0iHyMKaqEeaVuqljGw-fqQ" contract="_0iHyMKaqEeaVuqljGw-fqQ"/> + </packagedElement> + <packagedElement xmi:type="uml:Interface" xmi:id="_0iCSoKaqEeaVuqljGw-fqQ" name="Protocol2"/> + <packagedElement xmi:type="uml:Interface" xmi:id="_0iEu4KaqEeaVuqljGw-fqQ" name="Protocol2~"/> + <packagedElement xmi:type="uml:Usage" xmi:id="_0iGkEKaqEeaVuqljGw-fqQ" client="_0h-oQKaqEeaVuqljGw-fqQ" supplier="_0iEu4KaqEeaVuqljGw-fqQ"/> + <packagedElement xmi:type="uml:AnyReceiveEvent" xmi:id="_0iHLIKaqEeaVuqljGw-fqQ" name="*"/> + <packagedElement xmi:type="uml:Interface" xmi:id="_0iHyMKaqEeaVuqljGw-fqQ" name="Protocol2IO"/> + <packagedElement xmi:type="uml:Usage" xmi:id="_0i080KaqEeaVuqljGw-fqQ" client="_0h-oQKaqEeaVuqljGw-fqQ" supplier="_0iHyMKaqEeaVuqljGw-fqQ"/> + </packagedElement> + <packagedElement xmi:type="uml:Package" xmi:id="_YbdjIK31Eeab8Ykik38t7Q" name="nested"/> + <packagedElement xmi:type="uml:Enumeration" xmi:id="_7riE0McrEeaHJtEKGdWDxg" name="YesNo"> + <ownedLiteral xmi:id="_Agx8gMcsEeaHJtEKGdWDxg" name="no"/> + <ownedLiteral xmi:id="_Bc6NkMcsEeaHJtEKGdWDxg" name="yes"/> + <ownedLiteral xmi:id="_CGhyUMcsEeaHJtEKGdWDxg" name="maybe"/> + </packagedElement> + <packagedElement xmi:type="uml:Class" xmi:id="_EAtAAMcsEeaHJtEKGdWDxg" name="Passivity"/> + <profileApplication xmi:id="_usQngKapEeaVuqljGw-fqQ"> + <eAnnotations xmi:id="_usWHEKapEeaVuqljGw-fqQ" source="http://www.eclipse.org/uml2/2.0.0/UML"> + <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/papyrus/umlrt#/"/> + </eAnnotations> + <appliedProfile href="pathmap://UML_RT_PROFILE/uml-rt.profile.uml#_1h74oEeVEeO0lv5O1DTHOQ"/> + </profileApplication> + </uml:Model> + <UMLRealTime:Capsule xmi:id="_caZkQKaqEeaVuqljGw-fqQ" base_Class="_cUZp8KaqEeaVuqljGw-fqQ"/> + <UMLRealTime:Capsule xmi:id="_eOms0KaqEeaVuqljGw-fqQ" base_Class="_eOTK0KaqEeaVuqljGw-fqQ"/> + <UMLRealTime:Capsule xmi:id="_go3IwKaqEeaVuqljGw-fqQ" base_Class="_golb8KaqEeaVuqljGw-fqQ"/> + <UMLRealTime:RTPort xmi:id="_uFo28KaqEeaVuqljGw-fqQ" base_Port="_uFmasKaqEeaVuqljGw-fqQ"/> + <UMLRealTime:ProtocolContainer xmi:id="_ufdFIKaqEeaVuqljGw-fqQ" base_Package="_ufb3AKaqEeaVuqljGw-fqQ"/> + <UMLRealTime:RTMessageSet xmi:id="_uffhYKaqEeaVuqljGw-fqQ" base_Interface="_ufeTQKaqEeaVuqljGw-fqQ"/> + <UMLRealTime:RTMessageSet xmi:id="_ufh9oKaqEeaVuqljGw-fqQ" base_Interface="_ufhWkKaqEeaVuqljGw-fqQ" rtMsgKind="out"/> + <UMLRealTime:RTMessageSet xmi:id="_ufloAKaqEeaVuqljGw-fqQ" base_Interface="_ufkZ4KaqEeaVuqljGw-fqQ" rtMsgKind="inOut"/> + <UMLRealTime:Protocol xmi:id="_ufndMKaqEeaVuqljGw-fqQ" base_Collaboration="_ufaB0KaqEeaVuqljGw-fqQ"/> + <UMLRealTime:RTPort xmi:id="_0JRNUKaqEeaVuqljGw-fqQ" base_Port="_0JPYIKaqEeaVuqljGw-fqQ"/> + <UMLRealTime:ProtocolContainer xmi:id="_0iBrkKaqEeaVuqljGw-fqQ" base_Package="_0iAdcKaqEeaVuqljGw-fqQ"/> + <UMLRealTime:RTMessageSet xmi:id="_0iDgwKaqEeaVuqljGw-fqQ" base_Interface="_0iCSoKaqEeaVuqljGw-fqQ"/> + <UMLRealTime:RTMessageSet xmi:id="_0iF9AKaqEeaVuqljGw-fqQ" base_Interface="_0iEu4KaqEeaVuqljGw-fqQ" rtMsgKind="out"/> + <UMLRealTime:RTMessageSet xmi:id="_0iIZQKaqEeaVuqljGw-fqQ" base_Interface="_0iHyMKaqEeaVuqljGw-fqQ" rtMsgKind="inOut"/> + <UMLRealTime:Protocol xmi:id="_0i080aaqEeaVuqljGw-fqQ" base_Collaboration="_0h-oQKaqEeaVuqljGw-fqQ"/> + <UMLRealTime:RTPort xmi:id="_AZdMkKarEeaVuqljGw-fqQ" base_Port="_AZbXYKarEeaVuqljGw-fqQ"/> + <UMLRealTime:RTPort xmi:id="_AZdMkaarEeaVuqljGw-fqQ" base_Port="_AZbXYaarEeaVuqljGw-fqQ"/> + <UMLRealTime:RTPort xmi:id="_QxE7QqarEeaVuqljGw-fqQ" base_Port="_QxE7QKarEeaVuqljGw-fqQ"/> + <UMLRealTime:RTPort xmi:id="_QxE7Q6arEeaVuqljGw-fqQ" base_Port="_QxE7QaarEeaVuqljGw-fqQ"/> + <UMLRealTime:RTRedefinedElement xmi:id="_4_EpMKarEeaVuqljGw-fqQ" base_RedefinableElement="_AZbXYKarEeaVuqljGw-fqQ" rootFragment="_uFmasKaqEeaVuqljGw-fqQ"/> + <UMLRealTime:RTRedefinedElement xmi:id="_6Np8MKarEeaVuqljGw-fqQ" base_RedefinableElement="_AZbXYaarEeaVuqljGw-fqQ" rootFragment="_0JPYIKaqEeaVuqljGw-fqQ"/> + <UMLRealTime:RTRedefinedElement xmi:id="_8HImUKarEeaVuqljGw-fqQ" base_RedefinableElement="_QxE7QKarEeaVuqljGw-fqQ" rootFragment="_uFmasKaqEeaVuqljGw-fqQ"/> + <UMLRealTime:RTRedefinedElement xmi:id="_98Q78KarEeaVuqljGw-fqQ" base_RedefinableElement="_QxE7QaarEeaVuqljGw-fqQ" rootFragment="_0JPYIKaqEeaVuqljGw-fqQ"/> +</xmi:XMI> diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/no_inheritance.di b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/no_inheritance.di new file mode 100644 index 000000000..bf9abab34 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/no_inheritance.di @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/> diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/no_inheritance.notation b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/no_inheritance.notation new file mode 100644 index 000000000..7b03b1ac5 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/no_inheritance.notation @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:configuration="http://www.eclipse.org/papyrus/infra/viewpoints/configuration" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/viewpoints/policy/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML"> + <notation:Diagram xmi:id="_S0VTkMIiEeay5fvLrgBZSQ" type="CompositeStructure" measurementUnit="Pixel"> + <children xmi:type="notation:Shape" xmi:id="_S0XIwMIiEeay5fvLrgBZSQ" type="Class_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_S0ZlAMIiEeay5fvLrgBZSQ" type="Class_NameLabel"/> + <children xmi:type="notation:DecorationNode" xmi:id="_S0ZlAcIiEeay5fvLrgBZSQ" type="Class_FloatingNameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_S0ZlAsIiEeay5fvLrgBZSQ" y="5"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_S0aMEMIiEeay5fvLrgBZSQ" type="Class_StructureCompartment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_S0aMEcIiEeay5fvLrgBZSQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_S0aMEsIiEeay5fvLrgBZSQ"/> + </children> + <element xmi:type="uml:Class" href="no_inheritance.uml#_SxHngMIiEeay5fvLrgBZSQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_S0XIwcIiEeay5fvLrgBZSQ" x="40" y="40" width="500" height="250"/> + </children> + <styles xmi:type="notation:StringValueStyle" xmi:id="_S0VTkcIiEeay5fvLrgBZSQ" name="diagram_compatibility_version" stringValue="1.2.0"/> + <styles xmi:type="notation:DiagramStyle" xmi:id="_S0VTksIiEeay5fvLrgBZSQ"/> + <styles xmi:type="style:PapyrusViewStyle" xmi:id="_S0VTk8IiEeay5fvLrgBZSQ"> + <owner xmi:type="uml:Class" href="no_inheritance.uml#_SxHngMIiEeay5fvLrgBZSQ"/> + <configuration xmi:type="configuration:PapyrusDiagram" href="platform:/plugin/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/configuration/UMLRT.configuration#_Z79eQHcZEeSnWeKqQOfW2A"/> + </styles> + <element xmi:type="uml:Class" href="no_inheritance.uml#_SxHngMIiEeay5fvLrgBZSQ"/> + </notation:Diagram> + <notation:Diagram xmi:id="_TeMI4MIiEeay5fvLrgBZSQ" type="CompositeStructure" measurementUnit="Pixel"> + <children xmi:type="notation:Shape" xmi:id="_TeMv8MIiEeay5fvLrgBZSQ" type="Class_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_TeMv8sIiEeay5fvLrgBZSQ" type="Class_NameLabel"/> + <children xmi:type="notation:DecorationNode" xmi:id="_TeMv88IiEeay5fvLrgBZSQ" type="Class_FloatingNameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_TeMv9MIiEeay5fvLrgBZSQ" y="5"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_TeMv9cIiEeay5fvLrgBZSQ" type="Class_StructureCompartment"> + <styles xmi:type="notation:TitleStyle" xmi:id="_TeMv9sIiEeay5fvLrgBZSQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_TeMv98IiEeay5fvLrgBZSQ"/> + </children> + <element xmi:type="uml:Class" href="no_inheritance.uml#_Td9fYMIiEeay5fvLrgBZSQ"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_TeMv8cIiEeay5fvLrgBZSQ" x="40" y="40" width="500" height="250"/> + </children> + <styles xmi:type="notation:StringValueStyle" xmi:id="_TeMI4cIiEeay5fvLrgBZSQ" name="diagram_compatibility_version" stringValue="1.2.0"/> + <styles xmi:type="notation:DiagramStyle" xmi:id="_TeMI4sIiEeay5fvLrgBZSQ"/> + <styles xmi:type="style:PapyrusViewStyle" xmi:id="_TeMI48IiEeay5fvLrgBZSQ"> + <owner xmi:type="uml:Class" href="no_inheritance.uml#_Td9fYMIiEeay5fvLrgBZSQ"/> + <configuration xmi:type="configuration:PapyrusDiagram" href="platform:/plugin/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/configuration/UMLRT.configuration#_Z79eQHcZEeSnWeKqQOfW2A"/> + </styles> + <element xmi:type="uml:Class" href="no_inheritance.uml#_Td9fYMIiEeay5fvLrgBZSQ"/> + </notation:Diagram> +</xmi:XMI> diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/no_inheritance.uml b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/no_inheritance.uml new file mode 100644 index 000000000..eafde987f --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/resources/no_inheritance.uml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:UMLRealTime="http://www.eclipse.org/papyrus/umlrt" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML"> + <uml:Model xmi:id="_R9PTgMIiEeay5fvLrgBZSQ" name="no_inheritance"> + <packagedElement xmi:type="uml:Class" xmi:id="_SxHngMIiEeay5fvLrgBZSQ" name="Capsule1" isActive="true"> + <ownedAttribute xmi:type="uml:Port" xmi:id="_UXZBwMIiEeay5fvLrgBZSQ" name="protocol1" visibility="public" type="_Uozh4MIiEeay5fvLrgBZSQ" isOrdered="true" aggregation="composite" isBehavior="true"/> + </packagedElement> + <packagedElement xmi:type="uml:Class" xmi:id="_Td9fYMIiEeay5fvLrgBZSQ" name="Capsule2" isActive="true"> + <ownedAttribute xmi:type="uml:Property" xmi:id="_VqmWEMIiEeay5fvLrgBZSQ" name="capsule1" visibility="protected" type="_SxHngMIiEeay5fvLrgBZSQ" isOrdered="true" aggregation="composite"/> + </packagedElement> + <packagedElement xmi:type="uml:Package" xmi:id="_Uo3zUMIiEeay5fvLrgBZSQ" name="Protocol1"> + <packagedElement xmi:type="uml:Collaboration" xmi:id="_Uozh4MIiEeay5fvLrgBZSQ" name="Protocol1"> + <interfaceRealization xmi:type="uml:InterfaceRealization" xmi:id="_Uo-hAMIiEeay5fvLrgBZSQ" client="_Uozh4MIiEeay5fvLrgBZSQ" supplier="_Uo8EwMIiEeay5fvLrgBZSQ" contract="_Uo8EwMIiEeay5fvLrgBZSQ"/> + <interfaceRealization xmi:type="uml:InterfaceRealization" xmi:id="_UpGc0MIiEeay5fvLrgBZSQ" client="_Uozh4MIiEeay5fvLrgBZSQ" supplier="_UpEnoMIiEeay5fvLrgBZSQ" contract="_UpEnoMIiEeay5fvLrgBZSQ"/> + </packagedElement> + <packagedElement xmi:type="uml:Interface" xmi:id="_Uo8EwMIiEeay5fvLrgBZSQ" name="Protocol1"/> + <packagedElement xmi:type="uml:Interface" xmi:id="_UpAWMMIiEeay5fvLrgBZSQ" name="Protocol1~"/> + <packagedElement xmi:type="uml:Usage" xmi:id="_UpCycMIiEeay5fvLrgBZSQ" client="_Uozh4MIiEeay5fvLrgBZSQ" supplier="_UpAWMMIiEeay5fvLrgBZSQ"/> + <packagedElement xmi:type="uml:AnyReceiveEvent" xmi:id="_UpEAkMIiEeay5fvLrgBZSQ" name="*"/> + <packagedElement xmi:type="uml:Interface" xmi:id="_UpEnoMIiEeay5fvLrgBZSQ" name="Protocol1IO"/> + <packagedElement xmi:type="uml:Usage" xmi:id="_UpHq8MIiEeay5fvLrgBZSQ" client="_Uozh4MIiEeay5fvLrgBZSQ" supplier="_UpEnoMIiEeay5fvLrgBZSQ"/> + </packagedElement> + <profileApplication xmi:type="uml:ProfileApplication" xmi:id="_R9o8IMIiEeay5fvLrgBZSQ"> + <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_R9qKQMIiEeay5fvLrgBZSQ" source="http://www.eclipse.org/uml2/2.0.0/UML"> + <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/papyrus/umlrt#/"/> + </eAnnotations> + <appliedProfile xmi:type="uml:Profile" href="pathmap://UML_RT_PROFILE/uml-rt.profile.uml#_1h74oEeVEeO0lv5O1DTHOQ"/> + </profileApplication> + </uml:Model> + <UMLRealTime:Capsule xmi:id="_S0dPYMIiEeay5fvLrgBZSQ" base_Class="_SxHngMIiEeay5fvLrgBZSQ"/> + <UMLRealTime:Capsule xmi:id="_TeNXAMIiEeay5fvLrgBZSQ" base_Class="_Td9fYMIiEeay5fvLrgBZSQ"/> + <UMLRealTime:RTPort xmi:id="_UXsjwMIiEeay5fvLrgBZSQ" base_Port="_UXZBwMIiEeay5fvLrgBZSQ"/> + <UMLRealTime:ProtocolContainer xmi:id="_Uo5ogMIiEeay5fvLrgBZSQ" base_Package="_Uo3zUMIiEeay5fvLrgBZSQ"/> + <UMLRealTime:RTMessageSet xmi:id="_Uo9S4MIiEeay5fvLrgBZSQ" base_Interface="_Uo8EwMIiEeay5fvLrgBZSQ"/> + <UMLRealTime:RTMessageSet xmi:id="_UpBkUMIiEeay5fvLrgBZSQ" base_Interface="_UpAWMMIiEeay5fvLrgBZSQ" rtMsgKind="out"/> + <UMLRealTime:RTMessageSet xmi:id="_UpFOsMIiEeay5fvLrgBZSQ" base_Interface="_UpEnoMIiEeay5fvLrgBZSQ" rtMsgKind="inOut"/> + <UMLRealTime:Protocol xmi:id="_UpISAMIiEeay5fvLrgBZSQ" base_Collaboration="_Uozh4MIiEeay5fvLrgBZSQ"/> + <UMLRealTime:CapsulePart xmi:id="_VqtDwMIiEeay5fvLrgBZSQ" base_Property="_VqmWEMIiEeay5fvLrgBZSQ"/> +</xmi:XMI> diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicCapsulePartInheritanceTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicCapsulePartInheritanceTest.java new file mode 100644 index 000000000..d3d6a08b4 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicCapsulePartInheritanceTest.java @@ -0,0 +1,82 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static org.eclipse.papyrusrt.umlrt.uml.tests.util.UMLMatchers.named; +import static org.eclipse.papyrusrt.umlrt.uml.tests.util.UMLMatchers.replicated; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.NoFacade; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.VisibilityKind; +import org.junit.ClassRule; +import org.junit.Test; + +/** + * Test cases for inheritance of basic capsule-part features. + */ +@TestModel("inheritance/parts.uml") +@NoFacade +public class BasicCapsulePartInheritanceTest { + + @ClassRule + public static final ModelFixture fixture = new ModelFixture(); + + public BasicCapsulePartInheritanceTest() { + super(); + } + + @Test + public void typeInheritance() { + Class subsub = fixture.getElement("Subsubcapsule"); + Property p1 = subsub.getOwnedAttributes().get(0); + Property p2 = subsub.getOwnedAttributes().get(1); + + assertThat(p1.getType(), named("Capsule2")); + assertThat(p2.getType(), named("Capsule4")); + } + + @Test + public void nameInheritance() { + Class subsub = fixture.getElement("Subsubcapsule"); + Property p1 = subsub.getOwnedAttributes().get(0); + Property p2 = subsub.getOwnedAttributes().get(1); + + assertThat(p1, named("capsule2")); + assertThat(p2, named("subpart")); + } + + @Test + public void visibilityInheritance() { + Class subsub = fixture.getElement("Subsubcapsule"); + Property p1 = subsub.getOwnedAttributes().get(0); + + assertThat(p1.getVisibility(), is(VisibilityKind.PROTECTED_LITERAL)); + assertThat(p1.isSetVisibility(), is(false)); + } + + @Test + public void replicationInheritance() { + Class subsub = fixture.getElement("Subsubcapsule"); + Property p1 = subsub.getOwnedAttributes().get(0); + Property p2 = subsub.getOwnedAttributes().get(1); + + assertThat(p1, replicated(1)); + assertThat(p2, replicated(4, 6)); + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicConnectorInheritanceTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicConnectorInheritanceTest.java new file mode 100644 index 000000000..62ac9ceb6 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicConnectorInheritanceTest.java @@ -0,0 +1,210 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static org.hamcrest.CoreMatchers.anything; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assume.assumeThat; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.util.EList; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsulePart; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.NoFacade; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.papyrusrt.umlrt.uml.util.UMLRTExtensionUtil; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Connector; +import org.eclipse.uml2.uml.ConnectorEnd; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.VisibilityKind; +import org.junit.Rule; +import org.junit.Test; + +/** + * Test cases for the port façade class {@link UMLRTCapsulePart}. + */ +@TestModel("inheritance/connectors.uml") +@NoFacade +public class BasicConnectorInheritanceTest { + + @Rule + public final ModelFixture fixture = new ModelFixture(); + + public BasicConnectorInheritanceTest() { + super(); + } + + @Test + public void connectorInherited() { + Class capsule = fixture.getElement("RootCapsule"); + Class subcapsule = fixture.getElement("Subcapsule"); + Class nested = fixture.getElement("NestedCapsule"); + + Connector connector = (Connector) subcapsule.getOwnedMember("connector1"); + assertThat(connector, notNullValue()); + assertThat(UMLRTExtensionUtil.isVirtualElement(connector), is(true)); + assertThat(connector.getOwner(), is(subcapsule)); + + Connector redefined = connector.getRedefinedConnector("connector1"); + assertThat(connector, notNullValue()); + assertThat(redefined.getOwner(), is(capsule)); + + EList<ConnectorEnd> ends = connector.getEnds(); + assertThat(ends.size(), is(2)); + ConnectorEnd end1 = ends.get(0); + ConnectorEnd end2 = ends.get(1); + + assertThat(end1.eIsSet(UMLPackage.Literals.CONNECTOR_END__ROLE), is(false)); + assertThat(end1.eIsSet(UMLPackage.Literals.CONNECTOR_END__PART_WITH_PORT), is(false)); + assertThat(end1.eIsSet(UMLPackage.Literals.MULTIPLICITY_ELEMENT__LOWER_VALUE), is(false)); + assertThat(end1.eIsSet(UMLPackage.Literals.MULTIPLICITY_ELEMENT__UPPER_VALUE), is(false)); + assertThat(end2.eIsSet(UMLPackage.Literals.CONNECTOR_END__ROLE), is(false)); + assertThat(end2.eIsSet(UMLPackage.Literals.CONNECTOR_END__PART_WITH_PORT), is(false)); + assertThat(end2.eIsSet(UMLPackage.Literals.MULTIPLICITY_ELEMENT__LOWER_VALUE), is(false)); + assertThat(end2.eIsSet(UMLPackage.Literals.MULTIPLICITY_ELEMENT__UPPER_VALUE), is(false)); + + assertThat(end1.getRole(), is(capsule.getOwnedPort("protocol1", null))); + assertThat(end1.getPartWithPort(), nullValue()); + assertThat(end2.getRole(), is(nested.getOwnedPort("protocol1", null))); + assertThat(end2.getPartWithPort(), is(capsule.getOwnedAttribute("nestedCapsule", null))); + } + + @Test + public void nameInheritance() { + Class capsule = fixture.getElement("RootCapsule"); + Class subcapsule = fixture.getElement("Subcapsule"); + + Connector connector = (Connector) subcapsule.getOwnedMember("connector1"); + Connector redefined = capsule.getOwnedConnector("connector1"); + + String oldName = redefined.getName(); + assertThat(connector.getName(), is(oldName)); + + fixture.expectNotification(connector, UMLPackage.Literals.NAMED_ELEMENT__NAME, Notification.SET, is(oldName), is("foo"), () -> { + redefined.setName("foo"); + assertThat(connector.getName(), is("foo")); + }); + } + + @Test + public void visibilityInheritance() { + Class capsule = fixture.getElement("RootCapsule"); + Class subcapsule = fixture.getElement("Subcapsule"); + + Connector connector = (Connector) subcapsule.getOwnedMember("connector1"); + Connector redefined = capsule.getOwnedConnector("connector1"); + + VisibilityKind oldVis = redefined.getVisibility(); + assertThat(connector.getVisibility(), is(oldVis)); + + fixture.expectNotification(connector, UMLPackage.Literals.NAMED_ELEMENT__VISIBILITY, Notification.SET, is(oldVis), is(VisibilityKind.PACKAGE_LITERAL), () -> { + redefined.setVisibility(VisibilityKind.PACKAGE_LITERAL); + assertThat(connector.getVisibility(), is(VisibilityKind.PACKAGE_LITERAL)); + }); + } + + @Test + public void roleInheritance() { + Class capsule = fixture.getElement("RootCapsule"); + Class subcapsule = fixture.getElement("Subcapsule"); + + Connector connector = (Connector) subcapsule.getOwnedMember("connector1"); + Connector redefined = capsule.getOwnedConnector("connector1"); + + Port port1 = capsule.getOwnedPort("protocol1", null); + assumeThat(port1, notNullValue()); + Port port2 = capsule.getOwnedPort("protocol2", null); + assumeThat(port2, notNullValue()); + + ConnectorEnd end1 = connector.getEnds().get(0); + ConnectorEnd redefEnd = redefined.getEnds().get(0); + + assumeThat(end1.getRole(), is(port1)); + + fixture.expectNotification(end1, UMLPackage.Literals.CONNECTOR_END__ROLE, Notification.SET, is(port1), is(port2), () -> { + redefEnd.setRole(port2); + assertThat(end1.getRole(), is(port2)); + }); + } + + @Test + public void partWithPortInheritance() { + Class capsule = fixture.getElement("RootCapsule"); + Class subcapsule = fixture.getElement("Subcapsule"); + + Connector connector = (Connector) subcapsule.getOwnedMember("connector1"); + Connector redefined = capsule.getOwnedConnector("connector1"); + + Property nested = capsule.getOwnedAttribute("nestedCapsule", null); + assumeThat(nested, notNullValue()); + Property part2 = capsule.createOwnedAttribute("part2", nested.getType()); + + ConnectorEnd end2 = connector.getEnds().get(1); + ConnectorEnd redefEnd = redefined.getEnds().get(1); + + assumeThat(end2.getPartWithPort(), is(nested)); + + fixture.expectNotification(end2, UMLPackage.Literals.CONNECTOR_END__PART_WITH_PORT, Notification.SET, is(nested), is(part2), () -> { + redefEnd.setPartWithPort(part2); + assertThat(end2.getPartWithPort(), is(part2)); + }); + } + + @Test + public void lowerBoundInheritance() { + Class capsule = fixture.getElement("RootCapsule"); + Class subcapsule = fixture.getElement("Subcapsule"); + + Connector connector = (Connector) subcapsule.getOwnedMember("connector1"); + Connector redefined = capsule.getOwnedConnector("connector1"); + + ConnectorEnd end1 = connector.getEnds().get(0); + ConnectorEnd redefEnd = redefined.getEnds().get(0); + redefEnd.setLower(1); + + int oldBound = redefEnd.getLower(); + assumeThat(end1.getLower(), is(oldBound)); + + fixture.expectNotification(end1.getLowerValue(), UMLPackage.Literals.LITERAL_INTEGER__VALUE, Notification.SET, is(oldBound), is(0), () -> { + redefEnd.setLower(0); + assertThat(end1.getLower(), is(0)); + }); + } + + @Test + public void upperBoundInheritance() { + Class capsule = fixture.getElement("RootCapsule"); + Class subcapsule = fixture.getElement("Subcapsule"); + + Connector connector = (Connector) subcapsule.getOwnedMember("connector1"); + Connector redefined = capsule.getOwnedConnector("connector1"); + + ConnectorEnd end1 = connector.getEnds().get(0); + ConnectorEnd redefEnd = redefined.getEnds().get(0); + redefEnd.setUpper(1); + + assumeThat(end1.getUpper(), is(redefEnd.getUpper())); + + fixture.expectNotification(end1.getUpperValue(), UMLPackage.Literals.LITERAL_UNLIMITED_NATURAL__VALUE, Notification.SET, anything(), is(7), () -> { + redefEnd.setUpper(7); + assertThat(end1.getUpper(), is(7)); + }); + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicElementCreationTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicElementCreationTest.java new file mode 100644 index 000000000..759ab8806 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicElementCreationTest.java @@ -0,0 +1,80 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.NoFacade; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Connector; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.UMLPackage; +import org.junit.Rule; +import org.junit.Test; + +/** + * Test cases for basic element creation. + */ +@TestModel("inheritance/ports.uml") +@NoFacade +public class BasicElementCreationTest { + + @Rule + public final ModelFixture fixture = new ModelFixture(); + + public BasicElementCreationTest() { + super(); + } + + @Test + public void createCapsule() { + Class newCapsule = fixture.getModel().createOwnedClass("NewCapsule", false); + assertThat(newCapsule, instanceOf(InternalUMLRTElement.class)); + } + + @Test + public void createCapsuleAsOwnedType() { + Class newCapsule = (Class) fixture.getModel().createOwnedType("NewCapsule", UMLPackage.Literals.CLASS); + assertThat(newCapsule, instanceOf(InternalUMLRTElement.class)); + } + + @Test + public void createPort() { + Class capsule = fixture.getElement("RootCapsule"); + Port newPort = capsule.createOwnedPort("newPort", null); + assertThat(newPort, instanceOf(InternalUMLRTElement.class)); + } + + @Test + public void createPart() { + Class capsule = fixture.getElement("RootCapsule"); + Property newPart = capsule.createOwnedAttribute("sub", fixture.getElement("Subcapsule")); + assertThat(newPart, instanceOf(InternalUMLRTElement.class)); + } + + @Test + public void createConnector() { + Class capsule = fixture.getElement("RootCapsule"); + Connector newConnector = capsule.createOwnedConnector(null); + assertThat(newConnector, instanceOf(InternalUMLRTElement.class)); + + assertThat(newConnector.createEnd(), instanceOf(InternalUMLRTElement.class)); + } + +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicExclusionTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicExclusionTest.java new file mode 100644 index 000000000..07b4815eb --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicExclusionTest.java @@ -0,0 +1,191 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static org.eclipse.papyrusrt.umlrt.uml.tests.util.UMLMatchers.stereotypedAs; +import static org.hamcrest.CoreMatchers.anything; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assume.assumeThat; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTRedefinedElement; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTNamedElement; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPort; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.uml2.uml.NamedElement; +import org.eclipse.uml2.uml.RedefinableElement; +import org.eclipse.uml2.uml.util.UMLUtil; +import org.junit.Rule; +import org.junit.Test; + +/** + * Basic test cases for exclusion. + */ +@TestModel("inheritance/ports.uml") +public class BasicExclusionTest { + + @Rule + public final ModelFixture fixture = new ModelFixture(); + + public BasicExclusionTest() { + super(); + } + + @Test + public void portNotExcluded() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + UMLRTPort rootPort = capsule.getPorts().get(0); + UMLRTCapsule subcapsule = capsule.getSubclasses().get(0); + UMLRTPort subPort = subcapsule.getPort(rootPort.getName()); + UMLRTCapsule subsubcapsule = subcapsule.getSubclasses().get(0); + UMLRTPort subsubPort = subsubcapsule.getPort(rootPort.getName()); + + assertThat(rootPort.isExcluded(), is(false)); + assertThat(subPort.isExcluded(), is(false)); + assertThat(subsubPort.isExcluded(), is(false)); + } + + @Test + public void excludePort() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + UMLRTPort rootPort = capsule.getPorts().get(0); + UMLRTCapsule subcapsule = capsule.getSubclasses().get(0); + UMLRTPort subPort = subcapsule.getPort(rootPort.getName()); + UMLRTCapsule subsubcapsule = subcapsule.getSubclasses().get(0); + UMLRTPort subsubPort = subsubcapsule.getPort(rootPort.getName()); + + assumeThat(subPort.isExcluded(), is(false)); + assumeThat(subsubPort.isExcluded(), is(false)); + + assertThat(subPort.exclude(), is(true)); + assertThat(getRootFragment(subPort), nullValue()); + assertThat(subPort.exclude(), is(false)); // No effect a second time + assertThat(subPort.isExcluded(), is(true)); + + // Doesn't affect further redefinitions (they are not recursively excluded) + assertThat(subsubPort.isExcluded(), is(false)); + + // But, of course, they can be excluded, too + assertThat(subsubPort.exclude(), is(true)); + assertThat(getRootFragment(subsubPort), nullValue()); + assertThat(subsubPort.isExcluded(), is(true)); + } + + @Test + public void reinheritPort() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + UMLRTPort rootPort = capsule.getPorts().get(0); + UMLRTCapsule subcapsule = capsule.getSubclasses().get(0); + UMLRTPort subPort = subcapsule.getPort(rootPort.getName()); + UMLRTCapsule subsubcapsule = subcapsule.getSubclasses().get(0); + UMLRTPort subsubPort = subsubcapsule.getPort(rootPort.getName()); + + assumeThat(subsubPort.exclude(), is(true)); + assumeThat(subPort.exclude(), is(true)); + + assertThat(subPort.reinherit(), is(true)); + assertThat(subPort.toUML(), not(stereotypedAs("UMLRealTime::RTRedefinedElement"))); + assertThat(subPort.reinherit(), is(false)); // No effect a second time + assertThat(subPort.isExcluded(), is(false)); + + // Doesn't affect further redefinitions (they are not recursively reinherited) + assertThat(subsubPort.isExcluded(), is(true)); + + // But, of course, they can be reinherited, too + assertThat(subsubPort.reinherit(), is(true)); + assertThat(subsubPort.toUML(), not(stereotypedAs("UMLRealTime::RTRedefinedElement"))); + assertThat(subsubPort.isExcluded(), is(false)); + } + + @Test + public void excludedMembers() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + UMLRTPort rootPort = capsule.getPorts().get(0); + UMLRTCapsule subcapsule = capsule.getSubclasses().get(0); + UMLRTPort subPort = subcapsule.getPort(rootPort.getName()); + UMLRTCapsule subsubcapsule = subcapsule.getSubclasses().get(0); + UMLRTPort subsubPort = subsubcapsule.getPort(rootPort.getName()); + + assumeThat(subPort.exclude(), is(true)); + + assertThat(subcapsule.getPorts(), not(hasItem(subPort))); + assertThat(subcapsule.getPorts().stream().filter(p -> p.redefines(rootPort)).count(), is(0L)); + assertThat(subcapsule.getExcludedElements(), hasItem(subPort)); + assertThat(subcapsule.getExcludedElement("protocol1", UMLRTPort.class), is(subPort)); + + // Doesn't affect further redefinitions (they are not recursively reinherited) + assertThat(subsubcapsule.getPorts(), hasItem(subsubPort)); + assertThat(subsubcapsule.getPorts().stream().filter(p -> p.redefines(rootPort)).count(), is(1L)); + assertThat(subsubcapsule.getExcludedElements(), not(hasItem(subsubPort))); + + // But, of course, they can be excluded, too + subsubPort.exclude(); + assertThat(subsubcapsule.getPorts(), not(hasItem(subsubPort))); + assertThat(subsubcapsule.getPorts().stream().filter(p -> p.redefines(rootPort)).count(), is(0L)); + assertThat(subsubcapsule.getExcludedElements(), hasItem(subsubPort)); + assertThat(subsubcapsule.getExcludedElement("protocol1", UMLRTPort.class), is(subsubPort)); + + // But, they are still there + assertThat(subcapsule.getPort(rootPort.getName()), is(subPort)); + assertThat(subsubcapsule.getPort(rootPort.getName()), is(subsubPort)); + } + + @Test + public void exclusionNotifications() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule subcapsule = root.getCapsule("Subcapsule"); + UMLRTPort port = subcapsule.getPort("protocol1"); + + fixture.expectNotification(subcapsule.toUML(), + ExtUMLExtPackage.Literals.NAMESPACE__EXCLUDED_MEMBER, + Notification.ADD, + anything(), is(port.toUML()), + port::exclude); + + fixture.expectNotification(subcapsule.toUML(), + ExtUMLExtPackage.Literals.NAMESPACE__EXCLUDED_MEMBER, + Notification.REMOVE, + is(port.toUML()), anything(), + port::reinherit); + } + + // + // Test framework + // + + RedefinableElement getRootFragment(UMLRTNamedElement element) { + NamedElement uml = element.toUML(); + return (uml instanceof RedefinableElement) + ? getRootFragment((RedefinableElement) uml) + : null; + } + + RedefinableElement getRootFragment(RedefinableElement element) { + RTRedefinedElement rtRedef = UMLUtil.getStereotypeApplication(element, RTRedefinedElement.class); + return (rtRedef == null) ? null : rtRedef.getRootFragment(); + } + +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicImplicitMembersTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicImplicitMembersTest.java new file mode 100644 index 000000000..65a2bf299 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicImplicitMembersTest.java @@ -0,0 +1,311 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static org.hamcrest.CoreMatchers.anything; +import static org.hamcrest.CoreMatchers.everyItem; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeThat; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.common.notify.impl.AdapterImpl; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocol; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.NoFacade; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Collaboration; +import org.eclipse.uml2.uml.Interface; +import org.eclipse.uml2.uml.Operation; +import org.eclipse.uml2.uml.PackageableElement; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.RedefinableElement; +import org.eclipse.uml2.uml.UMLPackage; +import org.junit.Rule; +import org.junit.Test; + +/** + * Basic test cases for the UML extension feature containing implicit members. + */ +@NoFacade +public class BasicImplicitMembersTest { + + @Rule + public final ModelFixture fixture = new ModelFixture(); + + public BasicImplicitMembersTest() { + super(); + } + + @Test + @TestModel("inheritance/ports.uml") + public void addImplicitPort() { + Class capsule = fixture.getElement("RootCapsule"); + + // Capture notifications of new ports added + List<Notifier> notifiers = new ArrayList<>(); + List<EStructuralFeature> features = new ArrayList<>(); + capsule.eAdapters().add(new AdapterImpl() { + @Override + public void notifyChanged(Notification msg) { + switch (msg.getEventType()) { + case Notification.ADD: + if (msg.getNewValue() instanceof Port) { + notifiers.add((Notifier) msg.getNotifier()); + features.add((EStructuralFeature) msg.getFeature()); + } + break; + } + } + }); + + @SuppressWarnings("unchecked") + EList<Port> implicitPorts = (EList<Port>) capsule.eGet(ExtUMLExtPackage.Literals.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT); + Port newPort = fixture.create(UMLPackage.Literals.PORT, "newPort"); + implicitPorts.add(newPort); + + assertThat(capsule.getOwnedPorts(), not(hasItem(newPort))); + assertThat(capsule.getOwnedMembers(), hasItem(newPort)); + assertThat(capsule.getOwnedElements(), hasItem(newPort)); + assertThat(newPort.getNamespace(), is(capsule)); + assertThat(newPort.getOwner(), is(capsule)); + + assertThat(capsule.eContents(), hasItem(newPort)); + assertThat(newPort.eContainer(), is(capsule)); + assertThat(((InternalEObject) newPort).eInternalContainer(), not(capsule)); + + // Because implicitPort is a derived subset of this + assertThat(newPort.eContainmentFeature(), is(ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE)); + + // Subset of implicit members + @SuppressWarnings("unchecked") + EList<RedefinableElement> implicitMembers = (EList<RedefinableElement>) capsule.eGet(ExtUMLExtPackage.Literals.NAMESPACE__IMPLICIT_MEMBER); + assertThat(implicitMembers, hasItem(newPort)); + + // And we got the expected notifications + assertThat(notifiers.size(), is(2)); + assertThat(notifiers, everyItem(is(capsule))); + assertThat(features.get(0), is(ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE)); + assertThat(features.get(1), is(ExtUMLExtPackage.Literals.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT)); + + // Finally, the implicit element is in a resource but not the model resource + assertThat(((InternalEObject) newPort).eInternalResource(), notNullValue()); + assertThat(((InternalEObject) newPort).eInternalResource(), not(fixture.getResource())); + } + + @Test + @TestModel("inheritance/ports.uml") + public void removeImplicitPort() { + Class capsule = fixture.getElement("RootCapsule"); + + @SuppressWarnings("unchecked") + EList<Port> implicitPorts = (EList<Port>) capsule.eGet(ExtUMLExtPackage.Literals.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT); + Port newPort = fixture.create(UMLPackage.Literals.PORT, "newPort"); + implicitPorts.add(newPort); + + assumeThat(capsule.getOwnedMembers(), hasItem(newPort)); + + newPort.destroy(); + + assertThat(capsule.getOwnedPorts(), not(hasItem(newPort))); + assertThat(capsule.eContents(), not(hasItem(newPort))); + assertThat(implicitPorts, not(hasItem(newPort))); + assertThat(newPort.eContainer(), nullValue()); + assertThat(newPort.eContainmentFeature(), nullValue()); + } + + @Test + @TestModel("inheritance/ports.uml") + public void reifyImplicitPort() { + Class capsule = fixture.getElement("RootCapsule"); + + @SuppressWarnings("unchecked") + EList<Port> implicitPorts = (EList<Port>) capsule.eGet(ExtUMLExtPackage.Literals.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT); + Port newPort = fixture.create(UMLPackage.Literals.PORT, "newPort"); + implicitPorts.add(newPort); + + assumeThat(capsule.getOwnedMembers(), hasItem(newPort)); + + capsule.getOwnedPorts().add(newPort); + + assertThat(capsule.getOwnedPorts(), hasItem(newPort)); + assertThat(capsule.eContents(), hasItem(newPort)); + assertThat(implicitPorts, not(hasItem(newPort))); + assertThat(newPort.eContainer(), is(capsule)); + assertThat(newPort.eContainmentFeature(), is(UMLPackage.Literals.STRUCTURED_CLASSIFIER__OWNED_ATTRIBUTE)); + assertThat(((InternalEObject) newPort).eInternalContainer(), is(capsule)); + } + + @Test + @TestModel("inheritance/parts.uml") + public void addImplicitCapsulePart() { + Class capsule = fixture.getElement("RootCapsule"); + + // Capture notifications of new parts added + List<Notifier> notifiers = new ArrayList<>(); + List<EStructuralFeature> features = new ArrayList<>(); + capsule.eAdapters().add(new AdapterImpl() { + @Override + public void notifyChanged(Notification msg) { + switch (msg.getEventType()) { + case Notification.ADD: + if (msg.getNewValue() instanceof Property) { + notifiers.add((Notifier) msg.getNotifier()); + features.add((EStructuralFeature) msg.getFeature()); + } + break; + } + } + }); + + @SuppressWarnings("unchecked") + EList<Property> implicitParts = (EList<Property>) capsule.eGet(ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE); + Property newPart = fixture.create(UMLPackage.Literals.PROPERTY, "newPart"); + implicitParts.add(newPart); + + assertThat(capsule.getOwnedAttributes(), not(hasItem(newPart))); + assertThat(capsule.getOwnedMembers(), hasItem(newPart)); + assertThat(capsule.getOwnedElements(), hasItem(newPart)); + assertThat(newPart.getNamespace(), is(capsule)); + assertThat(newPart.getOwner(), is(capsule)); + + assertThat(capsule.eContents(), hasItem(newPart)); + assertThat(newPart.eContainer(), is(capsule)); + assertThat(((InternalEObject) newPart).eInternalContainer(), not(capsule)); + assertThat(newPart.eContainmentFeature(), is(ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE)); + + // Subset of implicit members + @SuppressWarnings("unchecked") + EList<RedefinableElement> implicitMembers = (EList<RedefinableElement>) capsule.eGet(ExtUMLExtPackage.Literals.NAMESPACE__IMPLICIT_MEMBER); + assertThat(implicitMembers, hasItem(newPart)); + + // And we got the expected notifications + assertThat(notifiers.size(), is(1)); + assertThat(notifiers, everyItem(is(capsule))); + assertThat(features.get(0), is(ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE)); + + // Finally, the implicit element is in a resource but not the model resource + assertThat(((InternalEObject) newPart).eInternalResource(), notNullValue()); + assertThat(((InternalEObject) newPart).eInternalResource(), not(fixture.getResource())); + } + + @Test + @TestModel("inheritance/parts.uml") + public void removeImplicitCapsulePart() { + Class capsule = fixture.getElement("RootCapsule"); + + @SuppressWarnings("unchecked") + EList<Property> implicitParts = (EList<Property>) capsule.eGet(ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE); + Property newPart = fixture.create(UMLPackage.Literals.PROPERTY, "newPart"); + implicitParts.add(newPart); + + assumeThat(capsule.getOwnedMembers(), hasItem(newPart)); + + newPart.destroy(); + + assertThat(capsule.getOwnedAttributes(), not(hasItem(newPart))); + assertThat(capsule.eContents(), not(hasItem(newPart))); + assertThat(implicitParts, not(hasItem(newPart))); + assertThat(newPart.eContainer(), nullValue()); + assertThat(newPart.eContainmentFeature(), nullValue()); + } + + @Test + @TestModel("inheritance/parts.uml") + public void reifyImplicitCapsulePart() { + Class capsule = fixture.getElement("RootCapsule"); + + @SuppressWarnings("unchecked") + EList<Property> implicitParts = (EList<Property>) capsule.eGet(ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE); + Property newPart = fixture.create(UMLPackage.Literals.PROPERTY, "newPart"); + implicitParts.add(newPart); + + assumeThat(capsule.getOwnedMembers(), hasItem(newPart)); + + capsule.getOwnedAttributes().add(newPart); + + assertThat(capsule.getOwnedAttributes(), hasItem(newPart)); + assertThat(capsule.eContents(), hasItem(newPart)); + assertThat(implicitParts, not(hasItem(newPart))); + assertThat(newPart.eContainer(), is(capsule)); + assertThat(newPart.eContainmentFeature(), is(UMLPackage.Literals.STRUCTURED_CLASSIFIER__OWNED_ATTRIBUTE)); + assertThat(((InternalEObject) newPart).eInternalContainer(), is(capsule)); + } + + @Test + @TestModel("inheritance/ports.uml") + public void capsuleClassSanity() { + Class capsule = fixture.getElement("RootCapsule"); + + @SuppressWarnings("unchecked") + EList<Port> implicitPorts = (EList<Port>) capsule.eGet(ExtUMLExtPackage.Literals.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT); + Port newPort = fixture.create(UMLPackage.Literals.PORT, "newPort"); + implicitPorts.add(newPort); + + List<PackageableElement> imported = null; + try { + // Inherited operation + Port port = (Port) capsule.getOwnedMember("newPort"); + assertThat(port, is(newPort)); + + imported = capsule.getImportedMembers(); + } catch (Exception e) { + e.printStackTrace(); + fail("Computing imported members failed: " + e.getMessage()); + } + + assertThat(imported, not(hasItem(anything()))); + } + + @Test + @TestModel("inheritance/ports.uml") + @NoFacade(false) + public void protocolMessageInterfaceSanity() { + UMLRTProtocol protocol2 = UMLRTProtocol.getInstance(fixture.getElement("Protocol2::Protocol2", Collaboration.class)); + UMLRTProtocol protocol1 = protocol2.getPackage().getProtocol("Protocol1"); + protocol2.setSuperProtocol(protocol1); + + Interface interface_ = fixture.getElement("Protocol2::Protocol2", Interface.class); + + List<PackageableElement> imported = null; + try { + // Inherited operation + Operation greet = (Operation) interface_.getOwnedMember("greet"); + assertThat(greet, notNullValue()); + + imported = interface_.getImportedMembers(); + } catch (Exception e) { + e.printStackTrace(); + fail("Computing imported members failed: " + e.getMessage()); + } + + assertThat(imported, not(hasItem(anything()))); + } + +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicPortInheritanceTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicPortInheritanceTest.java new file mode 100644 index 000000000..4425af37f --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicPortInheritanceTest.java @@ -0,0 +1,176 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static org.eclipse.papyrusrt.umlrt.uml.tests.util.UMLMatchers.named; +import static org.eclipse.papyrusrt.umlrt.uml.tests.util.UMLMatchers.replicated; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assume.assumeThat; + +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.NoFacade; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.OpaqueExpression; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.VisibilityKind; +import org.junit.Rule; +import org.junit.Test; + +/** + * Test cases for inheritance of basic port features. + */ +@TestModel("inheritance/ports.uml") +@NoFacade +public class BasicPortInheritanceTest { + + @Rule + public final ModelFixture fixture = new ModelFixture(); + + public BasicPortInheritanceTest() { + super(); + } + + @Test + public void typeInheritance() { + Class subsub = fixture.getElement("Subsubcapsule"); + Port p1 = subsub.getOwnedPorts().get(0); + Port p2 = subsub.getOwnedPorts().get(1); + + assertThat(p1.getType(), named("Protocol1")); + assertThat(p2.getType(), named("Protocol1")); + } + + @Test + public void nameInheritance() { + Class subsub = fixture.getElement("Subsubcapsule"); + Port p1 = subsub.getOwnedPorts().get(0); + Port p2 = subsub.getOwnedPorts().get(1); + + assertThat(p1, named("protocol1")); + assertThat(p2, named("subport")); + } + + @Test + public void visibilityInheritance() { + Class subsub = fixture.getElement("Subsubcapsule"); + Port p1 = subsub.getOwnedPorts().get(0); + + assertThat(p1.getVisibility(), is(VisibilityKind.PUBLIC_LITERAL)); + assertThat(p1.isSetVisibility(), is(false)); + } + + @Test + public void replicationInheritance() { + Class subsub = fixture.getElement("Subsubcapsule"); + Port p1 = subsub.getOwnedPorts().get(0); + Port p2 = subsub.getOwnedPorts().get(1); + + assertThat(p1, replicated(1)); + // The bound-values aren't implicitly created if not needed + assertThat(p1.getLowerValue(), nullValue()); + assertThat(p1.getUpperValue(), nullValue()); + + assertThat(p2, replicated(4, 6)); + // The bound-values are implicitly created if needed + assertThat(p2.getLowerValue(), notNullValue()); + assertThat(p2.getUpperValue(), notNullValue()); + } + + @Test + public void replicationRedefined() { + Class capsule = fixture.getElement("RootCapsule"); + Port r1 = capsule.getOwnedPorts().get(0); + Port r2 = capsule.getOwnedPorts().get(1); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port p1 = subsub.getOwnedPorts().get(0); + Port p2 = subsub.getOwnedPorts().get(1); + + assumeThat(p1, replicated(1)); + assumeThat(p2, replicated(4, 6)); + + p1.setUpper(2); + p2.setUpper(10); + + assertThat(p1, replicated(1, 2)); + assertThat(p2, replicated(4, 10)); + + r1.setUpper(3); + r2.setUpper(8); + + // Redefinition is unaffected + assertThat(p1, replicated(1, 2)); + assertThat(p2, replicated(4, 10)); + } + + @Test + public void replicationRedefinedDifferentKindOfValue() { + Class capsule = fixture.getElement("RootCapsule"); + Port r1 = capsule.getOwnedPorts().get(0); + Port r2 = capsule.getOwnedPorts().get(1); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port p1 = subsub.getOwnedPorts().get(0); + Port p2 = subsub.getOwnedPorts().get(1); + + assumeThat(p1, replicated(1)); + assumeThat(p2, replicated(4, 6)); + + p1.createUpperValue(null, null, UMLPackage.Literals.OPAQUE_EXPRESSION); + ((OpaqueExpression) p1.getUpperValue()).getBodies().add("NUM_PORTS"); + p2.createUpperValue(null, null, UMLPackage.Literals.OPAQUE_EXPRESSION); + ((OpaqueExpression) p2.getUpperValue()).getBodies().add("MAX"); + + assertThat(p1, replicated(1, 1)); // OpaqueExpression derives as 1 + assertThat(p2, replicated(4, 1)); // OpaqueExpression derives as 1 + + r1.setUpper(3); + r2.setUpper(8); + + // Redefinition is unaffected + assertThat(p1, replicated(1, 1)); + assertThat(p2, replicated(4, 1)); + } + + @Test + public void serviceInheritance() { + Class subsub = fixture.getElement("Subsubcapsule"); + Port p1 = subsub.getOwnedPorts().get(0); + + assertThat(p1.isService(), is(true)); + } + + @Test + public void behaviorInheritance() { + Class subsub = fixture.getElement("Subsubcapsule"); + Port p1 = subsub.getOwnedPorts().get(0); + + assertThat(p1.isBehavior(), is(true)); + } + + @Test + public void conjugatedInheritance() { + Class subsub = fixture.getElement("Subsubcapsule"); + Port p1 = subsub.getOwnedPorts().get(0); + + // Not much of a test, admittedly + assertThat(p1.isConjugated(), is(false)); + assertThat(p1.eIsSet(UMLPackage.Literals.PORT__IS_CONJUGATED), is(false)); + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicProtocolInheritanceTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicProtocolInheritanceTest.java new file mode 100644 index 000000000..3c150093f --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/BasicProtocolInheritanceTest.java @@ -0,0 +1,151 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static org.eclipse.papyrusrt.umlrt.uml.util.UMLRTExtensionUtil.isRedefinition; +import static org.eclipse.papyrusrt.umlrt.uml.util.UMLRTExtensionUtil.isVirtualElement; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assume.assumeThat; + +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.NoFacade; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.uml2.uml.Collaboration; +import org.eclipse.uml2.uml.Interface; +import org.eclipse.uml2.uml.NamedElement; +import org.eclipse.uml2.uml.Operation; +import org.eclipse.uml2.uml.Parameter; +import org.eclipse.uml2.uml.Type; +import org.eclipse.uml2.uml.UMLPackage; +import org.junit.Rule; +import org.junit.Test; + +/** + * Test cases for the UML-RT protocol semantics of {@link Collaboration}. + */ +@TestModel("inheritance/ports.uml") +@NoFacade +public class BasicProtocolInheritanceTest { + + @Rule + public final ModelFixture fixture = new ModelFixture(); + + public BasicProtocolInheritanceTest() { + super(); + } + + @Test + public void inheritance() { + Collaboration protocol1 = getProtocol("Protocol1"); + Collaboration protocol2 = getProtocol("Protocol2"); + + protocol2.createGeneralization(protocol1); + + // Inherited messages + Operation greet = (Operation) getInMessageSet("Protocol2").getOwnedMember("greet"); + assertThat(greet, notNullValue()); + assertThat(isVirtualElement(greet), is(true)); + } + + @Test + public void newMessageInherited() { + Collaboration protocol1 = getProtocol("Protocol1"); + Collaboration protocol2 = getProtocol("Protocol2"); + + protocol2.createGeneralization(protocol1); + + getOutMessageSet("Protocol1").createOwnedOperation("ack", null, null); + Operation ack = (Operation) getOutMessageSet("Protocol2").getOwnedMember("ack"); + assertThat(ack, notNullValue()); + assertThat(isVirtualElement(ack), is(true)); + } + + @Test + public void messageRedefinition() { + Collaboration protocol1 = getProtocol("Protocol1"); + Collaboration protocol2 = getProtocol("Protocol2"); + + protocol2.createGeneralization(protocol1); + + Operation greet = (Operation) getInMessageSet("Protocol2").getOwnedMember("greet"); + assumeThat(greet, notNullValue()); + assumeThat(isVirtualElement(greet), is(true)); + + Parameter data = greet.getOwnedParameter("data", null); + assumeThat(data, notNullValue()); + assertThat(isVirtualElement(data), is(true)); + + Type oldType = data.getType(); + assumeThat(oldType, notNullValue()); + assertThat(data.eIsSet(UMLPackage.Literals.TYPED_ELEMENT__TYPE), is(false)); + + data.setType(protocol1); // Not really valid, but convenient + + assertThat(isVirtualElement(data), is(false)); + assertThat(isVirtualElement(greet), is(false)); + + assertThat(isRedefinition(data), is(true)); + assertThat(isRedefinition(greet), is(true)); + } + + @Test + public void messageReinheritance() { + Collaboration protocol1 = getProtocol("Protocol1"); + Collaboration protocol2 = getProtocol("Protocol2"); + + protocol2.createGeneralization(protocol1); + + Operation greet = (Operation) getInMessageSet("Protocol2").getOwnedMember("greet"); + assumeThat(greet, notNullValue()); + assumeThat(isVirtualElement(greet), is(true)); + + Parameter data = greet.getOwnedParameter("data", null); + assumeThat(data, notNullValue()); + + Type oldType = data.getType(); + assumeThat(oldType, notNullValue()); + + data.setType(protocol1); // Not really valid, but convenient + + assumeThat(isRedefinition(data), is(true)); + assumeThat(isRedefinition(greet), is(true)); + + ((InternalUMLRTElement) greet).rtReinherit(); + + assertThat(isVirtualElement(greet), is(true)); + assertThat(isVirtualElement(data), is(true)); + + assertThat(data.eIsSet(UMLPackage.Literals.TYPED_ELEMENT__TYPE), is(false)); + assertThat(data.getType(), is(oldType)); + } + + // + // Test framework + // + + Collaboration getProtocol(String name) { + return fixture.getElement(name + NamedElement.SEPARATOR + name, Collaboration.class); + } + + Interface getInMessageSet(String name) { + return fixture.getElement(name + NamedElement.SEPARATOR + name, Interface.class); + } + + Interface getOutMessageSet(String name) { + return fixture.getElement(name + NamedElement.SEPARATOR + name + "~", Interface.class); + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/CapsuleFacadeTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/CapsuleFacadeTest.java new file mode 100644 index 000000000..8cfe3fade --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/CapsuleFacadeTest.java @@ -0,0 +1,274 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static java.util.Collections.singletonList; +import static java.util.stream.Collectors.toList; +import static org.eclipse.papyrusrt.umlrt.uml.tests.util.UMLMatchers.stereotypedAs; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assume.assumeThat; + +import java.util.Arrays; +import java.util.List; + +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTRedefinedElement; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsulePart; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPort; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocol; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.papyrusrt.umlrt.uml.util.UMLRTExtensionUtil; +import org.eclipse.uml2.uml.util.UMLUtil; +import org.junit.Rule; +import org.junit.Test; + +/** + * Test cases for the capsule façade class {@link UMLRTCapsule}. + */ +public class CapsuleFacadeTest { + + @Rule + public final ModelFixture fixture = new ModelFixture(); + + public CapsuleFacadeTest() { + super(); + } + + @Test + @TestModel("inheritance/ports.uml") + public void getPorts() { + UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule")); + + List<UMLRTPort> ports = capsule.getPorts(); + assertThat(ports.size(), is(2)); + assertThat(ports.get(0).getName(), is("protocol1")); + assertThat(ports.get(1).getName(), is("protocol2")); + } + + @Test + @TestModel("inheritance/ports.uml") + public void inheritPorts() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = model.getCapsule("RootCapsule"); + + UMLRTCapsule newCapsule = model.createCapsule("NewCapsule"); + newCapsule.setSuperclass(capsule); + + // It has inherited the ports + List<UMLRTPort> ports = newCapsule.getPorts(); + assertThat(ports.size(), is(2)); + assertThat(ports.get(0).getName(), is("protocol1")); + assertThat(ports.get(1).getName(), is("protocol2")); + + // But they are implicit redefinitions + ports.stream().map(UMLRTPort::toUML).forEach(port -> { + // It isn't attached to the model + assertThat(((InternalEObject) port).eInternalResource(), not(fixture.getResource())); + + // It doesn't actually have the name set + assertThat(port.isSetName(), is(false)); + assertThat(port.getName(), notNullValue()); + }); + } + + @Test + @TestModel("inheritance/parts.uml") + public void getCapsuleParts() { + UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule")); + + List<UMLRTCapsulePart> parts = capsule.getCapsuleParts(); + assertThat(parts.size(), is(2)); + assertThat(parts.get(0).getName(), is("capsule2")); + assertThat(parts.get(1).getName(), is("capsule3")); + } + + @Test + @TestModel("inheritance/parts.uml") + public void inheritCapsuleParts() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = model.getCapsule("RootCapsule"); + + UMLRTCapsule newCapsule = model.createCapsule("NewCapsule"); + newCapsule.setSuperclass(capsule); + + // It has inherited the parts + List<UMLRTCapsulePart> parts = newCapsule.getCapsuleParts(); + assertThat(parts.size(), is(2)); + assertThat(parts.get(0).getName(), is("capsule2")); + assertThat(parts.get(1).getName(), is("capsule3")); + + // But they are implicit redefinitions + parts.stream().map(UMLRTCapsulePart::toUML).forEach(part -> { + // It isn't attached to the model + assertThat(((InternalEObject) part).eInternalResource(), not(fixture.getResource())); + + // It doesn't actually have the name set + assertThat(part.isSetName(), is(false)); + assertThat(part.getName(), notNullValue()); + }); + } + + @Test + @TestModel("inheritance/ports.uml") + public void addPortToAncestorCapsule() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = model.getCapsule("RootCapsule"); + UMLRTCapsule subcapsule = model.getCapsule("Subcapsule"); + UMLRTCapsule subsubcapsule = model.getCapsule("Subsubcapsule"); + + UMLRTProtocol newProtocol = model.createProtocol("NewProtocol"); + UMLRTPort newPort = capsule.createPort(newProtocol); + + // This new port is inherited all down the line + UMLRTPort subport = subcapsule.getPort("newProtocol"); + assertThat(subport, notNullValue()); + assertThat("port was reified", UMLRTExtensionUtil.isVirtualElement(subport), is(true)); + assertThat(subport.getRedefinedPort(), is(newPort)); + UMLRTPort subsubport = subsubcapsule.getPort("newProtocol"); + assertThat(subsubport, notNullValue()); + assertThat("port was reified", UMLRTExtensionUtil.isVirtualElement(subsubport), is(true)); + assertThat(subsubport.getRedefinedPort(), is(subport)); + } + + @Test + @TestModel("inheritance/parts.uml") + public void addCapsulePartToAncestorCapsule() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = model.getCapsule("RootCapsule"); + UMLRTCapsule subcapsule = model.getCapsule("Subcapsule"); + UMLRTCapsule subsubcapsule = model.getCapsule("Subsubcapsule"); + + UMLRTCapsule newCapsule = model.createCapsule("NewCapsule"); + UMLRTCapsulePart newPart = capsule.createCapsulePart(newCapsule); + + // This new part is inherited all down the line + UMLRTCapsulePart subpart = subcapsule.getCapsulePart("newCapsule"); + assertThat(subpart, notNullValue()); + assertThat("capsule-part was reified", UMLRTExtensionUtil.isVirtualElement(subpart), is(true)); + assertThat(subpart.getRedefinedPart(), is(newPart)); + UMLRTCapsulePart subsubpart = subsubcapsule.getCapsulePart("newCapsule"); + assertThat(subsubpart, notNullValue()); + assertThat("capsule-part was reified", UMLRTExtensionUtil.isVirtualElement(subsubpart), is(true)); + assertThat(subsubpart.getRedefinedPart(), is(subpart)); + } + + @Test + @TestModel("inheritance/ports.uml") + public void getSuperCapsule() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = model.getCapsule("RootCapsule"); + UMLRTCapsule subcapsule = model.getCapsule("Subcapsule"); + UMLRTCapsule subsubcapsule = model.getCapsule("Subsubcapsule"); + + assertThat(subsubcapsule.getSuperclass(), is(subcapsule)); + assertThat(capsule.getSuperclass(), nullValue()); + } + + @Test + @TestModel("inheritance/ports.uml") + public void setSuperCapsule() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = model.getCapsule("RootCapsule"); + UMLRTCapsule subsubcapsule = model.getCapsule("Subsubcapsule"); + + subsubcapsule.setSuperclass(capsule); + assertThat(subsubcapsule.toUML().getSuperClasses(), is(singletonList(capsule.toUML()))); + } + + @Test + @TestModel("inheritance/ports.uml") + public void isSuperTypeOf() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = model.getCapsule("RootCapsule"); + UMLRTCapsule subcapsule = model.getCapsule("Subcapsule"); + UMLRTCapsule subsubcapsule = model.getCapsule("Subsubcapsule"); + + assertThat(capsule.isSuperTypeOf(capsule), is(true)); + assertThat(capsule.isSuperTypeOf(subcapsule), is(true)); + assertThat(capsule.isSuperTypeOf(subsubcapsule), is(true)); + assertThat(subcapsule.isSuperTypeOf(capsule), is(false)); + } + + @Test + @TestModel("inheritance/ports.uml") + public void getSubCapsules() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = model.getCapsule("RootCapsule"); + UMLRTCapsule subcapsule = model.getCapsule("Subcapsule"); + + assertThat(capsule.getSubclasses(), is(singletonList(subcapsule))); + } + + @Test + @TestModel("inheritance/ports.uml") + public void getHierarchy() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = model.getCapsule("RootCapsule"); + UMLRTCapsule subcapsule = model.getCapsule("Subcapsule"); + UMLRTCapsule subsubcapsule = model.getCapsule("Subsubcapsule"); + + assertThat(capsule.getHierarchy().collect(toList()), is(Arrays.asList(capsule, subcapsule, subsubcapsule))); + assertThat(subcapsule.getHierarchy().collect(toList()), is(Arrays.asList(subcapsule, subsubcapsule))); + } + + @Test + @TestModel("inheritance/ports.uml") + public void virtualElementsAreNotStereotypedAsRTRedefinedElements() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = model.getCapsule("RootCapsule"); + + UMLRTCapsule newCapsule = model.createCapsule("NewCapsule"); + newCapsule.setSuperclass(capsule); + + // It has inherited the ports + List<UMLRTPort> ports = newCapsule.getPorts(); + assumeThat(ports.size(), is(2)); + assumeThat(ports.get(0).getName(), is("protocol1")); + assumeThat(ports.get(1).getName(), is("protocol2")); + + // They are not stereotyped as «RTRedefinedElement» + ports.stream().map(UMLRTPort::toUML).forEach(port -> { + assertThat(port, stereotypedAs("UMLRealTime::RTPort")); + assertThat(port, not(stereotypedAs("UMLRealTime::RTRedefinedElement"))); + }); + } + + @Test + @TestModel("inheritance/ports.uml") + public void reifiedElementsAreStereotypedAsRTRedefinedElements() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = model.getCapsule("RootCapsule"); + UMLRTPort rootPort = model.getCapsule("RootCapsule").getPort("protocol1"); + + UMLRTCapsule newCapsule = model.createCapsule("NewCapsule"); + newCapsule.setSuperclass(capsule); + + // It has inherited the ports + UMLRTPort newPort = newCapsule.getPort("protocol1"); + assumeThat(newPort, notNullValue()); + + newPort.reify(); + assertThat(newPort.toUML(), stereotypedAs("UMLRealTime::RTRedefinedElement")); + RTRedefinedElement rtRedef = UMLUtil.getStereotypeApplication(newPort.toUML(), RTRedefinedElement.class); + + assertThat(rtRedef.getRootFragment(), is(rootPort.toUML())); + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/CapsulePartFacadeTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/CapsulePartFacadeTest.java new file mode 100644 index 000000000..ba82af56d --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/CapsulePartFacadeTest.java @@ -0,0 +1,196 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static org.eclipse.papyrusrt.umlrt.uml.tests.util.UMLMatchers.named; +import static org.eclipse.papyrusrt.umlrt.uml.tests.util.UMLMatchers.replicated; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.util.List; + +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsulePart; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsulePartKind; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.uml2.uml.AggregationKind; +import org.eclipse.uml2.uml.LiteralInteger; +import org.eclipse.uml2.uml.LiteralUnlimitedNatural; +import org.eclipse.uml2.uml.OpaqueExpression; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.UMLPackage; +import org.junit.Rule; +import org.junit.Test; + +/** + * Test cases for the port façade class {@link UMLRTCapsulePart}. + */ +@TestModel("inheritance/parts.uml") +public class CapsulePartFacadeTest { + + @Rule + public final ModelFixture fixture = new ModelFixture(); + + public CapsulePartFacadeTest() { + super(); + } + + @Test + public void partType() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + List<UMLRTCapsulePart> parts = capsule.getCapsuleParts(); + assertThat(parts.size(), is(2)); + + assertThat(parts.get(0).getType(), is(root.getCapsule("Capsule2"))); + assertThat(parts.get(1).getType(), is(root.getCapsule("Capsule3"))); + } + + @Test + public void setPartType() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + List<UMLRTCapsulePart> parts = capsule.getCapsuleParts(); + assertThat(parts.size(), is(2)); + parts.get(0).setType(root.getCapsule("Capsule4")); + + assertThat(parts.get(0).toUML().getType(), named("Capsule4")); + } + + @Test + public void optionality() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + UMLRTCapsulePart part1 = capsule.getCapsulePart("capsule2"); + UMLRTCapsulePart part2 = capsule.getCapsulePart("capsule3"); + + assertThat(part1.isOptional(), is(false)); + assertThat(part2.isOptional(), is(false)); + + // Make the parts optional + + part1.setOptional(true); + assertThat(part1.isOptional(), is(true)); + assertThat(part1.getReplicationFactor(), is(1)); + assertThat(part1.toUML(), replicated(0, 1)); + + part2.setOptional(true); + assertThat(part2.isOptional(), is(true)); + assertThat(part2.getReplicationFactor(), is(4)); + assertThat(part2.toUML(), replicated(0, 4)); + + // Restore them to fixed replication + + part1.setOptional(false); + assertThat(part1.isOptional(), is(false)); + assertThat(part1.getReplicationFactor(), is(1)); + assertThat(part1.toUML(), replicated(1)); + + part2.setOptional(false); + assertThat(part2.isOptional(), is(false)); + assertThat(part2.getReplicationFactor(), is(4)); + assertThat(part2.toUML(), replicated(4)); + } + + @Test + public void partReplication() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + UMLRTCapsulePart part1 = capsule.getCapsulePart("capsule2"); + UMLRTCapsulePart part2 = capsule.getCapsulePart("capsule3"); + + assertThat(part1.isSymbolicReplicationFactor(), is(false)); + assertThat(part1.getReplicationFactor(), is(1)); + assertThat(part2.isSymbolicReplicationFactor(), is(false)); + assertThat(part2.getReplicationFactor(), is(4)); + + part1.setReplicationFactor(2); + + assertThat(part1.toUML().getLowerValue(), instanceOf(LiteralInteger.class)); + assertThat(((LiteralInteger) part1.toUML().getLowerValue()).getValue(), is(2)); + assertThat(part1.toUML().getUpperValue(), instanceOf(LiteralUnlimitedNatural.class)); + assertThat(((LiteralUnlimitedNatural) part1.toUML().getUpperValue()).getValue(), is(2)); + } + + @Test + public void portReplicationExpression() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + UMLRTCapsulePart part = capsule.getCapsulePart("capsule2"); + Property umlPart = part.toUML(); + OpaqueExpression lowerValue = (OpaqueExpression) umlPart.createLowerValue(null, null, UMLPackage.Literals.OPAQUE_EXPRESSION); + OpaqueExpression upperValue = (OpaqueExpression) umlPart.createUpperValue(null, null, UMLPackage.Literals.OPAQUE_EXPRESSION); + + lowerValue.getBodies().add("NUM_CAPSULES"); + upperValue.getBodies().add("NUM_CAPSULES"); + + assertThat(part.isSymbolicReplicationFactor(), is(true)); + assertThat(part.getReplicationFactor(), is(1)); + + lowerValue.getBodies().set(0, "42"); + upperValue.getBodies().set(0, "42"); + + assertThat(part.isSymbolicReplicationFactor(), is(false)); + assertThat(part.getReplicationFactor(), is(42)); + } + + @Test + public void fixedKind() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + UMLRTCapsulePart part = capsule.getCapsulePart("capsule2"); + assertThat(part.getKind(), is(UMLRTCapsulePartKind.FIXED)); + } + + @Test + public void optionalKind() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + UMLRTCapsulePart part = capsule.getCapsulePart("capsule2"); + Property umlPart = part.toUML(); + + umlPart.setLower(0); + umlPart.setUpper(2); + assertThat(part.getKind(), is(UMLRTCapsulePartKind.OPTIONAL)); + + assertThat(part.getReplicationFactor(), is(2)); + } + + @Test + public void pluginKind() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + UMLRTCapsulePart part = capsule.getCapsulePart("capsule2"); + Property umlPart = part.toUML(); + + umlPart.setLower(0); + umlPart.setUpper(2); + umlPart.setAggregation(AggregationKind.SHARED_LITERAL); + assertThat(part.getKind(), is(UMLRTCapsulePartKind.PLUG_IN)); + + assertThat(part.getReplicationFactor(), is(2)); + } + +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ConnectorFacadeTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ConnectorFacadeTest.java new file mode 100644 index 000000000..ced120b15 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ConnectorFacadeTest.java @@ -0,0 +1,285 @@ +/***************************************************************************** + * Copyright (c) 2016, 2017 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static org.eclipse.papyrusrt.umlrt.uml.tests.util.UMLMatchers.replicated; +import static org.hamcrest.CoreMatchers.anything; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.hasItems; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assume.assumeThat; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.util.EContentAdapter; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsulePart; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTConnector; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTNamedElement; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPort; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.papyrusrt.umlrt.uml.util.UMLRTExtensionUtil; +import org.eclipse.uml2.uml.ConnectorEnd; +import org.junit.Rule; +import org.junit.Test; + +/** + * Test cases for the port façade class {@link UMLRTCapsulePart}. + */ +@TestModel("inheritance/connectors.uml") +public class ConnectorFacadeTest { + + @Rule + public final ModelFixture fixture = new ModelFixture(); + + public ConnectorFacadeTest() { + super(); + } + + @Test + public void connectorEnds() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + UMLRTCapsule nested = root.getCapsule("NestedCapsule"); + + UMLRTConnector connector = capsule.getConnector("connector1"); + assertThat(connector, notNullValue()); + + UMLRTPort port1 = connector.getSource(); + assertThat(port1, is(capsule.getPort("protocol1"))); + assertThat(connector.getSourcePartWithPort(), nullValue()); + + UMLRTPort port2 = connector.getTarget(); + assertThat(port2, is(nested.getPort("protocol1"))); + + UMLRTCapsulePart part = capsule.getCapsulePart("nestedCapsule"); + assumeThat(part, notNullValue()); + + assertThat(connector.getTargetPartWithPort(), is(part)); + } + + @Test + public void connectorInherited() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + UMLRTCapsule subcapsule = root.getCapsule("Subcapsule"); + UMLRTCapsule nested = root.getCapsule("NestedCapsule"); + + UMLRTConnector connector = subcapsule.getConnector("connector1"); + assertThat(connector, notNullValue()); + assertThat(connector.isVirtualRedefinition(), is(true)); + + UMLRTConnector redefined = connector.getRedefinedConnector(); + assertThat(redefined, notNullValue()); + assertThat(redefined.getCapsule(), is(capsule)); + + assertThat(connector.getSource(), notNullValue()); + assertThat(connector.getSource(), is(subcapsule.getPort("protocol1"))); + assertThat(connector.getTarget(), notNullValue()); + assertThat(connector.getTarget(), is(nested.getPort("protocol1"))); + + assertThat(connector.getTargetPartWithPort(), notNullValue()); + assertThat(connector.getTargetPartWithPort(), is(subcapsule.getCapsulePart("nestedCapsule"))); + + ConnectorEnd end = connector.toUML().getEnds().get(0); + assertThat(UMLRTExtensionUtil.isVirtualElement(end), is(true)); + assertThat(((InternalUMLRTElement) end).rtGetRedefinedElement(), is(redefined.toUML().getEnds().get(0))); + end = connector.toUML().getEnds().get(1); + assertThat(UMLRTExtensionUtil.isVirtualElement(end), is(true)); + assertThat(((InternalUMLRTElement) end).rtGetRedefinedElement(), is(redefined.toUML().getEnds().get(1))); + } + + /** + * Verifies that an excluded connector correctly resolves the ports and parts that + * it connects, even if those are, themselves, excluded. + */ + @Test + public void excludedConnectorExcludedEnds() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule subcapsule = root.getCapsule("Subcapsule"); + + UMLRTConnector connector = subcapsule.getConnector("connector1"); + assumeThat(connector, notNullValue()); + assumeThat(connector.isVirtualRedefinition(), is(true)); + + UMLRTPort sourcePort = connector.getSource(); + UMLRTCapsulePart targetPartWithPort = connector.getTargetPartWithPort(); + + connector.exclude(); + sourcePort.exclude(); + targetPartWithPort.exclude(); + + assumeThat(sourcePort.isExcluded(), is(true)); + assumeThat(targetPartWithPort.isExcluded(), is(true)); + + assertThat(connector.getSource(), is(sourcePort)); + assertThat(connector.getTargetPartWithPort(), is(targetPartWithPort)); + } + + @Test + public void lookingAtInheritedConnectorDoesNotWrite() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + UMLRTCapsule subcapsule = root.getCapsule("Subcapsule"); + + UMLRTConnector connector = subcapsule.getConnector("connector1"); + assumeThat(connector, notNullValue()); + assumeThat(connector.isVirtualRedefinition(), is(true)); + + List<Notification> notifications = new ArrayList<>(); + fixture.getModel().eAdapters().add(new EContentAdapter() { + @Override + public void notifyChanged(Notification notification) { + super.notifyChanged(notification); + + if (notification.getEventType() != Notification.RESOLVE) { + notifications.add(notification); + } + } + }); + + // Ensure initialization of the redefining ends + UMLRTConnector redefined = connector.getRedefinedConnector(); + assumeThat(redefined, notNullValue()); + assumeThat(redefined.getCapsule(), is(capsule)); + + assumeThat(connector.toUML().getEnds().size(), is(2)); + connector.toUML().getEnds().forEach(end -> { + assumeThat(((InternalEObject) end).eInternalContainer(), is(connector.toUML())); + }); + + assertThat(notifications, not(hasItem(anything()))); + } + + @Test + public void connectorReification() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule subcapsule = root.getCapsule("Subcapsule"); + + UMLRTConnector connector = subcapsule.getConnector("connector1"); + assertThat(connector, notNullValue()); + assumeThat(connector.isVirtualRedefinition(), is(true)); + + connector.setTargetReplicationFactor(2); + + // This reifies the connector and both ends + ConnectorEnd end = connector.toUML().getEnds().get(0); + assertThat(UMLRTExtensionUtil.isVirtualElement(end), is(false)); + end = connector.toUML().getEnds().get(1); + assertThat(UMLRTExtensionUtil.isVirtualElement(end), is(false)); + assertThat(UMLRTExtensionUtil.isVirtualElement(connector.toUML()), is(false)); + } + + @Test + public void connectorReplication() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule subcapsule = root.getCapsule("Subcapsule"); + + UMLRTConnector connector = subcapsule.getConnector("connector1"); + assertThat(connector, notNullValue()); + assumeThat(connector.isVirtualRedefinition(), is(true)); + + connector.setTargetReplicationFactor(2); + + assertThat(connector.getTargetReplicationFactor(), is(2)); + + // The redefined connector isn't changed, of course + assertThat(connector.getRedefinedConnector().getTargetReplicationFactor(), is(1)); + + ConnectorEnd end = connector.toUML().getEnds().get(1); + assertThat(end, replicated(2)); + } + + @Test + public void reificationEvents() { + List<UMLRTNamedElement> reified = new ArrayList<>(); + List<UMLRTNamedElement> virtualized = new ArrayList<>(); + + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule subcapsule = root.getCapsule("Subcapsule"); + + UMLRTConnector connector = subcapsule.getConnector("connector1"); + assertThat(connector, notNullValue()); + assumeThat(connector.isVirtualRedefinition(), is(true)); + + connector.addReificationListener((e, r) -> (r ? reified : virtualized).add(e)); + + // This changes only a connector end and reifies it + connector.setTargetReplicationFactor(2); + + assertThat(reified, hasItem(connector)); + assertThat(virtualized, not(hasItem(anything()))); + + reified.clear(); + virtualized.clear(); + + // The only support way to re-virtualize an element + connector.exclude(); + connector.reinherit(); + + assertThat(reified, not(hasItem(anything()))); + assertThat(virtualized, hasItem(connector)); + + // The ends are now virtual, too, of course + ConnectorEnd end = connector.toUML().getEnds().get(0); + assertThat(UMLRTExtensionUtil.isVirtualElement(end), is(true)); + end = connector.toUML().getEnds().get(1); + assertThat(UMLRTExtensionUtil.isVirtualElement(end), is(true)); + } + + @Test + public void portConnectors() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + UMLRTCapsule subcapsule = root.getCapsule("Subcapsule"); + + UMLRTPort redefinedPort = capsule.getPort("protocol1"); + UMLRTPort port = subcapsule.getRedefinitionOf(redefinedPort); + + UMLRTCapsulePart redefinedPart = capsule.getCapsulePart("nestedCapsule"); + UMLRTCapsulePart part = subcapsule.getRedefinitionOf(redefinedPart); + + UMLRTPort portOnPart = redefinedPart.getType().getPort("protocol1"); + + // Although in UML, the ends of inherited connectors reference the root + // port definition, we resolve connectors to the proper local capsule context + List<UMLRTConnector> rootConnectors = redefinedPort.getInsideConnectors(); + assertThat(rootConnectors.size(), is(1)); // In UML, there are three! + + List<UMLRTConnector> connectors = port.getInsideConnectors(); + assertThat(connectors.size(), is(1)); + + assertThat(connectors.get(0), not(rootConnectors.get(0))); + assertThat(connectors.get(0).redefines(rootConnectors.get(0)), is(true)); + + assertThat(redefinedPart.getConnectorsOfPorts(), is(rootConnectors)); + assertThat(part.getConnectorsOfPorts(), is(connectors)); + + // This port legitimately is connected (on the outside) to all of the connectors + // because there is only one definition of it (it is not redefined in any context) + List<UMLRTConnector> outsideConnectors = portOnPart.getOutsideConnectors(); + assertThat(outsideConnectors, hasItems(rootConnectors.get(0), connectors.get(0))); + } + +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/FacadeFactoryTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/FacadeFactoryTest.java new file mode 100644 index 000000000..70496e545 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/FacadeFactoryTest.java @@ -0,0 +1,192 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.CoreMatchers.sameInstance; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.fail; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Arrays; + +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsulePart; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTConnector; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTFactory; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTModel; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTNamedElement; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPort; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocol; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocolMessage; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.uml2.uml.NamedElement; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +/** + * Test cases for the façade factory API {@link UMLRTFactory}. + */ +@RunWith(Parameterized.class) +public class FacadeFactoryTest { + + @Rule + public final ModelFixture fixture; + + private final String elementName; + private final java.lang.Class<?> factoryClass; + private final java.lang.Class<? extends UMLRTNamedElement> facadeClass; + + public FacadeFactoryTest(String modelPath, String elementName, + FactoryKind factory, FacadeKind facade) { + + super(); + + this.elementName = elementName; + this.factoryClass = factory.factoryClass; + this.facadeClass = facade.facadeClass; + + this.fixture = new ModelFixture(modelPath); + } + + @Test + public void create() { + NamedElement element = fixture.getElement(elementName); + UMLRTNamedElement expected = getFacade(element); + UMLRTNamedElement actual = createFacade(element); + + if (expected == null) { + assertThat(actual, nullValue()); + } else { + assertThat(actual, sameInstance(expected)); + assertModel(element); + } + } + + // + // Test framework + // + + @Parameters(name = "{2} ==> {3}") + public static Iterable<Object[]> parameters() { + return Arrays.asList(new Object[][] { + { "inheritance/ports.uml", "RootCapsule", FactoryKind.UMLRTFactory, FacadeKind.Capsule }, + { "inheritance/ports.uml", "RootCapsule::protocol1", FactoryKind.UMLRTFactory, FacadeKind.Port }, + { "inheritance/parts.uml", "RootCapsule::capsule2", FactoryKind.UMLRTFactory, FacadeKind.CapsulePart }, + { "inheritance/connectors.uml", "RootCapsule::connector1", FactoryKind.UMLRTFactory, FacadeKind.Connector }, + { "inheritance/ports.uml", "Protocol1::Protocol1", FactoryKind.UMLRTFactory, FacadeKind.Protocol }, + { "inheritance/ports.uml", "Protocol1::Protocol1::greet", FactoryKind.UMLRTFactory, FacadeKind.ProtocolMessage }, + { "inheritance/ports.uml", "nested", FactoryKind.UMLRTFactory, FacadeKind.Package }, + + { "inheritance/ports.uml", "RootCapsule", FactoryKind.CapsuleFactory, FacadeKind.Capsule }, + { "inheritance/ports.uml", "RootCapsule::protocol1", FactoryKind.CapsuleFactory, FacadeKind.Port }, + { "inheritance/parts.uml", "RootCapsule::capsule2", FactoryKind.CapsuleFactory, FacadeKind.CapsulePart }, + { "inheritance/connectors.uml", "RootCapsule::connector1", FactoryKind.CapsuleFactory, FacadeKind.Connector }, + + { "inheritance/ports.uml", "Protocol1::Protocol1", FactoryKind.ProtocolFactory, FacadeKind.Protocol }, + { "inheritance/ports.uml", "Protocol1::Protocol1::greet", FactoryKind.ProtocolFactory, FacadeKind.ProtocolMessage }, + }); + } + + UMLRTNamedElement getFacade(NamedElement element) { + UMLRTNamedElement result = null; + + if (facadeClass != null) { + for (Method next : facadeClass.getMethods()) { + if (Modifier.isStatic(next.getModifiers()) + && "getInstance".equals(next.getName()) + && (next.getParameterTypes().length == 1) + && next.getParameterTypes()[0].isInstance(element)) { + + try { + result = (UMLRTNamedElement) next.invoke(null, element); + } catch (Exception e) { + e.printStackTrace(); + fail("Failed to get facade instance: " + e.getMessage()); + } + break; + } + } + } + + return result; + } + + UMLRTNamedElement createFacade(NamedElement element) { + UMLRTNamedElement result = null; + + for (Method next : factoryClass.getMethods()) { + if (Modifier.isStatic(next.getModifiers()) + && "create".equals(next.getName()) + && (next.getParameterTypes().length == 1) + && next.getParameterTypes()[0].isInstance(element)) { + + try { + result = (UMLRTNamedElement) next.invoke(null, element); + } catch (Exception e) { + e.printStackTrace(); + fail("Failed to create facade instance: " + e.getMessage()); + } + break; + } + } + + assertThat("No factory method found", result, notNullValue()); + + return result; + } + + void assertModel(NamedElement uml) { + UMLRTModel expected = UMLRTModel.getInstance(uml.eResource()); + assertThat(UMLRTFactory.create(uml).getModel(), sameInstance(expected)); + } + + // + // Nested types + // + + enum FactoryKind { + UMLRTFactory(UMLRTFactory.class), // + CapsuleFactory(UMLRTFactory.CapsuleFactory.class), // + ProtocolFactory(UMLRTFactory.ProtocolFactory.class); + + final Class<?> factoryClass; + + private FactoryKind(Class<?> factoryClass) { + this.factoryClass = factoryClass; + } + } + + enum FacadeKind { + Capsule(UMLRTCapsule.class), // + Port(UMLRTPort.class), // + CapsulePart(UMLRTCapsulePart.class), // + Connector(UMLRTConnector.class), // + Protocol(UMLRTProtocol.class), // + ProtocolMessage(UMLRTProtocolMessage.class), // + Package(UMLRTPackage.class); + + final Class<? extends UMLRTNamedElement> facadeClass; + + private FacadeKind(Class<? extends UMLRTNamedElement> facadeClass) { + this.facadeClass = facadeClass; + } + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/InheritanceNotificationTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/InheritanceNotificationTest.java new file mode 100644 index 000000000..e4f48e66f --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/InheritanceNotificationTest.java @@ -0,0 +1,323 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static org.hamcrest.CoreMatchers.anything; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assume.assumeThat; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.LiteralString; +import org.eclipse.uml2.uml.LiteralUnlimitedNatural; +import org.eclipse.uml2.uml.OpaqueExpression; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.Type; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.VisibilityKind; +import org.junit.Rule; +import org.junit.Test; + +/** + * Test cases for notifications from inherited features in redefinitions. + */ +@TestModel("inheritance/ports.uml") +public class InheritanceNotificationTest { + + @Rule + public final ModelFixture fixture = new ModelFixture(); + + public InheritanceNotificationTest() { + super(); + } + + @Test + public void nameNotification() { + Class root = fixture.getElement("RootCapsule"); + Port redefined = root.getOwnedPorts().get(0); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port port = subsub.getOwnedPorts().get(0); + + fixture.expectNotification(port, UMLPackage.Literals.NAMED_ELEMENT__NAME, + Notification.SET, anything(), is("newPortName"), + () -> redefined.setName("newPortName")); + } + + @Test + public void visibilityNotification() { + Class root = fixture.getElement("RootCapsule"); + Port redefined = root.getOwnedPorts().get(0); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port port = subsub.getOwnedPorts().get(0); + + fixture.expectNotification(port, UMLPackage.Literals.NAMED_ELEMENT__VISIBILITY, + Notification.SET, anything(), is(VisibilityKind.PACKAGE_LITERAL), + () -> redefined.setVisibility(VisibilityKind.PACKAGE_LITERAL)); + } + + @Test + public void typeNotification() { + Class root = fixture.getElement("RootCapsule"); + Port redefined = root.getOwnedPorts().get(0); + Type oldType = redefined.getType(); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port port = subsub.getOwnedPorts().get(0); + + fixture.expectNotification(port, UMLPackage.Literals.TYPED_ELEMENT__TYPE, + Notification.SET, is(oldType), nullValue(), + () -> redefined.setType(null)); + } + + @Test + public void replicationNotification() { + Class root = fixture.getElement("RootCapsule"); + Port redefined = root.getOwnedPorts().get(0); + redefined.setUpper(2); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port port = subsub.getOwnedPorts().get(0); + assumeThat(port.getUpper(), is(2)); + + fixture.expectNotification(port.getUpperValue(), UMLPackage.Literals.LITERAL_UNLIMITED_NATURAL__VALUE, + Notification.SET, is(2), is(3), + () -> redefined.setUpper(3)); + } + + @Test + public void replicationInheritanceSymbolicString() { + Class root = fixture.getElement("RootCapsule"); + Port redefined = root.getOwnedPorts().get(0); + redefined.setUpper(2); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port port = subsub.getOwnedPorts().get(0); + assumeThat(port.getUpperValue(), instanceOf(LiteralUnlimitedNatural.class)); + + fixture.expectNotification(port, UMLPackage.Literals.MULTIPLICITY_ELEMENT__UPPER_VALUE, + Notification.SET, instanceOf(LiteralUnlimitedNatural.class), instanceOf(LiteralString.class), + () -> ((LiteralString) redefined.createUpperValue(null, null, UMLPackage.Literals.LITERAL_STRING)) + .setValue("NUM_PORTS")); + + assertThat(port.getUpperValue(), instanceOf(LiteralString.class)); + assertThat(port.getUpperValue().eIsSet(UMLPackage.Literals.LITERAL_STRING__VALUE), is(false)); + assertThat(port.getUpperValue().stringValue(), is("NUM_PORTS")); + } + + @Test + public void replicationInheritanceSymbolicExpression() { + Class root = fixture.getElement("RootCapsule"); + Port redefined = root.getOwnedPorts().get(0); + redefined.setUpper(2); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port port = subsub.getOwnedPorts().get(0); + assumeThat(port.getUpperValue(), instanceOf(LiteralUnlimitedNatural.class)); + + fixture.expectNotification(port, UMLPackage.Literals.MULTIPLICITY_ELEMENT__UPPER_VALUE, + Notification.SET, instanceOf(LiteralUnlimitedNatural.class), instanceOf(OpaqueExpression.class), + () -> { + OpaqueExpression expr = ((OpaqueExpression) redefined.createUpperValue(null, null, UMLPackage.Literals.OPAQUE_EXPRESSION)); + expr.getBodies().add("NUM_PORTS"); + expr.getLanguages().add("C++"); + }); + + assertThat(port.getUpperValue(), instanceOf(OpaqueExpression.class)); + assertThat(port.getUpperValue().eIsSet(UMLPackage.Literals.OPAQUE_EXPRESSION__BODY), is(false)); + assertThat(port.getUpperValue().eIsSet(UMLPackage.Literals.OPAQUE_EXPRESSION__LANGUAGE), is(false)); + OpaqueExpression expr = (OpaqueExpression) port.getUpperValue(); + assertThat(expr.getBodies().size(), is(1)); + assertThat(expr.getBodies(), hasItem("NUM_PORTS")); + assertThat(expr.getLanguages().size(), is(1)); + assertThat(expr.getLanguages(), hasItem("C++")); + } + + @Test + public void serviceNotification() { + Class root = fixture.getElement("RootCapsule"); + Port redefined = root.getOwnedPorts().get(0); + boolean oldService = redefined.isService(); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port port = subsub.getOwnedPorts().get(0); + + fixture.expectNotification(port, UMLPackage.Literals.PORT__IS_SERVICE, + Notification.SET, is(oldService), is(false), + () -> redefined.setIsService(false)); + } + + @Test + public void behaviorNotification() { + Class root = fixture.getElement("RootCapsule"); + Port redefined = root.getOwnedPorts().get(0); + boolean oldBehavior = redefined.isBehavior(); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port port = subsub.getOwnedPorts().get(0); + + fixture.expectNotification(port, UMLPackage.Literals.PORT__IS_BEHAVIOR, + Notification.SET, is(oldBehavior), is(false), + () -> redefined.setIsBehavior(false)); + } + + @Test + public void conjugatedNotification() { + Class root = fixture.getElement("RootCapsule"); + Port redefined = root.getOwnedPorts().get(0); + boolean oldConjugated = redefined.isConjugated(); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port port = subsub.getOwnedPorts().get(0); + + fixture.expectNotification(port, UMLPackage.Literals.PORT__IS_CONJUGATED, + Notification.SET, is(oldConjugated), is(true), + () -> redefined.setIsConjugated(true)); + } + + @Test + public void nameRedefined() { + Class root = fixture.getElement("RootCapsule"); + Port redefined = root.getOwnedPorts().get(0); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port port = subsub.getOwnedPorts().get(0); + port.setName("redefining"); + + fixture.expectNoNotification(port, UMLPackage.Literals.NAMED_ELEMENT__NAME, + Notification.SET, anything(), is("newPortName"), + () -> redefined.setName("newPortName")); + } + + @Test + public void visibilityRedefined() { + Class root = fixture.getElement("RootCapsule"); + Port redefined = root.getOwnedPorts().get(0); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port port = subsub.getOwnedPorts().get(0); + port.setVisibility(VisibilityKind.PACKAGE_LITERAL); + + fixture.expectNoNotification(port, UMLPackage.Literals.NAMED_ELEMENT__VISIBILITY, + Notification.SET, anything(), is(VisibilityKind.PRIVATE_LITERAL), + () -> redefined.setVisibility(VisibilityKind.PRIVATE_LITERAL)); + } + + @Test + public void typeRedefined() { + Class root = fixture.getElement("RootCapsule"); + Port redefined = root.getOwnedPorts().get(0); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port port = subsub.getOwnedPorts().get(0); + port.setType(fixture.getElement("Protocol2::Protocol2")); + + fixture.expectNoNotification(port, UMLPackage.Literals.TYPED_ELEMENT__TYPE, + Notification.SET, anything(), nullValue(), + () -> redefined.setType(null)); + } + + @Test + public void serviceRedefined() { + Class root = fixture.getElement("RootCapsule"); + Port redefined = root.getOwnedPorts().get(0); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port port = subsub.getOwnedPorts().get(0); + port.setIsService(false); + + fixture.expectNoNotification(port, UMLPackage.Literals.PORT__IS_SERVICE, + Notification.SET, anything(), is(false), + () -> redefined.setIsService(false)); + } + + @Test + public void behaviorRedefined() { + Class root = fixture.getElement("RootCapsule"); + Port redefined = root.getOwnedPorts().get(0); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port port = subsub.getOwnedPorts().get(0); + port.setIsBehavior(false); + + fixture.expectNoNotification(port, UMLPackage.Literals.PORT__IS_BEHAVIOR, + Notification.SET, anything(), is(false), + () -> redefined.setIsBehavior(false)); + } + + @Test + public void conjugatedRedefined() { + Class root = fixture.getElement("RootCapsule"); + Port redefined = root.getOwnedPorts().get(0); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port port = subsub.getOwnedPorts().get(0); + port.setIsConjugated(true); + + fixture.expectNoNotification(port, UMLPackage.Literals.PORT__IS_CONJUGATED, + Notification.SET, anything(), is(true), + () -> redefined.setIsConjugated(true)); + } + + @Test + public void replicationRedefined() { + Class root = fixture.getElement("RootCapsule"); + Port redefined = root.getOwnedPorts().get(0); + redefined.setUpper(2); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port port = subsub.getOwnedPorts().get(0); + port.setUpper(4); + + fixture.expectNoNotification(port.getUpperValue(), UMLPackage.Literals.LITERAL_UNLIMITED_NATURAL__VALUE, + Notification.SET, anything(), anything(), + () -> redefined.setUpper(3)); + } + + @Test + public void replicationRedefinedExplicitOnTheUpperValue() { + Class root = fixture.getElement("RootCapsule"); + Port redefined = root.getOwnedPorts().get(0); + redefined.setUpper(2); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port port = subsub.getOwnedPorts().get(0); + ((LiteralUnlimitedNatural) port.getUpperValue()).setValue(4); + + fixture.expectNoNotification(port.getUpperValue(), UMLPackage.Literals.LITERAL_UNLIMITED_NATURAL__VALUE, + Notification.SET, anything(), anything(), + () -> redefined.setUpper(3)); + } + + @Test + public void redefinitionRemoved() { + Class root = fixture.getElement("RootCapsule"); + Port redefined = root.getOwnedPorts().get(0); + + Class subsub = fixture.getElement("Subsubcapsule"); + Port port = subsub.getOwnedPorts().get(0); + port.getRedefinedPorts().clear(); + + fixture.expectNoNotification(port, UMLPackage.Literals.NAMED_ELEMENT__NAME, + Notification.SET, anything(), is("newPortName"), + () -> redefined.setName("newPortName")); + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/LazyExtensionTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/LazyExtensionTest.java new file mode 100644 index 000000000..01df68566 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/LazyExtensionTest.java @@ -0,0 +1,195 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static org.hamcrest.CoreMatchers.anything; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assume.assumeThat; + +import java.util.List; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPort; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionResource; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.LiteralString; +import org.eclipse.uml2.uml.UMLPackage; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.junit.Rule; +import org.junit.Test; + +/** + * Test cases verifying lazy instantiation (and destruction) of + * extension elements. + */ +@TestModel("inheritance/ports.uml") +public class LazyExtensionTest { + + @Rule + public final ModelFixture fixture = new ModelFixture(); + + public LazyExtensionTest() { + super(); + } + + @Test + @TestModel("no_inheritance.uml") + public void noExtensionsWhenNotNeeded() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule1 = model.getCapsule("Capsule1"); + UMLRTCapsule capsule2 = model.getCapsule("Capsule2"); + + assertThat(capsule1.getSubclasses(), not(hasItem(anything()))); + assertThat(capsule2.getSubclasses(), not(hasItem(anything()))); + + // There are no extensions + assertThat(getExtensionExtent(), not(hasItem(anything()))); + } + + @Test + public void inheritPorts() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = model.getCapsule("RootCapsule"); + + // There are no extensions, yet, for any capsule + assertThat(getExtensionExtent(), not(hasExtension(UMLPackage.Literals.CLASS))); + + UMLRTCapsule newCapsule = model.createCapsule("NewCapsule"); + newCapsule.setSuperclass(capsule); + + // It has inherited the ports + List<UMLRTPort> ports = newCapsule.getPorts(); + assertThat(ports.size(), is(2)); + assertThat(ports.get(0).getName(), is("protocol1")); + assertThat(ports.get(1).getName(), is("protocol2")); + + // Now there is an extension for the capsule + assertThat(getExtensionExtent(), hasExtension(UMLPackage.Literals.CLASS)); + } + + @Test + public void uninheritPorts() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = model.getCapsule("RootCapsule"); + UMLRTCapsule newCapsule = model.createCapsule("NewCapsule"); + newCapsule.setSuperclass(capsule); + + // It has inherited the ports + List<UMLRTPort> ports = newCapsule.getPorts(); + assumeThat(ports.size(), is(2)); + + // There is an extension for the capsule + assumeThat(getExtensionExtent(), hasExtension(UMLPackage.Literals.CLASS)); + + newCapsule.setSuperclass(null); + + // There is no longer any need for an extension for the capsule + assertThat(getExtensionExtent(), not(hasExtension(UMLPackage.Literals.CLASS))); + } + + /** + * Tests the feature-setting implementation for inherited (extension) + * features that are not yet initialized. Other tests implicitly + * cover the feature-setting for many-value (list) features. + */ + @Test + public void inheritedSingleSetting() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = model.getCapsule("RootCapsule"); + + UMLRTCapsule newCapsule = model.createCapsule("NewCapsule"); + newCapsule.setSuperclass(capsule); + + List<UMLRTPort> ports = newCapsule.getPorts(); + assumeThat(ports.size(), is(2)); + UMLRTPort port = ports.get(1); + + EStructuralFeature.Setting setting = ((InternalEObject) port.toUML()).eSetting(UMLPackage.Literals.MULTIPLICITY_ELEMENT__LOWER_VALUE); + assertThat(setting.isSet(), is(false)); + + // Access the implicit multiplicity + assumeThat(port.toUML().getLower(), is(4)); + + LiteralString stringValue = fixture.create(UMLPackage.Literals.LITERAL_STRING); + stringValue.setValue("7"); + setting.set(stringValue); + + assertThat(port.toUML().getLower(), is(7)); + } + + // + // Test framework + // + + EList<EObject> getExtensionExtent() { + Resource result = ExtensionResource.getExtensionExtent(fixture.getModel()); + assertThat("No extension extent", result, notNullValue()); + return result.getContents(); + } + + Matcher<EObject> extendsA(EClass extendedMetaclass) { + return new BaseMatcher<EObject>() { + @Override + public void describeTo(Description description) { + String name = extendedMetaclass.getName(); + description.appendText("extends a " + name); + } + + @Override + public boolean matches(Object item) { + return (item instanceof ExtElement) + && extendedMetaclass.isInstance(((ExtElement) item).getExtendedElement()); + } + }; + } + + Matcher<Iterable<? super EObject>> hasExtension(EClass extendedMetaclass) { + return hasItem(extendsA(extendedMetaclass)); + } + + Matcher<EObject> extendsThe(Element extendedElement) { + return new BaseMatcher<EObject>() { + @Override + public void describeTo(Description description) { + description.appendText("extends " + extendedElement); + } + + @Override + public boolean matches(Object item) { + return (item instanceof ExtElement) + && (((ExtElement) item).getExtendedElement() == extendedElement); + } + }; + } + + Matcher<Iterable<? super EObject>> hasExtension(Element extendedElement) { + return hasItem(extendsThe(extendedElement)); + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/PackageFacadeTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/PackageFacadeTest.java new file mode 100644 index 000000000..fdef5c972 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/PackageFacadeTest.java @@ -0,0 +1,158 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static org.eclipse.papyrusrt.umlrt.uml.tests.util.UMLMatchers.stereotypedAs; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assume.assumeThat; + +import java.util.List; + +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTModel; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocol; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Enumeration; +import org.junit.Rule; +import org.junit.Test; + +/** + * Test cases for the package façade class {@link UMLRTPackage}. + */ +@TestModel("inheritance/ports.uml") +public class PackageFacadeTest { + + @Rule + public final ModelFixture fixture = new ModelFixture(); + + public PackageFacadeTest() { + super(); + } + + @Test + public void root() { + UMLRTPackage root = UMLRTModel.getInstance(fixture.getResource()).getRoot(); + assertThat(root, notNullValue()); + assertThat(root.getName(), is("ports")); + } + + @Test + public void capsules() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + + assertThat(model.getCapsules().size(), is(3)); + + UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("Subcapsule")); + assertThat(model.getCapsules(), hasItem(capsule)); + } + + @Test + public void getCapsule() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + + UMLRTCapsule capsule = model.getCapsule("Subcapsule"); + assertThat(capsule, notNullValue()); + assertThat(model.getCapsules(), hasItem(capsule)); + } + + @Test + public void createCapsule() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + + UMLRTCapsule capsule = model.createCapsule("NewCapsule"); + assertThat(capsule, notNullValue()); + assertThat(model.getCapsules(), hasItem(capsule)); + assertThat(capsule.toUML().isActive(), is(true)); + } + + @Test + public void nestedPackages() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + + // Protocol containers are not packages + assertThat(model.getNestedPackages().size(), is(1)); + assertThat(model.getNestedPackages().get(0).getName(), is("nested")); + } + + @Test + public void getPackage() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + + UMLRTPackage nested = model.getNestedPackage("nested"); + assertThat(nested, notNullValue()); + assertThat(model.getNestedPackages(), hasItem(nested)); + } + + @Test + public void createPackage() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + + UMLRTPackage newPackage = model.createNestedPackage("newpackage"); + assertThat(newPackage, notNullValue()); + assertThat(model.getNestedPackages(), hasItem(newPackage)); + } + + @Test + public void protocols() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + + List<UMLRTProtocol> protocols = model.getProtocols(); + assertThat(protocols.size(), is(2)); + assertThat(protocols.get(0).getName(), is("Protocol1")); + assertThat(protocols.get(1).getName(), is("Protocol2")); + } + + @Test + public void getProtocol() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + + UMLRTProtocol protocol2 = model.getProtocol("Protocol2"); + assertThat(protocol2, notNullValue()); + assertThat(model.getProtocols(), hasItem(protocol2)); + } + + @Test + public void createProtocol() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + + UMLRTProtocol newProtocol = model.createProtocol("NewProtocol"); + assertThat(newProtocol, notNullValue()); + assertThat(model.getProtocols(), hasItem(newProtocol)); + + // The collaboration and three message-set interfaces + assertThat(newProtocol.toUML().getNearestPackage().getOwnedTypes().size(), is(4)); + assertThat(newProtocol.toUML().getNearestPackage().getOwnedTypes(), + hasItem(stereotypedAs("UMLRealTime::RTMessageSet"))); + } + + @Test + public void otherTypes() { + UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel()); + + Enumeration yesno = fixture.getElement("YesNo"); + assumeThat(yesno, notNullValue()); + Class passive = fixture.getElement("Passivity"); + assumeThat(passive, notNullValue()); + + assertThat(model.getCapsule(yesno.getName()), nullValue()); + assertThat(model.getCapsule(passive.getName()), nullValue()); + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/PortFacadeTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/PortFacadeTest.java new file mode 100644 index 000000000..0de68c90f --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/PortFacadeTest.java @@ -0,0 +1,280 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static org.eclipse.papyrusrt.umlrt.uml.tests.util.UMLMatchers.hasStereotypeValue; +import static org.eclipse.papyrusrt.umlrt.uml.tests.util.UMLMatchers.named; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.sameInstance; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.util.List; + +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.PortRegistrationType; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPort; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPortKind; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocol; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.uml2.uml.LiteralInteger; +import org.eclipse.uml2.uml.LiteralUnlimitedNatural; +import org.eclipse.uml2.uml.OpaqueExpression; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.VisibilityKind; +import org.junit.Rule; +import org.junit.Test; + +/** + * Test cases for the port façade class {@link UMLRTPort}. + */ +@TestModel("inheritance/ports.uml") +public class PortFacadeTest { + + @Rule + public final ModelFixture fixture = new ModelFixture(); + + public PortFacadeTest() { + super(); + } + + @Test + public void portType() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + List<UMLRTPort> ports = capsule.getPorts(); + assertThat(ports.size(), is(2)); + + assertThat(ports.get(0).getType(), is(root.getProtocol("Protocol1"))); + assertThat(ports.get(1).getType(), is(root.getProtocol("Protocol2"))); + } + + @Test + public void setPortType() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + List<UMLRTPort> ports = capsule.getPorts(); + assertThat(ports.size(), is(2)); + ports.get(0).setType(root.getProtocol("Protocol2")); + + assertThat(ports.get(0).toUML().getType().getName(), is("Protocol2")); + } + + @Test + public void portReplication() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + UMLRTPort port1 = capsule.getPort("protocol1"); + UMLRTPort port2 = capsule.getPort("protocol2"); + + assertThat(port1.isSymbolicReplicationFactor(), is(false)); + assertThat(port1.getReplicationFactor(), is(1)); + assertThat(port2.isSymbolicReplicationFactor(), is(false)); + assertThat(port2.getReplicationFactor(), is(4)); + + port1.setReplicationFactor(2); + + assertThat(port1.toUML().getLowerValue(), instanceOf(LiteralInteger.class)); + assertThat(((LiteralInteger) port1.toUML().getLowerValue()).getValue(), is(2)); + assertThat(port1.toUML().getUpperValue(), instanceOf(LiteralUnlimitedNatural.class)); + assertThat(((LiteralUnlimitedNatural) port1.toUML().getUpperValue()).getValue(), is(2)); + } + + @Test + public void portReplicationExpression() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + UMLRTPort port = capsule.getPort("protocol1"); + Port umlPort = port.toUML(); + OpaqueExpression lowerValue = (OpaqueExpression) umlPort.createLowerValue(null, null, UMLPackage.Literals.OPAQUE_EXPRESSION); + OpaqueExpression upperValue = (OpaqueExpression) umlPort.createUpperValue(null, null, UMLPackage.Literals.OPAQUE_EXPRESSION); + + lowerValue.getBodies().add("NUM_GREETERS"); + upperValue.getBodies().add("NUM_GREETERS"); + + assertThat(port.isSymbolicReplicationFactor(), is(true)); + assertThat(port.getReplicationFactor(), is(1)); + + lowerValue.getBodies().set(0, "42"); + upperValue.getBodies().set(0, "42"); + + assertThat(port.isSymbolicReplicationFactor(), is(false)); + assertThat(port.getReplicationFactor(), is(42)); + } + + @Test + public void wired() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + UMLRTPort port = capsule.getPort("protocol1"); + assertThat(port.isWired(), is(true)); + port.setWired(false); + assertThat(port.toUML(), hasStereotypeValue("UMLRealTime::RTPort", "isWired", is(false))); + } + + @Test + public void registration() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + UMLRTPort port = capsule.getPort("protocol1"); + assertThat(port.getRegistration(), is(PortRegistrationType.AUTOMATIC)); + port.setRegistration(PortRegistrationType.APPLICATION); + assertThat(port.toUML(), hasStereotypeValue("UMLRealTime::RTPort", "registration", is(PortRegistrationType.APPLICATION))); + } + + @Test + public void conjugation() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + UMLRTPort port = capsule.getPort("protocol1"); + assertThat(port.isConjugated(), is(false)); + UMLRTProtocol type = port.getType(); + assertThat(type.isConjugate(), is(false)); + + port.setConjugated(true); + assertThat(port.getType().isConjugate(), is(true)); + assertThat(port.getType(), sameInstance(type.getConjugate())); + + assertThat(port.toUML().getType(), named("Protocol1")); + } + + @Test + public void typeConjugation() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + UMLRTPort port = capsule.getPort("protocol1"); + UMLRTProtocol type = port.getType(); + port.setType(type.getConjugate()); + + assertThat(port.isConjugated(), is(true)); + assertThat(port.getType().getName(), is("Protocol1~")); + } + + @Test + public void externalBehaviorKind() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + UMLRTPort port = capsule.getPort("protocol1"); + assertThat(port.getKind(), is(UMLRTPortKind.EXTERNAL_BEHAVIOR)); + } + + @Test + public void internalBehaviorKind() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + UMLRTPort port = capsule.getPort("protocol1"); + port.setKind(UMLRTPortKind.INTERNAL_BEHAVIOR); + assertThat(port.toUML().isService(), is(false)); + assertThat(port.getKind(), is(UMLRTPortKind.INTERNAL_BEHAVIOR)); + assertThat(port.toUML().getVisibility(), is(VisibilityKind.PROTECTED_LITERAL)); + } + + @Test + public void relayKind() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + UMLRTPort port = capsule.getPort("protocol1"); + port.setKind(UMLRTPortKind.RELAY); + assertThat(port.toUML().isBehavior(), is(false)); + assertThat(port.getKind(), is(UMLRTPortKind.RELAY)); + assertThat(port.toUML().getVisibility(), is(VisibilityKind.PUBLIC_LITERAL)); + } + + @Test + public void sapKind() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + UMLRTPort port = capsule.getPort("protocol1"); + port.setKind(UMLRTPortKind.SAP); + assertThat(port.toUML(), hasStereotypeValue("UMLRealTime::RTPort", "isWired", is(false))); + assertThat(port.toUML(), hasStereotypeValue("UMLRealTime::RTPort", "isPublish", is(false))); + assertThat(port.getKind(), is(UMLRTPortKind.SAP)); + assertThat(port.toUML().getVisibility(), is(VisibilityKind.PROTECTED_LITERAL)); + } + + @Test + public void sppKind() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = root.getCapsule("RootCapsule"); + + UMLRTPort port = capsule.getPort("protocol1"); + port.setKind(UMLRTPortKind.SPP); + assertThat(port.toUML(), hasStereotypeValue("UMLRealTime::RTPort", "isWired", is(false))); + assertThat(port.toUML(), hasStereotypeValue("UMLRealTime::RTPort", "isPublish", is(true))); + assertThat(port.getKind(), is(UMLRTPortKind.SPP)); + assertThat(port.toUML().getVisibility(), is(VisibilityKind.PUBLIC_LITERAL)); + } + + @Test + public void inheritedElement() { + UMLRTCapsule rootCapsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule")); + UMLRTCapsule subcapsule = rootCapsule.getPackage().createCapsule("NewSubcapsule"); + UMLRTCapsule subsubcapsule = rootCapsule.getPackage().createCapsule("NewSubsubcapsule"); + subcapsule.setSuperclass(rootCapsule); + subsubcapsule.setSuperclass(subcapsule); + + UMLRTPort rootPort = rootCapsule.getPort("protocol1"); + UMLRTPort subPort = subcapsule.getPort("protocol1"); + UMLRTPort subsubPort = subsubcapsule.getPort("protocol1"); + + assertThat(subsubPort.getInheritedElement(), is(rootPort)); + subPort.setBehavior(false); // Make a real redefinition here + assertThat(subsubPort.getInheritedElement(), is(subPort)); + } + + @TestModel("inheritance/connectors.uml") + @Test + public void isConnectedInside() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule subcapsule = root.getCapsule("Subcapsule"); + UMLRTCapsule nestedCapsule = root.getCapsule("NestedCapsule"); + + // this one is only connected inside + assertThat(subcapsule.getPort("protocol1").isConnectedInside(), is(true)); + // this one has no connectors + assertThat(subcapsule.getPort("protocol2").isConnectedInside(), is(false)); + // this one is only connected outside + assertThat(nestedCapsule.getPort("protocol1").isConnectedInside(), is(false)); + } + + @TestModel("inheritance/connectors.uml") + @Test + public void isConnectedOutside() { + UMLRTPackage root = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule subcapsule = root.getCapsule("Subcapsule"); + UMLRTCapsule nestedCapsule = root.getCapsule("NestedCapsule"); + + // this one is only connected inside + assertThat(subcapsule.getPort("protocol1").isConnectedOutside(), is(false)); + // this one has no connectors + assertThat(subcapsule.getPort("protocol2").isConnectedOutside(), is(false)); + // this one is only connected outside + assertThat(nestedCapsule.getPort("protocol1").isConnectedOutside(), is(true)); + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ProtocolFacadeTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ProtocolFacadeTest.java new file mode 100644 index 000000000..61253d3ae --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ProtocolFacadeTest.java @@ -0,0 +1,436 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static java.util.stream.Collectors.toList; +import static org.eclipse.papyrusrt.umlrt.uml.tests.util.UMLMatchers.named; +import static org.eclipse.papyrusrt.umlrt.uml.tests.util.UMLMatchers.redefines; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.CoreMatchers.sameInstance; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assume.assumeThat; + +import java.util.Arrays; +import java.util.List; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.change.ChangeDescription; +import org.eclipse.emf.ecore.change.util.ChangeRecorder; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTMessageKind; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocol; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocolMessage; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.papyrusrt.umlrt.uml.util.UMLRTExtensionUtil; +import org.eclipse.uml2.uml.Interface; +import org.eclipse.uml2.uml.Operation; +import org.eclipse.uml2.uml.Parameter; +import org.eclipse.uml2.uml.PrimitiveType; +import org.eclipse.uml2.uml.Type; +import org.junit.Rule; +import org.junit.Test; + +/** + * Test cases for the protocol façade class {@link UMLRTProtocol}. + */ +@TestModel("inheritance/ports.uml") +public class ProtocolFacadeTest { + + @Rule + public final ModelFixture fixture = new ModelFixture(); + + public ProtocolFacadeTest() { + super(); + } + + @Test + public void messages() { + UMLRTProtocol protocol = getProtocol("Protocol1"); + List<UMLRTProtocolMessage> messages = protocol.getMessages(); + assertThat(messages.isEmpty(), is(false)); + assertThat(messages.get(0).getName(), is("greet")); + assertThat(messages.get(0).getKind(), is(RTMessageKind.IN)); + assertThat(messages.get(0).toReceiveEvent(), notNullValue()); + } + + @Test + public void getMessage() { + UMLRTProtocol protocol = getProtocol("Protocol1"); + + UMLRTProtocolMessage message = protocol.getMessage("greet"); + assertThat(message, notNullValue()); + + message = protocol.getMessage("foo"); + assertThat(message, nullValue()); + } + + @Test + public void getMessageByKind() { + UMLRTProtocol protocol = getProtocol("Protocol1"); + + UMLRTProtocolMessage message = protocol.getMessage(RTMessageKind.IN, "greet"); + assertThat(message, notNullValue()); + + message = protocol.getMessage(RTMessageKind.OUT, "greet"); + assertThat(message, nullValue()); + } + + @Test + public void createMessage() { + UMLRTProtocol protocol = getProtocol("Protocol1"); + + UMLRTProtocolMessage message = protocol.createMessage(RTMessageKind.OUT, "status", + (PrimitiveType) fixture.getModel().getMember("Integer")); + + assertThat(message, notNullValue()); + assertThat(message.getKind(), is(RTMessageKind.OUT)); + assertThat(message.toUML().getInterface().getName(), is("Protocol1~")); + assertThat(message.toUML().getOwnedParameters().size(), is(1)); + assertThat(message.toUML().getOwnedParameters().get(0).getName(), is("data")); + assertThat(message.toUML().getOwnedParameters().get(0).getType().getName(), is("Integer")); + assertThat(message.toReceiveEvent(), notNullValue()); + } + + @Test + public void setMessageKind() { + UMLRTProtocol protocol = getProtocol("Protocol1"); + + UMLRTProtocolMessage message = protocol.getMessage(RTMessageKind.IN, "greet"); + assumeThat(message, notNullValue()); + + message.setKind(RTMessageKind.OUT); + + assertThat(message.getKind(), is(RTMessageKind.OUT)); + assertThat(message.toUML().getInterface().getName(), is("Protocol1~")); + assertThat(message.toUML().getOwnedParameters().size(), is(1)); + assertThat(message.toUML().getOwnedParameters().get(0).getName(), is("data")); + assertThat(message.toUML().getOwnedParameters().get(0).getType().getName(), is("String")); + } + + @Test + public void inheritance() { + UMLRTProtocol protocol1 = getProtocol("Protocol1"); + UMLRTProtocol protocol2 = getProtocol("Protocol2"); + + assertThat(protocol2.getSuperProtocol(), nullValue()); + + protocol2.setSuperProtocol(protocol1); + assertThat(protocol2.getSuperProtocol(), is(protocol1)); + + // Inherited messages + List<UMLRTProtocolMessage> messages = protocol2.getMessages(); + assertThat(messages.isEmpty(), is(false)); + assertThat(messages.get(0).getName(), is("greet")); + assertThat(messages.get(0).toUML().isSetName(), is(false)); + assertThat(protocol2.getMessage("greet").toUML(), redefines(protocol1.getMessage("greet").toUML())); + + // Message sets + Interface in = fixture.getElement("Protocol2::Protocol2", Interface.class); + Interface out = fixture.getElement("Protocol2::Protocol2~", Interface.class); + Interface inout = fixture.getElement("Protocol2::Protocol2IO", Interface.class); + assertThat(in.getGenerals(), hasItem(named("Protocol1"))); + assertThat(out.getGenerals(), hasItem(named("Protocol1~"))); + assertThat(inout.getGenerals(), hasItem(named("Protocol1IO"))); + + // Clear the super + protocol2.setSuperProtocol(null); + assertThat(protocol2.getSuperProtocol(), nullValue()); + assertThat(in.getGenerals().isEmpty(), is(true)); + assertThat(out.getGenerals().isEmpty(), is(true)); + assertThat(inout.getGenerals().isEmpty(), is(true)); + assertThat(protocol2.getMessages().isEmpty(), is(true)); + } + + @Test + public void inheritanceViaUML() { + UMLRTProtocol protocol1 = getProtocol("Protocol1"); + UMLRTProtocol protocol2 = getProtocol("Protocol2"); + + assertThat(protocol2.getSuperProtocol(), nullValue()); + + // Via the UML API + protocol2.toUML().createGeneralization(protocol1.toUML()); + assertThat(protocol2.getSuperProtocol(), is(protocol1)); + + // Inherited messages + List<UMLRTProtocolMessage> messages = protocol2.getMessages(); + assertThat(messages.isEmpty(), is(false)); + assertThat(messages.get(0).getName(), is("greet")); + assertThat(messages.get(0).toUML().isSetName(), is(false)); + assertThat(protocol2.getMessage("greet").toUML(), redefines(protocol1.getMessage("greet").toUML())); + + // Message sets + Interface in = fixture.getElement("Protocol2::Protocol2", Interface.class); + Interface out = fixture.getElement("Protocol2::Protocol2~", Interface.class); + Interface inout = fixture.getElement("Protocol2::Protocol2IO", Interface.class); + assertThat(in.getGenerals(), hasItem(named("Protocol1"))); + assertThat(out.getGenerals(), hasItem(named("Protocol1~"))); + assertThat(inout.getGenerals(), hasItem(named("Protocol1IO"))); + + // Clear the super + protocol2.setSuperProtocol(null); + assertThat(protocol2.getSuperProtocol(), nullValue()); + assertThat(in.getGenerals().isEmpty(), is(true)); + assertThat(out.getGenerals().isEmpty(), is(true)); + assertThat(inout.getGenerals().isEmpty(), is(true)); + assertThat(protocol2.getMessages().isEmpty(), is(true)); + } + + @Test + public void newMessageInherited() { + UMLRTProtocol protocol1 = getProtocol("Protocol1"); + UMLRTProtocol protocol2 = getProtocol("Protocol2"); + + protocol2.setSuperProtocol(protocol1); + assumeThat(protocol2.getSuperProtocol(), is(protocol1)); + + UMLRTProtocolMessage newMessage = protocol1.createMessage(RTMessageKind.OUT, "reply"); + + UMLRTProtocolMessage inherited = protocol2.getMessage("reply"); + assertThat(inherited, notNullValue()); + assertThat(inherited.getKind(), is(RTMessageKind.OUT)); + assertThat(inherited.toUML(), redefines(newMessage.toUML())); + assertThat(inherited.getInheritedElement(), is(newMessage)); + } + + @Test + public void messageParameters() { + UMLRTProtocol protocol1 = getProtocol("Protocol1"); + UMLRTProtocol protocol2 = getProtocol("Protocol2"); + + protocol2.setSuperProtocol(protocol1); + assumeThat(protocol2.getSuperProtocol(), is(protocol1)); + + UMLRTProtocolMessage newMessage = protocol1.createMessage(RTMessageKind.OUT, "reply"); + + UMLRTProtocolMessage inherited = protocol2.getMessage("reply"); + assumeThat(inherited, notNullValue()); + + Type stringType = (PrimitiveType) fixture.getModel().getMember("String"); + newMessage.createParameter("text", stringType); + + Parameter text = inherited.getParameter("text"); + assertThat(text, notNullValue()); + assertThat(UMLRTExtensionUtil.isVirtualElement(text), is(true)); // It's inherited + + assertThat(inherited.getParameter(stringType), is(text)); + assertThat(inherited.getParameters(), hasItem(text)); + } + + @Test + public void conjugation() { + UMLRTProtocol protocol1 = getProtocol("Protocol1"); + assertThat(protocol1.isConjugate(), is(false)); + + UMLRTProtocol protocol1_ = protocol1.getConjugate(); + assertThat(protocol1_.isConjugate(), is(true)); + assertThat(protocol1_.getConjugate(), is(protocol1)); + assertThat("Conjugate not cached", protocol1.getConjugate(), sameInstance(protocol1_)); + assertThat(protocol1_.getName(), is("Protocol1~")); + + protocol1_.setName("MyProtocol~"); + assertThat(protocol1.getName(), is("MyProtocol")); + } + + @Test + public void messageParameterInheritance() { + UMLRTProtocol protocol1 = getProtocol("Protocol1"); + UMLRTProtocol protocol2 = getProtocol("Protocol2"); + + assertThat(protocol2.getSuperProtocol(), nullValue()); + + protocol2.setSuperProtocol(protocol1); + assumeThat(protocol2.getSuperProtocol(), is(protocol1)); + + // Inherited message parameters + List<UMLRTProtocolMessage> messages = protocol2.getMessages(); + assumeThat(messages.isEmpty(), is(false)); + assumeThat(messages.get(0).getName(), is("greet")); + + EList<Parameter> parameters = messages.get(0).toUML().getOwnedParameters(); + assertThat(parameters, hasItem(named("data"))); + Parameter data = parameters.get(0); + assertThat(data.isSetName(), is(false)); + assertThat(data.getName(), is("data")); + } + + @Test + public void messageReification() { + UMLRTProtocol protocol1 = getProtocol("Protocol1"); + UMLRTProtocol protocol2 = getProtocol("Protocol2"); + + assertThat(protocol2.getSuperProtocol(), nullValue()); + + protocol2.setSuperProtocol(protocol1); + assumeThat(protocol2.getSuperProtocol(), is(protocol1)); + + // Inherited message + List<UMLRTProtocolMessage> messages = protocol2.getMessages(); + assumeThat(messages.isEmpty(), is(false)); + assumeThat(messages.get(0).getName(), is("greet")); + + Operation operation = messages.get(0).toUML(); + + assumeThat(UMLRTExtensionUtil.isVirtualElement(operation), is(true)); + + // This reifies the operation + ChangeRecorder recorder = new ChangeRecorder(fixture.getResource()); + operation.setName("sayHello"); + ChangeDescription change = recorder.endRecording(); + + assertThat(UMLRTExtensionUtil.isVirtualElement(operation), is(false)); + + // Must be careful not to reify the operation by mistake + UMLRTExtensionUtil.run(operation, change::applyAndReverse); + + // The operation was un-reified + assertThat(UMLRTExtensionUtil.isVirtualElement(operation), is(true)); + + // Must be careful not to reify the operation by mistake + UMLRTExtensionUtil.run(operation, change::apply); + + // The operation was re-reified + assertThat(UMLRTExtensionUtil.isVirtualElement(operation), is(false)); + } + + @Test + public void messageReificationByParameter() { + UMLRTProtocol protocol1 = getProtocol("Protocol1"); + UMLRTProtocol protocol2 = getProtocol("Protocol2"); + + assertThat(protocol2.getSuperProtocol(), nullValue()); + + protocol2.setSuperProtocol(protocol1); + assumeThat(protocol2.getSuperProtocol(), is(protocol1)); + + // Inherited message parameters + List<UMLRTProtocolMessage> messages = protocol2.getMessages(); + assumeThat(messages.isEmpty(), is(false)); + assumeThat(messages.get(0).getName(), is("greet")); + + Operation operation = messages.get(0).toUML(); + Parameter parameter = operation.getOwnedParameter("data", null); + + assumeThat(UMLRTExtensionUtil.isVirtualElement(operation), is(true)); + assumeThat(UMLRTExtensionUtil.isVirtualElement(parameter), is(true)); + + // This reifies both parameter (actually, all parameters) and operation + ChangeRecorder recorder = new ChangeRecorder(Arrays.asList(fixture.getResource(), parameter)); + parameter.setName("foo"); + ChangeDescription change = recorder.endRecording(); + + assertThat(UMLRTExtensionUtil.isVirtualElement(parameter), is(false)); + assertThat(UMLRTExtensionUtil.isVirtualElement(operation), is(false)); + + // Must be careful not to reify the element by mistake + UMLRTExtensionUtil.run(parameter, change::applyAndReverse); + + // The elements were un-reified + assertThat(UMLRTExtensionUtil.isVirtualElement(operation), is(true)); + assertThat(UMLRTExtensionUtil.isVirtualElement(parameter), is(true)); + + // Must be careful not to reify the element by mistake + UMLRTExtensionUtil.run(parameter, change::apply); + + // The elements were re-reified + assertThat(UMLRTExtensionUtil.isVirtualElement(operation), is(false)); + assertThat(UMLRTExtensionUtil.isVirtualElement(parameter), is(false)); + } + + @Test + public void superprotocolWithConjugation() { + UMLRTProtocol protocol1 = getProtocol("Protocol1").getConjugate(); + UMLRTProtocol protocol2 = getProtocol("Protocol2").getConjugate(); + UMLRTProtocol protocol3 = createProtocol("Protocol3").getConjugate(); + + protocol2.toUML().createGeneralization(protocol1.toUML()); + protocol3.toUML().createGeneralization(protocol2.toUML()); + + assertThat(protocol1.getSuperProtocol(), nullValue()); + assertThat(protocol2.getSuperProtocol(), is(protocol1)); + assertThat(protocol3.getSuperProtocol(), is(protocol2)); + } + + @Test + public void subprotocols() { + UMLRTProtocol protocol1 = getProtocol("Protocol1"); + UMLRTProtocol protocol2 = getProtocol("Protocol2"); + UMLRTProtocol protocol3 = createProtocol("Protocol3"); + + protocol2.toUML().createGeneralization(protocol1.toUML()); + protocol3.toUML().createGeneralization(protocol2.toUML()); + + assertThat(protocol1.getSubProtocols(), is(Arrays.asList(protocol2))); + assertThat(protocol2.getSubProtocols(), is(Arrays.asList(protocol3))); + } + + @Test + public void subprotocolsWithConjugation() { + UMLRTProtocol protocol1 = getProtocol("Protocol1").getConjugate(); + UMLRTProtocol protocol2 = getProtocol("Protocol2").getConjugate(); + UMLRTProtocol protocol3 = createProtocol("Protocol3").getConjugate(); + + protocol2.toUML().createGeneralization(protocol1.toUML()); + protocol3.toUML().createGeneralization(protocol2.toUML()); + + assertThat(protocol1.getSubProtocols(), is(Arrays.asList(protocol2))); + assertThat(protocol2.getSubProtocols(), is(Arrays.asList(protocol3))); + } + + @Test + public void hierarchy() { + UMLRTProtocol protocol1 = getProtocol("Protocol1"); + UMLRTProtocol protocol2 = getProtocol("Protocol2"); + UMLRTProtocol protocol3 = createProtocol("Protocol3"); + + protocol2.toUML().createGeneralization(protocol1.toUML()); + protocol3.toUML().createGeneralization(protocol2.toUML()); + + assertThat(protocol1.getHierarchy().collect(toList()), + is(Arrays.asList(protocol1, protocol2, protocol3))); + assertThat(protocol2.getHierarchy().collect(toList()), + is(Arrays.asList(protocol2, protocol3))); + } + + @Test + public void hierarchyWithConjugation() { + UMLRTProtocol protocol1 = getProtocol("Protocol1").getConjugate(); + UMLRTProtocol protocol2 = getProtocol("Protocol2").getConjugate(); + UMLRTProtocol protocol3 = createProtocol("Protocol3").getConjugate(); + + protocol2.toUML().createGeneralization(protocol1.toUML()); + protocol3.toUML().createGeneralization(protocol2.toUML()); + + assertThat(protocol1.getHierarchy().collect(toList()), + is(Arrays.asList(protocol1, protocol2, protocol3))); + assertThat(protocol2.getHierarchy().collect(toList()), + is(Arrays.asList(protocol2, protocol3))); + } + + // + // Test framework + // + + UMLRTProtocol getProtocol(String name) { + return UMLRTPackage.getInstance(fixture.getModel()).getProtocol(name); + } + + UMLRTProtocol createProtocol(String name) { + return UMLRTPackage.getInstance(fixture.getModel()).createProtocol(name); + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ProtocolMessageConjugationTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ProtocolMessageConjugationTest.java new file mode 100644 index 000000000..4633ffb4c --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ProtocolMessageConjugationTest.java @@ -0,0 +1,195 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static org.eclipse.papyrusrt.umlrt.uml.tests.util.UMLMatchers.named; +import static org.hamcrest.CoreMatchers.anything; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.sameInstance; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeThat; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; + +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTMessageKind; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocol; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocolMessage; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.uml2.uml.Interface; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +/** + * Test cases for working with messages in conjugate {@link UMLRTProtocol}s. + */ +@TestModel("inheritance/ports.uml") +@RunWith(Parameterized.class) +public class ProtocolMessageConjugationTest { + + @Rule + public final ModelFixture fixture = new ModelFixture(); + + private final RTMessageKind kind; + private final RTMessageKind conjKind; + + public ProtocolMessageConjugationTest(RTMessageKind kind) { + super(); + + this.kind = kind; + this.conjKind = (kind == RTMessageKind.IN) + ? RTMessageKind.OUT + : (kind == RTMessageKind.OUT) + ? RTMessageKind.IN + : kind; + } + + @Test + public void conjugation() { + UMLRTProtocol protocol1 = getProtocol("Protocol1"); + assumeThat(protocol1.isConjugate(), is(false)); + + UMLRTProtocol protocol1_ = protocol1.getConjugate(); + assumeThat(protocol1_.isConjugate(), is(true)); + + UMLRTProtocolMessage msg = protocol1.createMessage(kind, "newmsg"); + UMLRTProtocolMessage msg_ = protocol1_.getMessage("newmsg"); + assertThat(msg_.getKind(), is(conjKind)); + assertThat("Message conjugate not cached", protocol1_.getMessage("newmsg"), sameInstance(msg_)); + + msg_.setKind(kind); + assertThat(msg.getKind(), is(conjKind)); + String expectedInterface = interfaceName("Protocol1", conjKind); + assertThat("Message not moved in UML", msg.toUML().getInterface(), named(expectedInterface)); + } + + @Test + public void getMessagesByKind() { + UMLRTProtocol protocol1 = getProtocol("Protocol1"); + assumeThat(protocol1.isConjugate(), is(false)); + + UMLRTProtocol protocol1_ = protocol1.getConjugate(); + assumeThat(protocol1_.isConjugate(), is(true)); + + // Create a message using UML API for test independence + Interface interface_ = fixture.getElement("Protocol1::" + interfaceName("Protocol1", conjKind), Interface.class); + interface_.createOwnedOperation("newmsg", null, null); + + // Get messages from the conjugate + List<UMLRTProtocolMessage> messages = protocol1_.getMessages(kind); + assertThat(messages, hasItem(anything())); + UMLRTProtocolMessage msg = messages.stream() + .filter(m -> m.getName().equals("newmsg")) + .findFirst().get(); // Asserts that it is there + assertThat(msg.getKind(), is(kind)); + } + + @Test + public void getMessageByKindAndName() { + UMLRTProtocol protocol1 = getProtocol("Protocol1"); + assumeThat(protocol1.isConjugate(), is(false)); + + UMLRTProtocol protocol1_ = protocol1.getConjugate(); + assumeThat(protocol1_.isConjugate(), is(true)); + + // Create a message using UML API for test independence + Interface interface_ = fixture.getElement("Protocol1::" + interfaceName("Protocol1", conjKind), Interface.class); + interface_.createOwnedOperation("newmsg", null, null); + + // Get message from the conjugate + UMLRTProtocolMessage message = protocol1_.getMessage(kind, "newmsg"); + assertThat(message, notNullValue()); + assertThat(message.getKind(), is(kind)); + } + + @Test + public void createMessage() { + assertNewConjugatedMessage(protocol -> protocol.createMessage(kind, "foo")); + } + + void assertNewConjugatedMessage(Function<UMLRTProtocol, UMLRTProtocolMessage> factory) { + UMLRTProtocol protocol1 = getProtocol("Protocol1"); + assumeThat(protocol1.isConjugate(), is(false)); + + UMLRTProtocol protocol1_ = protocol1.getConjugate(); + assumeThat(protocol1_.isConjugate(), is(true)); + + UMLRTProtocolMessage newMessage = factory.apply(protocol1_); + assertThat(newMessage.getKind(), is(kind)); + + String expectedInterface = interfaceName("Protocol1", conjKind); + assertThat(newMessage.toUML().getInterface(), named(expectedInterface)); + } + + @Test + public void conjugationCreateMessageWithData() { + assertNewConjugatedMessage(protocol -> protocol.createMessage(kind, "foo", fixture.getElement("YesNo"))); + } + + @Test + public void conjugationCreateMessageWithParameters() { + assertNewConjugatedMessage(protocol -> protocol.createMessage(kind, "foo", + Arrays.asList("yesno"), Arrays.asList(fixture.getElement("YesNo")))); + } + + // + // Test framework + // + + @Parameters(name = "{0}") + public static Iterable<Object[]> parameters() { + return Arrays.asList(new Object[][] { + { RTMessageKind.IN }, + { RTMessageKind.OUT }, + { RTMessageKind.IN_OUT }, + }); + } + + String interfaceName(String protocolName, RTMessageKind kind) { + String result; + + switch (conjKind) { + case IN: + // It's actually an IN message in the model + result = protocolName; + break; + case OUT: + // It's actually an OUT message in the model + result = protocolName + "~"; + break; + case IN_OUT: + // Idempotent under conjugation + result = protocolName + "IO"; + break; + default: + fail("Invalid message kind: " + kind); + throw new Error(); // Unreachable + } + + return result; + } + + UMLRTProtocol getProtocol(String name) { + return UMLRTPackage.getInstance(fixture.getModel()).getProtocol(name); + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ReificationTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ReificationTest.java new file mode 100644 index 000000000..4ac74d980 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ReificationTest.java @@ -0,0 +1,303 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assume.assumeThat; + +import java.util.Arrays; +import java.util.function.Function; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.change.ChangeDescription; +import org.eclipse.emf.ecore.change.util.ChangeRecorder; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTNamedElement; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.ExtUMLExtPackage; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.util.UMLRTExtensionUtil; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Connector; +import org.eclipse.uml2.uml.MultiplicityElement; +import org.eclipse.uml2.uml.NamedElement; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.Property; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +/** + * Test cases for the automatic reification of implicit members on edit. + */ +@RunWith(Parameterized.class) +public class ReificationTest { + + @Rule + public final ModelFixture fixture; + + private EReference extension; + private Function<Class, EList<NamedElement>> ownedListAccessor; + private Function<UMLRTCapsule, UMLRTNamedElement> newElementCreator; + + public ReificationTest(String testModelPath, EReference extension, + Function<Class, EList<NamedElement>> ownedListAccessor, + Function<UMLRTCapsule, UMLRTNamedElement> newElementCreator) { + + super(); + + this.fixture = new ModelFixture(testModelPath); + this.extension = extension; + this.ownedListAccessor = ownedListAccessor; + this.newElementCreator = newElementCreator; + } + + @Test + public void autoReifyElement() { + Class capsule = fixture.getElement("RootCapsule"); + + @SuppressWarnings("unchecked") + EList<NamedElement> implicitElements = (EList<NamedElement>) capsule.eGet(extension); + NamedElement newElement = fixture.create(extension.getEReferenceType(), "newElement"); + implicitElements.add(newElement); + + assumeThat(capsule.getOwnedMembers(), hasItem(newElement)); + + newElement.setName("myElement"); + + assertThat(ownedListAccessor.apply(capsule), hasItem(newElement)); + assertThat(implicitElements, not(hasItem(newElement))); + + assertThat(UMLRTExtensionUtil.isVirtualElement(newElement), is(false)); + } + + @Test + public void reinheritElement() { + Class capsule = fixture.getElement("RootCapsule"); + Class subcapsule = fixture.getElement("Subcapsule"); + UMLRTNamedElement newElement = newElementCreator.apply(UMLRTCapsule.getInstance(capsule)); + NamedElement inherited = UMLRTCapsule.getInstance(subcapsule).getRedefinitionOf(newElement).toUML(); + + @SuppressWarnings("unchecked") + EList<NamedElement> implicitElements = (EList<NamedElement>) subcapsule.eGet(extension); + + assumeThat(implicitElements, hasItem(inherited)); + assumeThat(ownedListAccessor.apply(subcapsule), not(hasItem(inherited))); + assumeThat(UMLRTExtensionUtil.isVirtualElement(inherited), is(true)); + + inherited.setName("myElement"); + + assumeThat(implicitElements, not(hasItem(inherited))); + assumeThat(ownedListAccessor.apply(subcapsule), hasItem(inherited)); + assumeThat(UMLRTExtensionUtil.isVirtualElement(inherited), is(false)); + + ((InternalUMLRTElement) inherited).rtReinherit(); + + // The element was un-reified + assertThat(implicitElements, hasItem(inherited)); + assertThat(ownedListAccessor.apply(subcapsule), not(hasItem(inherited))); + assertThat(UMLRTExtensionUtil.isVirtualElement(inherited), is(true)); + + // And the name was unset + assertThat(inherited.isSetName(), is(false)); + assertThat(inherited.getName(), is(newElement.getName())); // Inherited + } + + @Test + public void undoRedoAutoReifyElement() { + Class capsule = fixture.getElement("RootCapsule"); + + @SuppressWarnings("unchecked") + EList<NamedElement> implicitElements = (EList<NamedElement>) capsule.eGet(extension); + NamedElement newElement = fixture.create(extension.getEReferenceType(), "newElement"); + implicitElements.add(newElement); + + assumeThat(capsule.getOwnedMembers(), hasItem(newElement)); + + ChangeRecorder recorder = new ChangeRecorder(fixture.getResource()); + newElement.setName("myElement"); + ChangeDescription change = recorder.endRecording(); + + assumeThat(ownedListAccessor.apply(capsule), hasItem(newElement)); + assumeThat(UMLRTExtensionUtil.isVirtualElement(newElement), is(false)); + + // Must be careful not to reify the element by mistake + UMLRTExtensionUtil.run(newElement, change::applyAndReverse); + + // The element was un-reified + assertThat(implicitElements, hasItem(newElement)); + assertThat(ownedListAccessor.apply(capsule), not(hasItem(newElement))); + assertThat(UMLRTExtensionUtil.isVirtualElement(newElement), is(true)); + + // Must be careful not to reify the element by mistake + UMLRTExtensionUtil.run(newElement, change::apply); + + // The element was re-reified + assertThat(implicitElements, not(hasItem(newElement))); + assertThat(ownedListAccessor.apply(capsule), hasItem(newElement)); + assertThat(UMLRTExtensionUtil.isVirtualElement(newElement), is(false)); + } + + @Test + public void autoReifyElementByMultiplicityBound() { + Class capsule = fixture.getElement("RootCapsule"); + Class subcapsule = fixture.getElement("Subcapsule"); + UMLRTNamedElement newElement = newElementCreator.apply(UMLRTCapsule.getInstance(capsule)); + + MultiplicityElement mult = getMultiplicityElement(newElement.toUML()); + mult.setLower(2); + mult.setUpper(2); + + NamedElement inherited = UMLRTCapsule.getInstance(subcapsule).getRedefinitionOf(newElement).toUML(); + mult = getMultiplicityElement(inherited); + mult.setUpper(7); + + // It was reified + assertThat(ownedListAccessor.apply(subcapsule), hasItem(inherited)); + assertThat(UMLRTExtensionUtil.isVirtualElement(inherited), is(false)); + } + + @Test + public void reificationListener() { + UMLRTPackage package_ = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = package_.getCapsule("RootCapsule"); + + @SuppressWarnings("unchecked") + EList<NamedElement> implicitElements = (EList<NamedElement>) capsule.toUML().eGet(extension); + UMLRTNamedElement newElement = newElementCreator.apply(capsule); + implicitElements.add(newElement.toUML()); // Forcibly virtualize it + + Boolean[] callback = { null }; + newElement.addReificationListener((element, reified) -> callback[0] = reified); + + ChangeRecorder recorder = new ChangeRecorder(fixture.getResource()); + newElement.setName("myElement"); + ChangeDescription change = recorder.endRecording(); + + assertThat("No reification event", callback[0], is(Boolean.TRUE)); + callback[0] = null; + + // Must be careful not to reify the element by mistake + UMLRTExtensionUtil.run(newElement, change::applyAndReverse); + + assertThat("No un-reification event", callback[0], is(Boolean.FALSE)); + callback[0] = null; + + // Must be careful not to reify the element by mistake + UMLRTExtensionUtil.run(newElement, change::apply); + + assertThat("No reification event", callback[0], is(Boolean.TRUE)); + } + + @Test + public void reificationListenerByMultiplicityBound() { + UMLRTPackage package_ = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = package_.getCapsule("RootCapsule"); + UMLRTCapsule subcapsule = package_.getCapsule("Subcapsule"); + + UMLRTNamedElement newElement = newElementCreator.apply(capsule); + MultiplicityElement mult = getMultiplicityElement(newElement.toUML()); + mult.setLower(2); + mult.setUpper(2); + + UMLRTNamedElement inherited = subcapsule.getRedefinitionOf(newElement); + + Boolean[] callback = { null }; + inherited.addReificationListener((element, reified) -> callback[0] = reified); + + + ChangeRecorder recorder = new ChangeRecorder(fixture.getResource()); + mult = getMultiplicityElement(inherited.toUML()); + mult.setUpper(7); + ChangeDescription change = recorder.endRecording(); + + assertThat("No reification event", callback[0], is(Boolean.TRUE)); + callback[0] = null; + + // Must be careful not to reify the element by mistake + UMLRTExtensionUtil.run(inherited, change::applyAndReverse); + + assertThat("No un-reification event", callback[0], is(Boolean.FALSE)); + callback[0] = null; + + // Must be careful not to reify the element by mistake + UMLRTExtensionUtil.run(inherited, change::apply); + + assertThat("No reification event", callback[0], is(Boolean.TRUE)); + } + + @Test + public void deletedElementIsNotReified() { + UMLRTPackage package_ = UMLRTPackage.getInstance(fixture.getModel()); + UMLRTCapsule capsule = package_.getCapsule("RootCapsule"); + UMLRTNamedElement newElement = newElementCreator.apply(capsule); + + @SuppressWarnings("unchecked") + EList<NamedElement> implicitElements = (EList<NamedElement>) capsule.toUML().eGet(extension); + implicitElements.add(newElement.toUML()); // Forcibly virtualize it + + Boolean[] callback = { null }; + newElement.addReificationListener((element, reified) -> callback[0] = reified); + + // Don't do newPort.destroy() because that does much else besides detaching the element + EcoreUtil.remove(newElement.toUML()); + + assertThat("Got reification event", callback[0], nullValue()); + } + + // + // Test framework + // + + @Parameters(name = "{index}: {0}") + public static Iterable<Object[]> parameters() { + return Arrays.asList(new Object[][] { + // Test cases for port inheritance + { "inheritance/ports.uml", ExtUMLExtPackage.Literals.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT, + (Function<Class, EList<Port>>) Class::getOwnedPorts, + (Function<UMLRTCapsule, UMLRTNamedElement>) capsule -> capsule.createPort(capsule.getPackage().createProtocol("NewProtocol")) }, + // Test cases for capsule-part inheritance + { "inheritance/parts.uml", ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE, + (Function<Class, EList<Property>>) Class::getOwnedAttributes, + (Function<UMLRTCapsule, UMLRTNamedElement>) capsule -> capsule.createCapsulePart(capsule.getPackage().createCapsule("NewCapsule")) }, + // Test cases for capsule-part inheritance + { "inheritance/connectors.uml", ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR, + (Function<Class, EList<Connector>>) Class::getOwnedConnectors, + (Function<UMLRTCapsule, UMLRTNamedElement>) capsule -> capsule.createConnector("NewConnector", capsule.getPorts().get(0), null, capsule.getCapsuleParts().get(0).getType().getPorts().get(0), capsule.getCapsuleParts().get(0)) }, + }); + } + + MultiplicityElement getMultiplicityElement(NamedElement element) { + MultiplicityElement result = null; + + if (element instanceof MultiplicityElement) { + result = (MultiplicityElement) element; + } else if (element instanceof Connector) { + result = ((Connector) element).getEnds().get(0); + } + + assertThat("No multiplicity element", result, notNullValue()); + return result; + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/StereotypeInheritanceNotificationTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/StereotypeInheritanceNotificationTest.java new file mode 100644 index 000000000..bcdd1f8ac --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/StereotypeInheritanceNotificationTest.java @@ -0,0 +1,196 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static org.eclipse.uml2.uml.util.UMLUtil.getStereotypeApplication; +import static org.hamcrest.CoreMatchers.anything; +import static org.hamcrest.CoreMatchers.is; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.PortRegistrationType; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTPort; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.uml2.uml.Class; +import org.junit.Rule; +import org.junit.Test; + +/** + * Test cases for notifications from inherited features in stereotypes of redefinitions. + */ +@TestModel("inheritance/ports.uml") +public class StereotypeInheritanceNotificationTest { + + @Rule + public final ModelFixture fixture = new ModelFixture(); + + public StereotypeInheritanceNotificationTest() { + super(); + } + + @Test + public void notificationNotification() { + Class root = fixture.getElement("RootCapsule"); + RTPort redefined = getStereotypeApplication(root.getOwnedPorts().get(0), RTPort.class); + boolean oldNotification = redefined.isNotification(); + + Class subsub = fixture.getElement("Subsubcapsule"); + RTPort port = getStereotypeApplication(subsub.getOwnedPorts().get(0), RTPort.class); + + fixture.expectNotification(port, UMLRealTimePackage.Literals.RT_PORT__IS_NOTIFICATION, + Notification.SET, is(oldNotification), is(true), + () -> redefined.setIsNotification(true)); + } + + @Test + public void publishNotification() { + Class root = fixture.getElement("RootCapsule"); + RTPort redefined = getStereotypeApplication(root.getOwnedPorts().get(0), RTPort.class); + boolean oldPublish = redefined.isPublish(); + + Class subsub = fixture.getElement("Subsubcapsule"); + RTPort port = getStereotypeApplication(subsub.getOwnedPorts().get(0), RTPort.class); + + fixture.expectNotification(port, UMLRealTimePackage.Literals.RT_PORT__IS_PUBLISH, + Notification.SET, is(oldPublish), is(true), + () -> redefined.setIsPublish(true)); + } + + @Test + public void wiredNotification() { + Class root = fixture.getElement("RootCapsule"); + RTPort redefined = getStereotypeApplication(root.getOwnedPorts().get(0), RTPort.class); + boolean oldWired = redefined.isWired(); + + Class subsub = fixture.getElement("Subsubcapsule"); + RTPort port = getStereotypeApplication(subsub.getOwnedPorts().get(0), RTPort.class); + + fixture.expectNotification(port, UMLRealTimePackage.Literals.RT_PORT__IS_WIRED, + Notification.SET, is(oldWired), is(false), + () -> redefined.setIsWired(false)); + } + + @Test + public void registrationNotification() { + Class root = fixture.getElement("RootCapsule"); + RTPort redefined = getStereotypeApplication(root.getOwnedPorts().get(0), RTPort.class); + PortRegistrationType oldRegistration = redefined.getRegistration(); + + Class subsub = fixture.getElement("Subsubcapsule"); + RTPort port = getStereotypeApplication(subsub.getOwnedPorts().get(0), RTPort.class); + + fixture.expectNotification(port, UMLRealTimePackage.Literals.RT_PORT__REGISTRATION, + Notification.SET, is(oldRegistration), is(PortRegistrationType.APPLICATION), + () -> redefined.setRegistration(PortRegistrationType.APPLICATION)); + } + + @Test + public void registrationOverrideNotification() { + Class root = fixture.getElement("RootCapsule"); + RTPort redefined = getStereotypeApplication(root.getOwnedPorts().get(0), RTPort.class); + String oldRegistrationOverride = redefined.getRegistrationOverride(); + + Class subsub = fixture.getElement("Subsubcapsule"); + RTPort port = getStereotypeApplication(subsub.getOwnedPorts().get(0), RTPort.class); + + fixture.expectNotification(port, UMLRealTimePackage.Literals.RT_PORT__REGISTRATION_OVERRIDE, + Notification.SET, is(oldRegistrationOverride), is("foo"), + () -> redefined.setRegistrationOverride("foo")); + } + + @Test + public void notificationRedefined() { + Class root = fixture.getElement("RootCapsule"); + RTPort redefined = getStereotypeApplication(root.getOwnedPorts().get(0), RTPort.class); + + Class subsub = fixture.getElement("Subsubcapsule"); + RTPort port = getStereotypeApplication(subsub.getOwnedPorts().get(0), RTPort.class); + port.setIsNotification(true); + + fixture.expectNoNotification(port, UMLRealTimePackage.Literals.RT_PORT__IS_NOTIFICATION, + Notification.SET, anything(), is(true), + () -> redefined.setIsNotification(true)); + } + + @Test + public void publishRedefined() { + Class root = fixture.getElement("RootCapsule"); + RTPort redefined = getStereotypeApplication(root.getOwnedPorts().get(0), RTPort.class); + + Class subsub = fixture.getElement("Subsubcapsule"); + RTPort port = getStereotypeApplication(subsub.getOwnedPorts().get(0), RTPort.class); + port.setIsPublish(true); + + fixture.expectNoNotification(port, UMLRealTimePackage.Literals.RT_PORT__IS_PUBLISH, + Notification.SET, anything(), is(true), + () -> redefined.setIsPublish(true)); + } + + @Test + public void wiredRedefined() { + Class root = fixture.getElement("RootCapsule"); + RTPort redefined = getStereotypeApplication(root.getOwnedPorts().get(0), RTPort.class); + + Class subsub = fixture.getElement("Subsubcapsule"); + RTPort port = getStereotypeApplication(subsub.getOwnedPorts().get(0), RTPort.class); + port.setIsWired(false); + + fixture.expectNoNotification(port, UMLRealTimePackage.Literals.RT_PORT__IS_WIRED, + Notification.SET, anything(), is(false), + () -> redefined.setIsWired(false)); + } + + @Test + public void registrationRedefined() { + Class root = fixture.getElement("RootCapsule"); + RTPort redefined = getStereotypeApplication(root.getOwnedPorts().get(0), RTPort.class); + + Class subsub = fixture.getElement("Subsubcapsule"); + RTPort port = getStereotypeApplication(subsub.getOwnedPorts().get(0), RTPort.class); + port.setRegistration(PortRegistrationType.AUTOMATIC_LOCKED); + + fixture.expectNoNotification(port, UMLRealTimePackage.Literals.RT_PORT__REGISTRATION, + Notification.SET, anything(), is(PortRegistrationType.APPLICATION), + () -> redefined.setRegistration(PortRegistrationType.APPLICATION)); + } + + @Test + public void registrationOverrideRedefined() { + Class root = fixture.getElement("RootCapsule"); + RTPort redefined = getStereotypeApplication(root.getOwnedPorts().get(0), RTPort.class); + + Class subsub = fixture.getElement("Subsubcapsule"); + RTPort port = getStereotypeApplication(subsub.getOwnedPorts().get(0), RTPort.class); + port.setRegistrationOverride("bar"); + + fixture.expectNoNotification(port, UMLRealTimePackage.Literals.RT_PORT__REGISTRATION_OVERRIDE, + Notification.SET, anything(), is("foo"), + () -> redefined.setRegistrationOverride("foo")); + } + + @Test + public void redefinitionRemoved() { + Class root = fixture.getElement("RootCapsule"); + RTPort redefined = getStereotypeApplication(root.getOwnedPorts().get(0), RTPort.class); + + Class subsub = fixture.getElement("Subsubcapsule"); + RTPort port = getStereotypeApplication(subsub.getOwnedPorts().get(0), RTPort.class); + port.getBase_Port().getRedefinedPorts().clear(); + + fixture.expectNoNotification(port, UMLRealTimePackage.Literals.RT_PORT__REGISTRATION, + Notification.SET, anything(), is(PortRegistrationType.APPLICATION), + () -> redefined.setRegistration(PortRegistrationType.APPLICATION)); + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/StereotypePortInheritanceTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/StereotypePortInheritanceTest.java new file mode 100644 index 000000000..868e548f9 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/StereotypePortInheritanceTest.java @@ -0,0 +1,127 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.PortRegistrationType; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTPort; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.util.UMLUtil; +import org.junit.ClassRule; +import org.junit.Test; + +/** + * Test cases for inheritance of port stereotype features. + */ +@TestModel("inheritance/ports.uml") +public class StereotypePortInheritanceTest { + + @ClassRule + public static final ModelFixture fixture = new ModelFixture(); + + public StereotypePortInheritanceTest() { + super(); + } + + @Test + public void notificationInheritance() { + Class subsub = fixture.getElement("Subsubcapsule"); + Port p1 = subsub.getOwnedPorts().get(0); + RTPort stereo = UMLUtil.getStereotypeApplication(p1, RTPort.class); + + assertThat(stereo.isNotification(), is(false)); + assertThat(stereo.eIsSet(UMLRealTimePackage.Literals.RT_PORT__IS_NOTIFICATION), is(false)); + + Class root = fixture.getElement("RootCapsule"); + Port r1 = root.getOwnedPorts().get(0); + UMLUtil.getStereotypeApplication(r1, RTPort.class).setIsNotification(true); + + assertThat(stereo.isNotification(), is(true)); + assertThat(stereo.eIsSet(UMLRealTimePackage.Literals.RT_PORT__IS_NOTIFICATION), is(false)); + } + + @Test + public void publishInheritance() { + Class subsub = fixture.getElement("Subsubcapsule"); + Port p1 = subsub.getOwnedPorts().get(0); + RTPort stereo = UMLUtil.getStereotypeApplication(p1, RTPort.class); + + assertThat(stereo.isPublish(), is(false)); + assertThat(stereo.eIsSet(UMLRealTimePackage.Literals.RT_PORT__IS_PUBLISH), is(false)); + + Class root = fixture.getElement("RootCapsule"); + Port r1 = root.getOwnedPorts().get(0); + UMLUtil.getStereotypeApplication(r1, RTPort.class).setIsPublish(true); + + assertThat(stereo.isPublish(), is(true)); + assertThat(stereo.eIsSet(UMLRealTimePackage.Literals.RT_PORT__IS_PUBLISH), is(false)); + } + + @Test + public void wiredInheritance() { + Class subsub = fixture.getElement("Subsubcapsule"); + Port p1 = subsub.getOwnedPorts().get(0); + RTPort stereo = UMLUtil.getStereotypeApplication(p1, RTPort.class); + + assertThat(stereo.isWired(), is(true)); + assertThat(stereo.eIsSet(UMLRealTimePackage.Literals.RT_PORT__IS_WIRED), is(false)); + + Class root = fixture.getElement("RootCapsule"); + Port r1 = root.getOwnedPorts().get(0); + UMLUtil.getStereotypeApplication(r1, RTPort.class).setIsWired(false); + + assertThat(stereo.isWired(), is(false)); + assertThat(stereo.eIsSet(UMLRealTimePackage.Literals.RT_PORT__IS_WIRED), is(false)); + } + + @Test + public void registrationInheritance() { + Class subsub = fixture.getElement("Subsubcapsule"); + Port p1 = subsub.getOwnedPorts().get(0); + RTPort stereo = UMLUtil.getStereotypeApplication(p1, RTPort.class); + + assertThat(stereo.getRegistration(), is(PortRegistrationType.AUTOMATIC)); + assertThat(stereo.eIsSet(UMLRealTimePackage.Literals.RT_PORT__REGISTRATION), is(false)); + + Class root = fixture.getElement("RootCapsule"); + Port r1 = root.getOwnedPorts().get(0); + UMLUtil.getStereotypeApplication(r1, RTPort.class).setRegistration(PortRegistrationType.APPLICATION); + + assertThat(stereo.getRegistration(), is(PortRegistrationType.APPLICATION)); + assertThat(stereo.eIsSet(UMLRealTimePackage.Literals.RT_PORT__REGISTRATION), is(false)); + } + + @Test + public void registrationOverrideInheritance() { + Class subsub = fixture.getElement("Subsubcapsule"); + Port p1 = subsub.getOwnedPorts().get(0); + RTPort stereo = UMLUtil.getStereotypeApplication(p1, RTPort.class); + + assertThat(stereo.getRegistrationOverride(), is("")); + assertThat(stereo.eIsSet(UMLRealTimePackage.Literals.RT_PORT__REGISTRATION_OVERRIDE), is(false)); + + Class root = fixture.getElement("RootCapsule"); + Port r1 = root.getOwnedPorts().get(0); + UMLUtil.getStereotypeApplication(r1, RTPort.class).setRegistrationOverride("foo"); + + assertThat(stereo.getRegistrationOverride(), is("foo")); + assertThat(stereo.eIsSet(UMLRealTimePackage.Literals.RT_PORT__REGISTRATION_OVERRIDE), is(false)); + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/ModelFixture.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/ModelFixture.java new file mode 100644 index 000000000..01f1bc40e --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/ModelFixture.java @@ -0,0 +1,446 @@ +/***************************************************************************** + * Copyright (c) 2016, 2017 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests.util; + +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.fail; + +import java.lang.annotation.Annotation; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.provider.EcoreItemProviderAdapterFactory; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.emf.ecore.util.EContentAdapter; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.edit.provider.ComposedAdapterFactory; +import org.eclipse.emf.edit.provider.IDisposable; +import org.eclipse.emf.edit.provider.IItemLabelProvider; +import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage; +import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement; +import org.eclipse.papyrusrt.umlrt.uml.util.UMLRTResourcesUtil; +import org.eclipse.uml2.common.util.UML2Util; +import org.eclipse.uml2.uml.NamedElement; +import org.eclipse.uml2.uml.Namespace; +import org.eclipse.uml2.uml.Package; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.edit.providers.UMLItemProviderAdapterFactory; +import org.hamcrest.Matcher; +import org.hamcrest.StringDescription; +import org.hamcrest.core.IsAnything; +import org.junit.rules.TestWatcher; +import org.junit.runner.Description; + +/** + * A JUnit test fixture that loads a test model from a resource, via annotation + * or specified in the constructor, and provides a variety of utilities for + * manipulation and interrogation of the model and test assertions. + * + * @see TestModel + */ +public class ModelFixture extends TestWatcher { + + private String testModelPath; + private ResourceSet resourceSet; + private Package testModel; + private AdapterFactory adapterFactory; + + /** + * Initializes me. I will get the test model from an annotation. + * + * @see TestModel + */ + public ModelFixture() { + this(null); + } + + /** + * Initializes me with an explicit test model path. + * + * @param the + * test model path. If {@code null}, then I will look for an annotation + */ + public ModelFixture(String testModelPath) { + super(); + + this.testModelPath = testModelPath; + } + + public ResourceSet getResourceSet() { + return resourceSet; + } + + public Resource getResource() { + return testModel.eResource(); + } + + public Package getModel() { + return testModel; + } + + public UMLRTPackage getRoot() { + return UMLRTPackage.getInstance(getModel()); + } + + @SuppressWarnings("unchecked") + public <T> T create(EClass eclass) { + return (T) resourceSet.getPackageRegistry() + .getEFactory(eclass.getEPackage().getNsURI()) + .create(eclass); + } + + public <T extends NamedElement> T create(EClass eclass, String name) { + @SuppressWarnings("unchecked") + T result = (T) resourceSet.getPackageRegistry() + .getEFactory(eclass.getEPackage().getNsURI()) + .create(eclass); + result.setName(name); + return result; + } + + @SuppressWarnings("unchecked") + public <N extends NamedElement> N getElement(String name) { + NamedElement result = find(testModel, Arrays.asList(name.split(NamedElement.SEPARATOR)), null); + + assertThat("Element not found: " + name, result, notNullValue()); + + return (N) result; + } + + public <N extends NamedElement> N getElement(String name, Class<N> metaclass) { + NamedElement result = find(testModel, Arrays.asList(name.split(NamedElement.SEPARATOR)), + metaclass::isInstance); + + assertThat("Element not found: " + name, result, notNullValue()); + + return metaclass.cast(result); + } + + Stream<NamedElement> members(Namespace namespace, String name) { + return namespace.getMembers().stream() + .filter(m -> name.equals(m.getName())); + } + + NamedElement find(NamedElement element, List<String> qualifiedName, Predicate<? super NamedElement> filter) { + NamedElement result; + + if (qualifiedName.isEmpty()) { + result = element; + } else if (element instanceof Namespace) { + Stream<NamedElement> members = members((Namespace) element, qualifiedName.get(0)); + List<String> subQualifiedName = qualifiedName.subList(1, qualifiedName.size()); + result = members.map(m -> find(m, subQualifiedName, filter)) + .filter(Objects::nonNull) + .filter(safeFilter(filter)) + .findFirst() + .orElse(null); + } else { + result = null; + } + + return result; + } + + private static <T> Predicate<T> safeFilter(Predicate<T> filter) { + return (filter == null) ? __ -> true : filter; + } + + @Override + protected void starting(Description description) { + Optional<String> testModelPath = getTestModelPath(description); + testModelPath.ifPresent(path_ -> { + Optional<Class<?>> context = getAnyTest(description).map(Description::getTestClass); + context.ifPresent(testClass -> { + String path = path_; + if (!path.startsWith("resources/")) { + path = "resources/" + path; + } + URI modelURI = URI.createURI(getResource(testClass, path).toExternalForm(), true); + loadTestModel(modelURI); + }); + }); + + ComposedAdapterFactory composed = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE); + composed.addAdapterFactory(new StereotypeApplicationItemProviderAdapterFactory()); + composed.addAdapterFactory(new UMLItemProviderAdapterFactory()); + composed.addAdapterFactory(new EcoreItemProviderAdapterFactory()); + composed.addAdapterFactory(new ReflectiveItemProviderAdapterFactory()); + adapterFactory = composed; + } + + private Optional<String> getTestModelPath(Description description) { + Optional<String> result = Optional.ofNullable(testModelPath); + return result.isPresent() + ? result + : getTestModel(description).map(TestModel::value); + } + + private URL getResource(Class<?> context, String path) { + URL result = context.getClassLoader().getResource(path); + + if (result == null) { + // Maybe we aren't deployed in a JAR but are in the development environment + String base = context.getResource(context.getSimpleName() + ".class").toExternalForm(); + base = base.split("bin/")[0]; + + try { + result = new URL(base + path); + } catch (MalformedURLException e) { + e.printStackTrace(); + fail("Malformed test resource URL: " + e.getMessage()); + } + } + + return result; + } + + private void loadTestModel(URI modelURI) { + resourceSet = new ResourceSetImpl(); + UMLRTResourcesUtil.init(resourceSet); + + testModel = UML2Util.load(resourceSet, modelURI, UMLPackage.Literals.PACKAGE); + } + + @Override + protected void finished(Description description) { + if (resourceSet != null) { + try { + // Check that nothing accidentally created the wrong kind of model element + assertModelImplementationOverrides(); + + // And that no façades were instantiated, if applicable + getAnnotation(description, NoFacade.class) + .map(NoFacade::value) + .filter(Boolean.TRUE::equals) + .ifPresent(__ -> assertNoFacades()); + } finally { + ((IDisposable) adapterFactory).dispose(); + resourceSet.getResources().forEach(Resource::unload); + resourceSet.getResources().clear(); + resourceSet.eAdapters().clear(); + } + } + + testModel = null; + resourceSet = null; + adapterFactory = null; + } + + public String label(EObject object) { + IItemLabelProvider labels = (IItemLabelProvider) adapterFactory.adapt(object, IItemLabelProvider.class); + return (labels != null) ? labels.getText(object) : object.toString(); + } + + List<Resource> modelResources() { + return resourceSet.getResources().stream() + .filter(r -> !"pathmap".equals(r.getURI().scheme())) + .collect(Collectors.toList()); + } + + void assertModelImplementationOverrides() { + Set<EClass> overridden = new HashSet<>(Arrays.asList( + UMLRealTimePackage.Literals.RT_PORT, + UMLPackage.Literals.CLASS, + UMLPackage.Literals.PORT, + UMLPackage.Literals.PROPERTY, + UMLPackage.Literals.COLLABORATION, + UMLPackage.Literals.CONNECTOR, + UMLPackage.Literals.CONNECTOR_END, + UMLPackage.Literals.INTERFACE, + UMLPackage.Literals.LITERAL_INTEGER, + UMLPackage.Literals.LITERAL_UNLIMITED_NATURAL, + UMLPackage.Literals.LITERAL_STRING, + UMLPackage.Literals.OPAQUE_EXPRESSION, + UMLPackage.Literals.OPERATION, + UMLPackage.Literals.PACKAGE, + UMLPackage.Literals.PARAMETER, + UMLPackage.Literals.MODEL)); + + EcoreUtil.getAllContents(modelResources()).forEachRemaining(next -> { + if (next instanceof EObject) { + EObject eObject = (EObject) next; + if (overridden.contains(eObject.eClass()) != (eObject instanceof InternalUMLRTElement)) { + fail("Incorrect impl class override for " + label(eObject)); + } + } + }); + } + + void assertNoFacades() { + try { + Class<? extends Adapter> facadeAdapterType = Class.forName( + "org.eclipse.papyrusrt.umlrt.uml.FacadeObject$BasicFacadeAdapter") //$NON-NLS-1$ + .asSubclass(Adapter.class); + EcoreUtil.getAllContents(modelResources()).forEachRemaining(next -> { + if (next instanceof EObject) { + EObject eObject = (EObject) next; + eObject.eAdapters().stream() + .filter(facadeAdapterType::isInstance) + .map(Adapter.class::cast) + .forEach(adapter -> fail("Found a facade adapter: " + label((EObject) adapter.getTarget()))); + } + }); + } catch (Exception e) { + e.printStackTrace(); + fail("Could not get facade adapter type: " + e.getMessage()); + } + } + + Optional<TestModel> getTestModel(Description description) { + return getAnnotation(description, TestModel.class); + } + + <A extends Annotation> Optional<A> getAnnotation(Description description, Class<A> annotationType) { + A result = description.getAnnotation(annotationType); + + if ((result == null) && (description.getTestClass() != null)) { + result = description.getTestClass().getAnnotation(annotationType); + } + + return Optional.ofNullable(result); + } + + Optional<Description> getAnyTest(Description description) { + Optional<Description> result; + + if (description.getTestClass() != null) { + result = Optional.of(description); + } else { + result = description.getChildren().stream() + .map(this::getAnyTest) + .filter(Optional::isPresent) + .findAny() + .flatMap(Function.identity()); + } + + return result; + } + + public <T> void expectNotification(Notifier notifier, Object feature, int eventType, + Matcher<T> oldValueMatcher, Matcher<T> newValueMatcher, Runnable script) { + + expectNotification(notifier, feature, eventType, oldValueMatcher, newValueMatcher, script, true); + } + + public <T> void expectNoNotification(Notifier notifier, Object feature, int eventType, + Matcher<T> oldValueMatcher, Matcher<T> newValueMatcher, Runnable script) { + + expectNotification(notifier, feature, eventType, oldValueMatcher, newValueMatcher, script, false); + } + + private <T> void expectNotification(Notifier notifier, Object feature, int eventType, + Matcher<T> oldValueMatcher, Matcher<T> newValueMatcher, Runnable script, + boolean expected) { + + AtomicBoolean found = new AtomicBoolean(); + AtomicBoolean everFoundOldValue = new AtomicBoolean(); + AtomicBoolean everFoundNewValue = new AtomicBoolean(); + + Adapter adapter = new EContentAdapter() { + { + // It may be "contained" in an unset feature (e.g., Connector::end) + addAdapter(notifier); + } + + @Override + public void notifyChanged(Notification notification) { + super.notifyChanged(notification); + + if (!notification.isTouch()) { + if ((notification.getNotifier() == notifier) + && (notification.getFeature() == feature) + && (notification.getEventType() == eventType)) { + + boolean oldValueMatches = (oldValueMatcher == null) + || oldValueMatcher.matches(notification.getOldValue()); + boolean newValueMatches = (newValueMatcher == null) + || newValueMatcher.matches(notification.getNewValue()); + + found.compareAndSet(false, oldValueMatches && newValueMatches); + everFoundOldValue.compareAndSet(false, oldValueMatches); + everFoundNewValue.compareAndSet(false, newValueMatches); + } + } + } + }; + + resourceSet.eAdapters().add(adapter); + try { + script.run(); + } finally { + resourceSet.eAdapters().remove(adapter); + } + + if (found.get() != expected) { + org.hamcrest.Description desc = new StringDescription(); + + String notifierType = (notifier instanceof EObject) + ? ((EObject) notifier).eClass().getName() + : String.valueOf(notifier); + String featureName = (feature instanceof EStructuralFeature) + ? ((EStructuralFeature) feature).getName() + : String.valueOf(feature); + + if (expected) { + desc.appendText("no notification on "); + } else { + desc.appendText("notification on "); + } + desc.appendText(notifierType); + desc.appendText("::").appendText(featureName); + + if (!everFoundNewValue.get() && !isTrivial(newValueMatcher)) { + desc.appendText(" where newValue "); + newValueMatcher.describeTo(desc); + } else if (!everFoundOldValue.get() && !isTrivial(oldValueMatcher)) { + desc.appendText(" where oldValue "); + oldValueMatcher.describeTo(desc); + } else if (newValueMatcher != null) { + // At least there's a new-value IsAnything + desc.appendText(" where newValue "); + newValueMatcher.describeTo(desc); + } + + fail(desc.toString()); + } + } + + private static boolean isTrivial(Matcher<?> matcher) { + return (matcher == null) || (matcher instanceof IsAnything<?>); + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/NoFacade.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/NoFacade.java new file mode 100644 index 000000000..bc34dc8df --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/NoFacade.java @@ -0,0 +1,38 @@ +/***************************************************************************** + * Copyright (c) 2016 CEA LIST and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * CEA LIST - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests.util; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Annotates a test method or class that must not cause any objects of the + * façade API to be created. + */ +@Retention(RUNTIME) +@Target({ TYPE, METHOD }) +public @interface NoFacade { + /** + * Whether the test must not trigger the façade API. Annotating with + * a {@code false} value is useful to override the suite-level annotation + * for a specific test. + * + * @return whether the test must not trigger the façade API + */ + boolean value() default true; +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/StereotypeApplicationItemProviderAdapterFactory.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/StereotypeApplicationItemProviderAdapterFactory.java new file mode 100644 index 000000000..48662b58b --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/StereotypeApplicationItemProviderAdapterFactory.java @@ -0,0 +1,171 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests.util; + +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.edit.provider.ChangeNotifier; +import org.eclipse.emf.edit.provider.ComposeableAdapterFactory; +import org.eclipse.emf.edit.provider.ComposedAdapterFactory; +import org.eclipse.emf.edit.provider.IChangeNotifier; +import org.eclipse.emf.edit.provider.IDisposable; +import org.eclipse.emf.edit.provider.IItemLabelProvider; +import org.eclipse.emf.edit.provider.INotifyChangedListener; +import org.eclipse.emf.edit.provider.ItemProviderAdapter; +import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.util.UMLUtil; + +/** + * Adapter factory for nice labelling of stereotype applications as distinct objects. + */ +public class StereotypeApplicationItemProviderAdapterFactory extends AdapterFactoryImpl implements ComposeableAdapterFactory, IChangeNotifier, IDisposable { + + private ComposedAdapterFactory parentAdapterFactory; + + private IChangeNotifier changeNotifier = new ChangeNotifier(); + + private Collection<Object> supportedTypes = new ArrayList<>(); + + private ItemProviderAdapter itemProvider; + + public StereotypeApplicationItemProviderAdapterFactory() { + super(); + + supportedTypes.add(IItemLabelProvider.class); + } + + protected Adapter createAdapter() { + if (itemProvider == null) { + class SAAdapter extends ItemProviderAdapter implements IItemLabelProvider { + SAAdapter(AdapterFactory factory) { + super(factory); + } + + @Override + public String getText(Object object) { + String result; + if (object instanceof EObject) { + Element element = UMLUtil.getBaseElement((EObject) object); + if (element != null) { + EObject appl = (EObject) object; + String baseLabel = ((IItemLabelProvider) getRootAdapterFactory().adapt(element, IItemLabelProvider.class)).getText(element); + if (baseLabel.indexOf(">>") > 0) { + baseLabel = baseLabel.substring(baseLabel.indexOf(">>") + 3, baseLabel.length()); + } + result = String.format("<<%s>> on %s", appl.eClass().getName(), baseLabel); + } else { + result = super.getText(object); + } + } else { + result = super.getText(object); + } + + return result; + } + } + + itemProvider = new SAAdapter(this); + } + return itemProvider; + } + + @Override + public ComposeableAdapterFactory getRootAdapterFactory() { + return (parentAdapterFactory == null) + ? this + : parentAdapterFactory.getRootAdapterFactory(); + } + + @Override + public void setParentAdapterFactory(ComposedAdapterFactory parentAdapterFactory) { + this.parentAdapterFactory = parentAdapterFactory; + } + + @Override + public boolean isFactoryForType(Object type) { + return supportedTypes.contains(type) || isProfilePackage(type); + } + + protected boolean isProfilePackage(Object type) { + return (type == UMLRealTimePackage.eINSTANCE) + || ((type instanceof EPackage) + ? UMLUtil.getProfile((EPackage) type) != null + : (type instanceof EObject) && (UMLUtil.getProfile(((EObject) type).eClass().getEPackage()) != null)); + } + + @Override + protected Adapter createAdapter(Notifier target) { + Adapter result; + + if ((target instanceof EObject) && (UMLUtil.getBaseElement((EObject) target) != null)) { + result = createAdapter(); + } else { + result = super.createAdapter(target); + } + + return result; + } + + @Override + public Adapter adapt(Notifier notifier, Object type) { + return super.adapt(notifier, this); + } + + @Override + public Object adapt(Object object, Object type) { + if (isFactoryForType(type)) { + Object adapter = super.adapt(object, type); + if (!(type instanceof Class<?>) || (((Class<?>) type).isInstance(adapter))) { + return adapter; + } + } + + return null; + } + + @Override + public void addListener(INotifyChangedListener notifyChangedListener) { + changeNotifier.addListener(notifyChangedListener); + } + + @Override + public void removeListener(INotifyChangedListener notifyChangedListener) { + changeNotifier.removeListener(notifyChangedListener); + } + + @Override + public void fireNotifyChanged(Notification notification) { + changeNotifier.fireNotifyChanged(notification); + + if (parentAdapterFactory != null) { + parentAdapterFactory.fireNotifyChanged(notification); + } + } + + @Override + public void dispose() { + if (itemProvider != null) { + itemProvider.dispose(); + } + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/TestModel.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/TestModel.java new file mode 100644 index 000000000..cccdf2b4a --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/TestModel.java @@ -0,0 +1,31 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests.util; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Locates a test model to be loaded by the {@link ModelFixture}. + */ +@Retention(RUNTIME) +@Target({ TYPE, METHOD }) +public @interface TestModel { + /** Path of the test model to load, relative to the test bundle. */ + String value(); +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/UMLMatchers.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/UMLMatchers.java new file mode 100644 index 000000000..09a0c0f3e --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/UMLMatchers.java @@ -0,0 +1,171 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.tests.util; + +import java.util.Objects; + +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.MultiplicityElement; +import org.eclipse.uml2.uml.NamedElement; +import org.eclipse.uml2.uml.RedefinableElement; +import org.eclipse.uml2.uml.Stereotype; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; + +/** + * Hamcrest matchers for assertions on UML model elements. + */ +public class UMLMatchers { + + /** + * Not instantiable by clients. + */ + private UMLMatchers() { + super(); + } + + public static <N extends NamedElement> Matcher<N> named(String name) { + return new BaseMatcher<N>() { + @Override + public void describeTo(Description description) { + description.appendText("element named \"").appendText(name).appendText("\""); + } + + @Override + public boolean matches(Object item) { + return (item instanceof NamedElement) + && Objects.equals(((NamedElement) item).getName(), name); + } + }; + } + + public static <M extends MultiplicityElement> Matcher<M> replicated(int replication) { + return replicated(replication, replication); + } + + public static <M extends MultiplicityElement> Matcher<M> replicated(int lower, int upper) { + return new BaseMatcher<M>() { + @Override + public void describeTo(Description description) { + String desc = toString(lower, upper); + description.appendText(desc); + } + + private String toString(int lower, int upper) { + String result; + + if (upper == lower) { + result = String.format("has [%d] replication", upper); + } else if (upper < 0) { + if (lower <= 0) { + result = String.format("has [*] replication", lower); + } else { + result = String.format("has [%d..*] replication", lower); + } + } else { + result = String.format("has [%d..%d] replication", lower, upper); + } + + return result; + } + + @Override + public void describeMismatch(Object item, Description description) { + if (item instanceof MultiplicityElement) { + MultiplicityElement mult = (MultiplicityElement) item; + String desc = toString(mult.getLower(), mult.getUpper()); + description.appendText("was ").appendText(desc); + } else { + super.describeMismatch(item, description); + } + } + + @Override + public boolean matches(Object item) { + return (item instanceof MultiplicityElement) + && (((MultiplicityElement) item).getLower() == lower) + && (((MultiplicityElement) item).getUpper() == upper); + } + }; + } + + public static Matcher<Element> stereotypedAs(String qualifiedName) { + return new BaseMatcher<Element>() { + @Override + public void describeTo(Description description) { + description.appendText("element stereotyped as ").appendText(qualifiedName); + } + + @Override + public boolean matches(Object item) { + return (item instanceof Element) + && (((Element) item).getAppliedStereotype(qualifiedName) != null); + } + }; + } + + public static Matcher<Element> hasStereotypeValue(String stereotypeQName, String propertyName, Matcher<?> valueMatcher) { + return new BaseMatcher<Element>() { + @Override + public void describeTo(Description description) { + description.appendText("element has <<").appendText(stereotypeQName) + .appendText(">>::").appendText(propertyName).appendText(" "); + description.appendDescriptionOf(valueMatcher); + } + + @Override + public boolean matches(Object item) { + boolean result = false; + + if (item instanceof Element) { + Element element = (Element) item; + Stereotype stereo = element.getAppliedStereotype(stereotypeQName); + if (stereo != null) { + Object value = element.getValue(stereo, propertyName); + result = valueMatcher.matches(value); + } + } + + return result; + } + }; + } + + public static <R extends RedefinableElement> Matcher<R> redefines(R element) { + return new BaseMatcher<R>() { + @Override + public void describeTo(Description description) { + description.appendText("redefines ").appendText(element.getQualifiedName()); + } + + @Override + public boolean matches(Object item) { + return (item instanceof RedefinableElement) + && redefines((RedefinableElement) item, element); + } + + boolean redefines(RedefinableElement element, RedefinableElement redefined) { + boolean result = element == redefined; + + if (!result) { + result = element.getRedefinedElements().stream() + .anyMatch(r -> redefines(r, redefined)); + } + + return result; + } + }; + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/util/tests/InheritanceKindTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/util/tests/InheritanceKindTest.java new file mode 100644 index 000000000..5ea81ce7e --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/util/tests/InheritanceKindTest.java @@ -0,0 +1,127 @@ +/***************************************************************************** + * Copyright (c) 2017 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.util.tests; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTNamedElement; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocol; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.papyrusrt.umlrt.uml.util.InheritanceKind; +import org.eclipse.uml2.uml.NamedElement; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; + +/** + * Test suite for the {@link InheritanceKind} enumeration. + */ +@TestModel("inheritance/connectors.uml") +public class InheritanceKindTest { + + @ClassRule + public static final ModelFixture model = new ModelFixture(); + + public InheritanceKindTest() { + super(); + } + + @Test + public void noneKind() { + assertThat(InheritanceKind.of(local()), is(InheritanceKind.NONE)); + + // Not an inheritable thing + assertThat(InheritanceKind.of(getCapsule()), is(InheritanceKind.NONE)); + + // No element + assertThat(InheritanceKind.of((NamedElement) null), is(InheritanceKind.NONE)); + } + + @Test + public void inheritedKind() { + assertThat(InheritanceKind.of(inherited()), is(InheritanceKind.INHERITED)); + } + + @Test + public void redefinedKind() { + assertThat(InheritanceKind.of(redefined()), is(InheritanceKind.REDEFINED)); + } + + @Test + public void excludedKind() { + assertThat(InheritanceKind.of(excluded()), is(InheritanceKind.EXCLUDED)); + } + + @Test + public void ordering() { + List<UMLRTNamedElement> elements = new ArrayList<>(Arrays.asList( + local(), excluded(), redefined(), inherited())); + + Collections.sort(elements, InheritanceKind.facadeComparator()); + + assertThat(elements, is(Arrays.asList(inherited(), redefined(), excluded(), local()))); + } + + // + // Test framework + // + + /** Get a capsule that inherits and locally defines stuff. */ + static UMLRTCapsule getCapsule() { + return model.getRoot().getCapsule("Subcapsule"); + } + + /** A locally-defined element. */ + static UMLRTNamedElement local() { + return getCapsule().getPort("newProtocol"); + } + + /** An excluded element. */ + static UMLRTNamedElement excluded() { + return getCapsule().getConnector("connector1"); + } + + /** A redefined element. */ + static UMLRTNamedElement redefined() { + return getCapsule().getPort("protocol1"); + } + + /** An inherited element. */ + static UMLRTNamedElement inherited() { + return getCapsule().getCapsulePart("nestedCapsule"); + } + + @BeforeClass + public static void setupRedefinitions() { + UMLRTCapsule subcapsule = getCapsule(); + UMLRTProtocol newProtocol = model.getRoot().createProtocol("NewProtocol"); + + // A locally-defined element + subcapsule.createPort(newProtocol); + + // A redefined element + subcapsule.getPort("protocol1").setReplicationFactor(2); + + // An excluded element + subcapsule.getConnector("connector1").exclude(); + } +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/util/tests/PairTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/util/tests/PairTest.java new file mode 100644 index 000000000..0717f063a --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/util/tests/PairTest.java @@ -0,0 +1,352 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.util.tests; + +import static java.util.Collections.emptySet; +import static java.util.Collections.singleton; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.sameInstance; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.Collections; +import java.util.ConcurrentModificationException; +import java.util.Iterator; +import java.util.ListIterator; +import java.util.NoSuchElementException; + +import org.eclipse.papyrusrt.umlrt.uml.util.Pair; +import org.junit.Test; + +/** + * Test suite for the {@link Pair} API. + */ +public class PairTest { + + @Test(expected = NullPointerException.class) + public void constructor() { + new Pair<>("Hello", null); + } + + @Test(expected = NullPointerException.class) + public void setFirst() { + Pair<String> pair = new Pair<>("Hello", "world"); + + pair.setFirst("Good-bye"); + assertThat(pair, is(Arrays.asList("Good-bye", "world"))); + + pair.setFirst(null); + } + + @Test(expected = NullPointerException.class) + public void setSecond() { + Pair<String> pair = new Pair<>("Hello", "world"); + + pair.setSecond("Earthlings"); + assertThat(pair, is(Arrays.asList("Hello", "Earthlings"))); + + pair.setSecond(null); + } + + @Test + public void size() { + Pair<String> pair = Pair.of("Hello", "world"); + assertThat(pair.size(), is(2)); + } + + @Test + public void isEmpty() { + Pair<String> pair = Pair.of("Hello", "world"); + assertThat(pair.isEmpty(), is(false)); + } + + @Test + public void contains() { + Pair<String> pair = Pair.of("Hello", "world"); + assertThat(pair.contains("Hello"), is(true)); + assertThat(pair.contains("world"), is(true)); + assertThat(pair.contains("Earthlings"), is(false)); + assertThat(pair.contains(null), is(false)); + } + + @Test(expected = ConcurrentModificationException.class) + public void concurrentModification() { + Pair<String> pair = Pair.of("Hello", "world"); + + Iterator<String> iter = pair.iterator(); + iter.next(); + pair.setFirst("Good-bye"); + iter.next(); + } + + @Test(expected = NoSuchElementException.class) + public void iterator() { + Pair<String> pair = Pair.of("Hello", "world"); + + Iterator<String> iter = pair.iterator(); + assertThat(iter.hasNext(), is(true)); + assertThat(iter.next(), is("Hello")); + assertThat(iter.hasNext(), is(true)); + assertThat(iter.next(), is("world")); + assertThat(iter.hasNext(), is(false)); + + iter.next(); + } + + @Test + public void toArray() { + Pair<String> pair = Pair.of("Hello", "world"); + assertThat(pair.toArray(), is(new Object[] { "Hello", "world" })); + } + + @Test + public void toArrayOfT() { + Pair<String> pair = Pair.of("Hello", "world"); + + String[] tooShort = new String[0]; + String[] array = pair.toArray(tooShort); + assertThat(array, not(sameInstance(tooShort))); + assertThat(array.length, is(2)); + assertThat(Arrays.asList(array), is(Arrays.asList("Hello", "world"))); + + String[] moreThanLongEnough = new String[] { "a", "b", "c", "d" }; + array = pair.toArray(moreThanLongEnough); + assertThat(array, sameInstance(moreThanLongEnough)); + assertThat(Arrays.asList(array), is(Arrays.asList("Hello", "world", null, "d"))); + + String[] justLongEnough = new String[] { "a", "b" }; + array = pair.toArray(justLongEnough); + assertThat(array, sameInstance(justLongEnough)); + assertThat(Arrays.asList(array), is(Arrays.asList("Hello", "world"))); + } + + @Test(expected = UnsupportedOperationException.class) + public void add() { + Pair<String> pair = Pair.of("Hello", "world"); + pair.add("!"); + } + + @Test(expected = UnsupportedOperationException.class) + public void remove() { + Pair<String> pair = Pair.of("Hello", "world"); + pair.remove("world"); + } + + @Test + public void containsAll() { + Pair<String> pair = Pair.of("Hello", "world"); + + assertThat(pair.containsAll(singleton("Hello")), is(true)); + assertThat(pair.containsAll(emptySet()), is(true)); + + assertThat(pair.containsAll(Arrays.asList("Hello", "world", "!")), is(false)); + assertThat(pair.containsAll(Arrays.asList("Hello", "world", "Hello")), is(true)); + } + + @Test(expected = UnsupportedOperationException.class) + public void addAll() { + Pair<String> pair = Pair.of("Hello", "world"); + pair.addAll(singleton("!")); + } + + @Test(expected = UnsupportedOperationException.class) + public void addAllAtIndex() { + Pair<String> pair = Pair.of("Hello", "world"); + pair.addAll(1, singleton("there")); + } + + @Test(expected = UnsupportedOperationException.class) + public void removeAll() { + Pair<String> pair = Pair.of("Hello", "world"); + pair.removeAll(Arrays.asList("Hello", "world")); + } + + @Test(expected = UnsupportedOperationException.class) + public void retainAll() { + Pair<String> pair = Pair.of("Hello", "world"); + pair.retainAll(Arrays.asList("Hello", "people")); + } + + @Test(expected = UnsupportedOperationException.class) + public void clear() { + Pair<String> pair = Pair.of("Hello", "world"); + pair.clear(); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void get() { + Pair<String> pair = Pair.of("Hello", "world"); + + assertThat(pair.get(0), is("Hello")); + assertThat(pair.get(1), is("world")); + + pair.get(2); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void set() { + Pair<String> pair = Pair.of("Hello", "world"); + + pair.set(0, "Good-bye"); + pair.set(1, "Earthlings"); + + assertThat(pair, is(Pair.of("Good-bye", "Earthlings"))); + + pair.set(2, "!"); + } + + @Test(expected = UnsupportedOperationException.class) + public void addAtIndex() { + Pair<String> pair = Pair.of("Hello", "world"); + pair.add(0, "Well"); + } + + @Test(expected = UnsupportedOperationException.class) + public void removeAtIndex() { + Pair<String> pair = Pair.of("Hello", "world"); + pair.remove(1); + } + + @Test + public void indexOf() { + Pair<String> pair = Pair.of("Hello", "world"); + assertThat(pair.indexOf("Hello"), is(0)); + assertThat(pair.indexOf("world"), is(1)); + assertThat(pair.indexOf("Earthlings"), is(-1)); + assertThat(pair.indexOf(null), is(-1)); + + pair = Pair.of("hello", "hello"); + assertThat(pair.indexOf("hello"), is(0)); + } + + @Test + public void lastIndexOf() { + Pair<String> pair = Pair.of("Hello", "world"); + assertThat(pair.lastIndexOf("Hello"), is(0)); + assertThat(pair.lastIndexOf("world"), is(1)); + assertThat(pair.lastIndexOf("Earthlings"), is(-1)); + assertThat(pair.lastIndexOf(null), is(-1)); + + pair = Pair.of("hello", "hello"); + assertThat(pair.lastIndexOf("hello"), is(1)); + } + + @Test(expected = NoSuchElementException.class) + public void listIterator() { + Pair<String> pair = Pair.of("Hello", "world"); + ListIterator<String> iter = pair.listIterator(); + + assertThat(iter.hasNext(), is(true)); + assertThat(iter.hasPrevious(), is(false)); + + assertThat(iter.previousIndex(), is(-1)); + assertThat(iter.nextIndex(), is(0)); + assertThat(iter.next(), is("Hello")); + + assertThat(iter.hasNext(), is(true)); + assertThat(iter.hasPrevious(), is(true)); + assertThat(iter.previousIndex(), is(0)); + assertThat(iter.nextIndex(), is(1)); + + assertThat(iter.previous(), is("Hello")); + assertThat(iter.previousIndex(), is(-1)); + assertThat(iter.nextIndex(), is(0)); + assertThat(iter.hasNext(), is(true)); + assertThat(iter.hasPrevious(), is(false)); + + assertThat(iter.next(), is("Hello")); + assertThat(iter.next(), is("world")); + + assertThat(iter.hasNext(), is(false)); + assertThat(iter.hasPrevious(), is(true)); + assertThat(iter.previousIndex(), is(1)); + assertThat(iter.nextIndex(), is(2)); + + assertThat(iter.previous(), is("world")); + + iter.set("Earthlings"); + assertThat(pair, is(Pair.of("Hello", "Earthlings"))); + + assertThat(iter.hasNext(), is(true)); + assertThat(iter.hasPrevious(), is(true)); + assertThat(iter.previousIndex(), is(0)); + assertThat(iter.nextIndex(), is(1)); + assertThat(iter.next(), is("Earthlings")); + + iter.next(); + } + + @Test(expected = NoSuchElementException.class) + public void listIteratorAtIndex() { + Pair<String> pair = Pair.of("Hello", "world"); + ListIterator<String> iter = pair.listIterator(2); + + assertThat(iter.hasPrevious(), is(true)); + assertThat(iter.previousIndex(), is(1)); + assertThat(iter.next(), is(2)); + assertThat(iter.previous(), is("world")); + assertThat(iter.hasPrevious(), is(true)); + assertThat(iter.previousIndex(), is(0)); + assertThat(iter.next(), is(1)); + assertThat(iter.previous(), is("Hello")); + + assertThat(iter.hasPrevious(), is(false)); + assertThat(iter.previousIndex(), is(-1)); + assertThat(iter.next(), is(0)); + iter.previous(); + } + + @Test + public void subList() { + Pair<String> pair = Pair.of("Hello", "world"); + + assertThat(pair.subList(0, 0), is(Collections.emptyList())); + assertThat(pair.subList(1, 1), is(Collections.emptyList())); + assertThat(pair.subList(2, 2), is(Collections.emptyList())); + + assertThat(pair.subList(0, 2), is(pair)); + assertThat(pair.subList(0, 1), is(Collections.singletonList("Hello"))); + assertThat(pair.subList(1, 2), is(Collections.singletonList("world"))); + + assertThat(pair.subList(0, 1).size(), is(1)); + assertThat(pair.subList(0, 1).isEmpty(), is(false)); + + pair.subList(1, 2).set(0, "Earthlings"); + assertThat(pair, is(Pair.of("Hello", "Earthlings"))); + } + + @Test + public void hashCode_() { + Pair<String> pair = Pair.of("Hello", "world"); + Pair<String> pair2 = Pair.of("Greetings", "Earthlings"); + Pair<String> pair3 = Pair.of("Hello", "world"); + + assertThat(pair.hashCode(), is(pair3.hashCode())); + assertThat(pair.hashCode(), not(pair2.hashCode())); + } + + @Test + public void equals_() { + Pair<String> pair = Pair.of("Hello", "world"); + + assertThat(pair.equals(pair), is(true)); + assertThat(pair.equals(Pair.of("Hello", "world")), is(true)); + assertThat(pair.equals(Pair.of("Greetings", "Earthlings")), is(false)); + assertThat(pair.equals(Arrays.asList("Hello", "world")), is(true)); + assertThat(pair.equals("Hello"), is(false)); + assertThat(pair.equals(null), is(false)); + } + +} diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/util/tests/UMLRTSwitchTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/util/tests/UMLRTSwitchTest.java new file mode 100644 index 000000000..4bb970729 --- /dev/null +++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/util/tests/UMLRTSwitchTest.java @@ -0,0 +1,348 @@ +/***************************************************************************** + * Copyright (c) 2017 Christian W. Damus and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.uml.util.tests; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.fail; + +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsulePart; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTClassifier; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTConnector; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTModel; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTNamedElement; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTPort; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocol; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocolMessage; +import org.eclipse.papyrusrt.umlrt.uml.UMLRTReplicatedElement; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture; +import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel; +import org.eclipse.papyrusrt.umlrt.uml.util.UMLRTSwitch; +import org.junit.ClassRule; +import org.junit.Test; + +/** + * Test suite for the {@link UMLRTSwitch} class. + */ +@TestModel("inheritance/connectors.uml") +public class UMLRTSwitchTest { + + @ClassRule + public static final ModelFixture model = new ModelFixture(); + + public UMLRTSwitchTest() { + super(); + } + + @Test + public void caseCapsule() { + UMLRTCapsule capsule = model.getRoot().getCapsule("RootCapsule"); + + UMLRTSwitch<String> fixture = new UMLRTSwitch<String>() { + @Override + public String caseCapsule(UMLRTCapsule object) { + return "ok"; + } + + @Override + public String caseClassifier(UMLRTClassifier object) { + fail("Should not call caseClassifier"); + return super.caseClassifier(object); + } + + @Override + public String defaultCase(Object object) { + fail("Should not call defaultCase"); + return super.defaultCase(object); + } + }; + + assertThat(fixture.doSwitch(capsule), is("ok")); + } + + @Test + public void casePort() { + UMLRTCapsule capsule = model.getRoot().getCapsule("RootCapsule"); + UMLRTPort port = capsule.getPort("protocol1"); + + UMLRTSwitch<String> fixture = new UMLRTSwitch<String>() { + @Override + public String casePort(UMLRTPort object) { + return "ok"; + } + + @Override + public String caseReplicatedElement(UMLRTReplicatedElement object) { + fail("Should not call caseReplicatedElement"); + return super.caseReplicatedElement(object); + } + + @Override + public String defaultCase(Object object) { + fail("Should not call defaultCase"); + return super.defaultCase(object); + } + }; + + assertThat(fixture.doSwitch(port), is("ok")); + } + + @Test + public void caseCapsulePart() { + UMLRTCapsule capsule = model.getRoot().getCapsule("RootCapsule"); + UMLRTCapsulePart part = capsule.getCapsulePart("nestedCapsule"); + + UMLRTSwitch<String> fixture = new UMLRTSwitch<String>() { + @Override + public String caseCapsulePart(UMLRTCapsulePart object) { + return "ok"; + } + + @Override + public String caseReplicatedElement(UMLRTReplicatedElement object) { + fail("Should not call caseReplicatedElement"); + return super.caseReplicatedElement(object); + } + + @Override + public String defaultCase(Object object) { + fail("Should not call defaultCase"); + return super.defaultCase(object); + } + }; + + assertThat(fixture.doSwitch(part), is("ok")); + } + + @Test + public void caseConnector() { + UMLRTCapsule capsule = model.getRoot().getCapsule("RootCapsule"); + UMLRTConnector connector = capsule.getConnector("connector1"); + + UMLRTSwitch<String> fixture = new UMLRTSwitch<String>() { + @Override + public String caseConnector(UMLRTConnector object) { + return "ok"; + } + + @Override + public String caseNamedElement(UMLRTNamedElement object) { + fail("Should not call caseNamedElement"); + return super.caseNamedElement(object); + } + + @Override + public String defaultCase(Object object) { + fail("Should not call defaultCase"); + return super.defaultCase(object); + } + }; + + assertThat(fixture.doSwitch(connector), is("ok")); + } + + @Test + public void caseProtocol() { + UMLRTProtocol protocol = model.getRoot().getProtocol("Protocol1"); + + UMLRTSwitch<String> fixture = new UMLRTSwitch<String>() { + @Override + public String caseProtocol(UMLRTProtocol object) { + return "ok"; + } + + @Override + public String caseClassifier(UMLRTClassifier object) { + fail("Should not call caseClassifier"); + return super.caseClassifier(object); + } + + @Override + public String defaultCase(Object object) { + fail("Should not call defaultCase"); + return super.defaultCase(object); + } + }; + + assertThat(fixture.doSwitch(protocol), is("ok")); + } + + @Test + public void caseProtocolMessage() { + UMLRTProtocol protocol = model.getRoot().getProtocol("Protocol1"); + UMLRTProtocolMessage msg = protocol.getMessage("greet"); + + UMLRTSwitch<String> fixture = new UMLRTSwitch<String>() { + @Override + public String caseProtocolMessage(UMLRTProtocolMessage object) { + return "ok"; + } + + @Override + public String caseNamedElement(UMLRTNamedElement object) { + fail("Should not call caseNamedElement"); + return super.caseNamedElement(object); + } + + @Override + public String defaultCase(Object object) { + fail("Should not call defaultCase"); + return super.defaultCase(object); + } + }; + + assertThat(fixture.doSwitch(msg), is("ok")); + } + + @Test + public void casePackage() { + UMLRTPackage nested = model.getRoot().getNestedPackage("nested"); + + UMLRTSwitch<String> fixture = new UMLRTSwitch<String>() { + @Override + public String casePackage(UMLRTPackage object) { + return "ok"; + } + + @Override + public String caseNamedElement(UMLRTNamedElement object) { + fail("Should not call caseNamedElement"); + return super.caseNamedElement(object); + } + + @Override + public String defaultCase(Object object) { + fail("Should not call defaultCase"); + return super.defaultCase(object); + } + }; + + assertThat(fixture.doSwitch(nested), is("ok")); + } + + @Test + public void caseModel() { + UMLRTModel model = UMLRTSwitchTest.model.getRoot().getModel(); + + UMLRTSwitch<String> fixture = new UMLRTSwitch<String>() { + @Override + public String caseModel(UMLRTModel object) { + return "ok"; + } + + @Override + public String defaultCase(Object object) { + fail("Should not call defaultCase"); + return super.defaultCase(object); + } + }; + + assertThat(fixture.doSwitch(model), is("ok")); + } + + @Test + public void caseClassifier() { + UMLRTCapsule capsule = model.getRoot().getCapsule("RootCapsule"); + UMLRTProtocol protocol = model.getRoot().getProtocol("Protocol1"); + + UMLRTSwitch<String> fixture = new UMLRTSwitch<String>() { + @Override + public String caseClassifier(UMLRTClassifier object) { + return "ok"; + } + + @Override + public String defaultCase(Object object) { + fail("Should not call defaultCase"); + return super.defaultCase(object); + } + }; + + assertThat(fixture.doSwitch(capsule), is("ok")); + assertThat(fixture.doSwitch(protocol), is("ok")); + } + + @Test + public void caseReplicatedElement() { + UMLRTCapsule capsule = model.getRoot().getCapsule("RootCapsule"); + UMLRTPort port = capsule.getPort("protocol1"); + UMLRTCapsulePart part = capsule.getCapsulePart("nestedCapsule"); + + UMLRTSwitch<String> fixture = new UMLRTSwitch<String>() { + @Override + public String caseReplicatedElement(UMLRTReplicatedElement object) { + return "ok"; + } + + @Override + public String defaultCase(Object object) { + fail("Should not call defaultCase"); + return super.defaultCase(object); + } + }; + + assertThat(fixture.doSwitch(port), is("ok")); + assertThat(fixture.doSwitch(part), is("ok")); + } + + @Test + public void caseNamedElement() { + UMLRTCapsule capsule = model.getRoot().getCapsule("RootCapsule"); + UMLRTPort port = capsule.getPort("protocol1"); + + UMLRTSwitch<String> fixture = new UMLRTSwitch<String>() { + @Override + public String caseNamedElement(UMLRTNamedElement object) { + return "ok"; + } + + @Override + public String defaultCase(Object object) { + fail("Should not call defaultCase"); + return super.defaultCase(object); + } + }; + + assertThat(fixture.doSwitch(capsule), is("ok")); + assertThat(fixture.doSwitch(port), is("ok")); + } + + @Test + public void defaultCase() { + Object garbage = new Object(); + + UMLRTSwitch<String> fixture = new UMLRTSwitch<String>() { + @Override + public String defaultCase(Object object) { + return "ok"; + } + }; + + assertThat(fixture.doSwitch(garbage), is("ok")); + + assertThat(fixture.doSwitch(null), is("ok")); // As in EMF + } + + @Test + public void emptySwitch() { + UMLRTCapsule capsule = model.getRoot().getCapsule("RootCapsule"); + + UMLRTSwitch<String> fixture = new UMLRTSwitch<>(); + + assertThat(fixture.doSwitch(capsule), nullValue()); + } +} diff --git a/tests/junit/umlrt/profile/pom.xml b/tests/junit/umlrt/profile/pom.xml index 2cb677767..8c8cd601b 100644 --- a/tests/junit/umlrt/profile/pom.xml +++ b/tests/junit/umlrt/profile/pom.xml @@ -14,5 +14,6 @@ <packaging>pom</packaging> <modules> <module>org.eclipse.papyrusrt.umlrt.profile.tests</module> + <module>org.eclipse.papyrusrt.umlrt.uml.tests</module> </modules> </project> |
