diff --git a/.project b/.project
index fdd0c87..48ebc25 100755
--- a/.project
+++ b/.project
@@ -20,6 +20,11 @@
+
+ org.hibernate.eclipse.console.hibernateBuilder
+
+
+
org.eclipse.m2e.core.maven2Builder
@@ -30,5 +35,6 @@
org.eclipse.jdt.core.javanature
org.eclipse.m2e.core.maven2Nature
org.eclipse.wst.common.project.facet.core.nature
+ org.hibernate.eclipse.console.hibernateNature
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
index 5be8ad6..41ac628 100755
--- a/.settings/org.eclipse.jdt.core.prefs
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -113,3 +113,364 @@ org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=11
+org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=true
+org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=1
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=true
+org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns=true
+org.eclipse.jdt.core.formatter.align_with_spaces=false
+org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=84
+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=80
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=20
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_loops=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain=0
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0
+org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_module_statements=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=84
+org.eclipse.jdt.core.formatter.alignment_for_shift_operator=0
+org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0
+org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=1
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch=0
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped=true
+org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=true
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=true
+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=false
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=false
+org.eclipse.jdt.core.formatter.comment.indent_tag_description=false
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags=do not insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+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=true
+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=true
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=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_space_after_additive_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not 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_switch_case_expressions=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_not_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case=insert
+org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_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_switch_case_expressions=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_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_relational_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=false
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line=one_line_if_single_item
+org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_code_block_on_one_line=one_line_if_empty
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=true
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line=one_line_if_single_item
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line=one_line_always
+org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line=one_line_if_empty
+org.eclipse.jdt.core.formatter.keep_method_body_on_one_line=one_line_if_single_item
+org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line=true
+org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=true
+org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.lineSplit=150
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=separate_lines_if_wrapped
+org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.text_block_indentation=0
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
+org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_before_relational_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_shift_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
+org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs
index a2fdc79..cb37178 100755
--- a/.settings/org.eclipse.jdt.ui.prefs
+++ b/.settings/org.eclipse.jdt.ui.prefs
@@ -1,3 +1,5 @@
eclipse.preferences.version=1
+formatter_profile=_KSKE
+formatter_settings_version=18
org.eclipse.jdt.ui.javadoc=true
org.eclipse.jdt.ui.text.custom_code_templates=/**\n * @return the ${bare_field_name}\n * @since Envoy Server Standalone v0.1-beta\n *//**\n * @param ${param} the ${bare_field_name} to set\n * @since Envoy Server Standalone v0.1-beta\n *//**\n * Creates an instance of @link{${enclosing_type}}.\n *\n * ${tags}\n * @since Envoy Server Standalone v0.1-beta\n *//**\n * Project\: <strong>${project_name}</strong><br>\n * File\: <strong>${file_name}</strong><br>\n * Created\: <strong>${date}</strong><br>\n * \n * @author ${user}\n * @since Envoy Server Standalone v0.1-beta\n *//**\n * ${tags}\n * @since Envoy Server Standalone v0.1-beta\n *//**\n * @author ${user}\n *\n * ${tags}\n * @since Envoy Server Standalone v0.1-beta\n *//**\n * {@inheritDoc}\n *//**\n * ${tags}\n * ${see_to_target}\n * @since Envoy Server Standalone v0.1-beta\n */${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}\n\n\n\n${exception_var}.printStackTrace();${body_statement}\n${body_statement}\nreturn ${field};${field} \= ${param};
diff --git a/.settings/org.eclipse.jpt.core.prefs b/.settings/org.eclipse.jpt.core.prefs
index 8aa2bb2..bc24399 100755
--- a/.settings/org.eclipse.jpt.core.prefs
+++ b/.settings/org.eclipse.jpt.core.prefs
@@ -1,3 +1,3 @@
eclipse.preferences.version=1
-org.eclipse.jpt.core.platform=hibernate2_1
+org.eclipse.jpt.core.platform=eclipselink2_5
org.eclipse.jpt.jpa.core.discoverAnnotatedClasses=true
diff --git a/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml b/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml
old mode 100755
new mode 100644
diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml
index 2fcb919..fe1f404 100755
--- a/.settings/org.eclipse.wst.common.project.facet.core.xml
+++ b/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/drop_all_tables.sql b/drop_all_tables.sql
new file mode 100644
index 0000000..9eb29c1
--- /dev/null
+++ b/drop_all_tables.sql
@@ -0,0 +1,5 @@
+DROP SCHEMA public CASCADE;
+CREATE SCHEMA public;
+GRANT ALL ON SCHEMA public TO postgres;
+GRANT ALL ON SCHEMA public TO envoy;
+GRANT ALL ON SCHEMA public TO public;
diff --git a/src/main/java/envoy/server/Startup.java b/src/main/java/envoy/server/Startup.java
index a4875ba..9ad4bc3 100755
--- a/src/main/java/envoy/server/Startup.java
+++ b/src/main/java/envoy/server/Startup.java
@@ -1,17 +1,21 @@
package envoy.server;
+import java.io.File;
import java.io.IOException;
-import java.util.HashSet;
+import java.util.HashMap;
import java.util.Set;
+import java.util.logging.Level;
import com.jenkov.nioserver.Server;
-import envoy.server.data.ConfigItem;
+import envoy.data.Config;
+import envoy.data.ConfigItem;
import envoy.server.data.PersistenceManager;
import envoy.server.net.ConnectionManager;
import envoy.server.net.ObjectMessageProcessor;
import envoy.server.net.ObjectMessageReader;
import envoy.server.processors.*;
+import envoy.util.EnvoyLog;
/**
* Starts the server.
@@ -25,6 +29,25 @@ import envoy.server.processors.*;
*/
public class Startup {
+ /**
+ * Initializes the logger with a new config instance.
+ *
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ private static void initLogging() {
+ final var items = new HashMap>();
+ items.put("homeDirectory",
+ new ConfigItem<>("homeDirectory", "h", File::new, new File(System.getProperty("user.home"), ".envoy-server"), true));
+ items.put("fileLevelBarrier", new ConfigItem<>("fileLevelBarrier", "fb", Level::parse, Level.WARNING, true));
+ items.put("consoleLevelBarrier", new ConfigItem<>("consoleLevelBarrier", "cb", Level::parse, Level.FINEST, true));
+
+ final var config = new Config();
+ config.load(items);
+
+ EnvoyLog.initialize(config);
+ EnvoyLog.attach("envoy");
+ }
+
/**
* Starts the server.
*
@@ -33,17 +56,22 @@ public class Startup {
* @since Envoy Server Standalone v0.1-alpha
*/
public static void main(String[] args) throws IOException {
- Set> processors = new HashSet<>();
- processors.add(new LoginCredentialProcessor());
- processors.add(new MessageProcessor());
- processors.add(new MessageStatusChangeProcessor());
- processors.add(new UserStatusChangeProcessor());
- processors.add(new IDGeneratorRequestProcessor());
- processors.add(new ContactsRequestEventProcessor());
- processors.add(new ContactOperationProcessor());
- Server server = new Server(8080, () -> new ObjectMessageReader(), new ObjectMessageProcessor(processors));
+ initLogging();
- initializeCurrentMessageId();
+ Server server = new Server(8080, ObjectMessageReader::new,
+ new ObjectMessageProcessor(Set.of(new LoginCredentialProcessor(),
+ new MessageProcessor(),
+ new GroupCreationProcessor(),
+ new MessageStatusChangeProcessor(),
+ new UserStatusChangeProcessor(),
+ new IDGeneratorRequestProcessor(),
+ new ContactSearchProcessor(),
+ new ContactOperationProcessor())));
+
+ // Initialize the current message ID
+ PersistenceManager persistenceManager = PersistenceManager.getInstance();
+ if (persistenceManager.getConfigItemByID("currentMessageId") == null)
+ persistenceManager.addConfigItem(new envoy.server.data.ConfigItem("currentMessageId", "0"));
server.start();
server.getSocketProcessor().registerSocketIdListener(ConnectionManager.getInstance());
@@ -53,9 +81,4 @@ public class Startup {
System.out.println("Stopped");
System.exit(0);
}
-
- private static void initializeCurrentMessageId() {
- PersistenceManager persMan = PersistenceManager.getInstance();
- if (persMan.getConfigItemById("currentMessageId") == null) persMan.addConfigItem(new ConfigItem("currentMessageId", "0"));
- }
}
diff --git a/src/main/java/envoy/server/data/Contact.java b/src/main/java/envoy/server/data/Contact.java
new file mode 100644
index 0000000..475b3ef
--- /dev/null
+++ b/src/main/java/envoy/server/data/Contact.java
@@ -0,0 +1,120 @@
+package envoy.server.data;
+
+import java.util.Date;
+import java.util.Set;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+/**
+ * This class acts as a superclass for all contacts, being {@link User}s and
+ * {@link Group}s.
+ *
+ * Project: envoy-server-standalone
+ * File: Contact.java
+ * Created: 24.03.2020
+ *
+ * @author Maximilian Käfer
+ * @since Envoy Server Standalone v0.1-alpha
+ */
+
+@Entity
+@Table(name = "contacts")
+@Inheritance(strategy = InheritanceType.JOINED)
+public abstract class Contact {
+
+ @Id
+ @GeneratedValue
+ protected long id;
+ protected String name;
+
+ @Temporal(TemporalType.TIMESTAMP)
+ private Date creationDate;
+
+ @ManyToMany(fetch = FetchType.EAGER)
+ protected Set contacts;
+
+ /**
+ * @return a {@link envoy.data.Contact} object of this envoy.server.data.Contact
+ * object.
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public abstract envoy.data.Contact toCommon();
+
+ /**
+ * Transforms this contact into a {@link envoy.data.Contact} where the contacts
+ * set of contacts is empty.
+ *
+ * @return a {@link envoy.data.Contact} object of this contact
+ * object.
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ protected abstract envoy.data.Contact toFlatCommon();
+
+ /**
+ * @return the ID of this contact.
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public long getID() { return id; }
+
+ /**
+ * Sets the ID of this contact.
+ *
+ * @param id to set for this contact
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public void setID(long id) { this.id = id; }
+
+ /**
+ * @return the name of this contact.
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public String getName() { return name; }
+
+ /**
+ * Sets the name of this contact.
+ *
+ * @param name to set for this contact
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public void setName(String name) { this.name = name; }
+
+ /**
+ * @return the contacts
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public Set getContacts() { return contacts; }
+
+ /**
+ * @param contacts the contacts to set
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public void setContacts(Set contacts) { this.contacts = contacts; }
+
+ /**
+ * @return the creationDate
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public Date getCreationDate() { return creationDate; }
+
+ /**
+ * @param creationDate the creationDate to set
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public void setCreationDate(Date creationDate) { this.creationDate = creationDate; }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() { return String.format("%s[id=%d,name=%s, contacts=%s]", getClass().getSimpleName(), id, name, contacts); }
+}
diff --git a/src/main/java/envoy/server/data/Group.java b/src/main/java/envoy/server/data/Group.java
new file mode 100644
index 0000000..5f3be22
--- /dev/null
+++ b/src/main/java/envoy/server/data/Group.java
@@ -0,0 +1,62 @@
+package envoy.server.data;
+
+import java.util.stream.Collectors;
+
+import javax.persistence.Entity;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+
+/**
+ * Represents a group inside the database. Referred to as "server group" as
+ * opposed to "group" from Envoy Common.
+ *
+ * Project: envoy-server-standalone
+ * File: Group.java
+ * Created: 24.03.2020
+ *
+ * @author Maximilian Käfer
+ * @since Envoy Server Standalone v0.1-alpha
+ */
+@Entity
+@Table(name = "groups")
+@NamedQueries({
+ @NamedQuery(
+ name = Group.findByName,
+ query = "SELECT g FROM Group g WHERE g.name = :name"
+ ),
+ @NamedQuery(
+ name = Group.findPendingGroups,
+ query = "SELECT g FROM Group g WHERE g.creationDate > :lastSeen AND :user MEMBER OF g.contacts"
+ )
+})
+public class Group extends Contact {
+
+ /**
+ * Named query retrieving a group by name (parameter {@code :name}).
+ *
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public static final String findByName = "Group.findByName";
+
+ /**
+ * Named query retrieving all pending groups for a specific user (parameter {@code :user}, {@code :lastSeen}).
+ *
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public static final String findPendingGroups = "Group.findPendingGroups";
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public envoy.data.Group toCommon() {
+ return new envoy.data.Group(id, name, contacts.parallelStream().map(User.class::cast).map(User::toFlatCommon).collect(Collectors.toSet()));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected envoy.data.Group toFlatCommon() { return toCommon(); }
+}
diff --git a/src/main/java/envoy/server/data/GroupMessage.java b/src/main/java/envoy/server/data/GroupMessage.java
new file mode 100644
index 0000000..4c64cf7
--- /dev/null
+++ b/src/main/java/envoy/server/data/GroupMessage.java
@@ -0,0 +1,99 @@
+package envoy.server.data;
+
+import java.util.Date;
+import java.util.Map;
+
+import javax.persistence.ElementCollection;
+import javax.persistence.Entity;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import envoy.data.MessageBuilder;
+
+/**
+ * Project: envoy-server-standalone
+ * File: GroupMessage.java
+ * Created: 18.04.2020
+ *
+ * @author Maximilian Käfer
+ * @since Envoy Server Standalone v0.1-beta
+ */
+@Entity
+public class GroupMessage extends Message {
+
+ @ElementCollection
+ private Map memberMessageStatus;
+
+ @Temporal(TemporalType.TIMESTAMP)
+ protected Date lastStatusChangeDate;
+
+ /**
+ * The constructor for a database object.
+ *
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public GroupMessage() {}
+
+ /**
+ * Constructs a database groupMessage from a common groupMessage.
+ *
+ * @param groupMessage the {@link envoy.data.GroupMessage} to convert
+ * into a
+ * database {@link GroupMessage}
+ * @param lastStatusChangeDate the {@link Date} to set
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public GroupMessage(envoy.data.GroupMessage groupMessage, Date lastStatusChangeDate) {
+ super(groupMessage);
+ memberMessageStatus = groupMessage.getMemberStatuses();
+ this.lastStatusChangeDate = lastStatusChangeDate;
+ }
+
+ /**
+ * Converts this groupMessage into an instance of
+ * {@link envoy.data.GroupMessage}.
+ *
+ * @return a {@link envoy.data.GroupMessage} containing the same values as this
+ * groupMessage
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ @Override
+ public envoy.data.GroupMessage toCommon() {
+ // TODO: Attachment
+ envoy.data.GroupMessage groupMessage = new MessageBuilder(sender.getID(), recipient.getID(), id).setDate(creationDate)
+ .setForwarded(forwarded)
+ .setStatus(status)
+ .setText(text)
+ // .setAttachment(attachment) TODO make this work
+ .buildGroupMessage((envoy.data.Group) recipient.toCommon(), memberMessageStatus);
+ groupMessage.setReceivedDate(receivedDate);
+ groupMessage.setReadDate(readDate);
+ return groupMessage;
+ }
+
+ /**
+ * @return the memberMessageStatus
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public Map getMemberMessageStatus() { return memberMessageStatus; }
+
+ /**
+ * @param memberMessageStatus the memberMessageStatus to set
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public void setMemberMessageStatus(Map memberMessageStatus) {
+ this.memberMessageStatus = memberMessageStatus;
+ }
+
+ /**
+ * @return the date at which one of the member statuses changed last
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public Date getLastStatusChangeDate() { return lastStatusChangeDate; }
+
+ /**
+ * @param date the date to set
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public void setLastStatusChangeDate(Date date) { lastStatusChangeDate = date; }
+}
diff --git a/src/main/java/envoy/server/data/Message.java b/src/main/java/envoy/server/data/Message.java
index f2584d3..9203a4f 100755
--- a/src/main/java/envoy/server/data/Message.java
+++ b/src/main/java/envoy/server/data/Message.java
@@ -21,36 +21,47 @@ import envoy.data.MessageBuilder;
*/
@Entity
@Table(name = "messages")
-@NamedQueries(
- { @NamedQuery(
- query = "SELECT m FROM Message m WHERE m.recipient =:recipient AND m.status = envoy.data.Message$MessageStatus.SENT",
- name = "getUnreadMessages"
- ) }
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@NamedQuery(
+ name = Message.getPending,
+ query = "SELECT m FROM Message m WHERE (m.recipient = :user AND m.status = envoy.data.Message$MessageStatus.SENT) "
+ + "OR (m.sender = :user) AND ((m.status = envoy.data.Message$MessageStatus.RECEIVED) AND (m.receivedDate > :lastSeen)"
+ + "OR (m.status = envoy.data.Message$MessageStatus.READ) AND (m.readDate > :lastSeen))"
)
public class Message {
+ /**
+ * Named query retrieving pending messages for a user (parameter {@code :user})
+ * which was last seen after a specific date (parameter {@code :lastSeen}).
+ *
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public static final String getPending = "Message.getPending";
+
@Id
- private long id;
+ protected long id;
- @ManyToOne(cascade = CascadeType.PERSIST)
- private User sender;
+ @ManyToOne
+ @JoinColumn
+ protected User sender;
- @ManyToOne(cascade = CascadeType.PERSIST)
- private User recipient;
+ @ManyToOne
+ @JoinColumn
+ protected Contact recipient;
@Temporal(TemporalType.TIMESTAMP)
- private Date creationDate;
+ protected Date creationDate;
@Temporal(TemporalType.TIMESTAMP)
- private Date receivedDate;
+ protected Date receivedDate;
@Temporal(TemporalType.TIMESTAMP)
- private Date readDate;
+ protected Date readDate;
- private String text;
- private envoy.data.Message.MessageStatus status;
- private byte[] attachment;
- private boolean forwarded;
+ protected String text;
+ protected envoy.data.Message.MessageStatus status;
+ protected byte[] attachment;
+ protected boolean forwarded;
/**
* The constructor for a database object.
@@ -67,15 +78,15 @@ public class Message {
* @since Envoy Server Standalone v0.1-alpha
*/
public Message(envoy.data.Message message) {
- PersistenceManager persMan = PersistenceManager.getInstance();
+ PersistenceManager persistenceManager = PersistenceManager.getInstance();
id = message.getID();
status = message.getStatus();
text = message.getText();
creationDate = message.getCreationDate();
receivedDate = message.getReceivedDate();
readDate = message.getReadDate();
- sender = persMan.getUserById(message.getSenderID());
- recipient = persMan.getUserById(message.getRecipientID());
+ sender = persistenceManager.getUserByID(message.getSenderID());
+ recipient = persistenceManager.getContactByID(message.getRecipientID());
forwarded = message.isForwarded();
// TODO: attachment = message.getAttachment().toByteArray();DOES NOT WORK YET
}
@@ -87,12 +98,13 @@ public class Message {
* message
* @since Envoy Server Standalone v0.1-alpha
*/
- public envoy.data.Message toCommonMessage() {
+ public envoy.data.Message toCommon() {
// TODO: Attachment
- envoy.data.Message message = new MessageBuilder(sender.getId(), recipient.getId(), id).setText(text)
+ envoy.data.Message message = new MessageBuilder(sender.getID(), recipient.getID(), id).setText(text)
.setDate(creationDate)
.setStatus(status)
.setForwarded(forwarded)
+ // .setAttachment(attachment) TODO make this work
.build();
message.setReceivedDate(receivedDate);
message.setReadDate(readDate);
@@ -103,12 +115,12 @@ public class Message {
* @return the id of a {link envoy.data.Message}
* @since Envoy Server Standalone v0.1-alpha
*/
- public long getId() { return id; }
+ public long getID() { return id; }
/**
* @param id the id to set
* @since Envoy Server Standalone v0.1-alpha
- * @see Message#getId()
+ * @see Message#getID()
*/
public void setId(long id) { this.id = id; }
@@ -129,7 +141,7 @@ public class Message {
* @return the recipient of a {link envoy.data.Message}
* @since Envoy Server Standalone v0.1-alpha
*/
- public User getRecipient() { return recipient; }
+ public Contact getRecipient() { return recipient; }
/**
* @param recipient the recipient to set
diff --git a/src/main/java/envoy/server/data/PersistenceManager.java b/src/main/java/envoy/server/data/PersistenceManager.java
index 57fc469..0221fe9 100755
--- a/src/main/java/envoy/server/data/PersistenceManager.java
+++ b/src/main/java/envoy/server/data/PersistenceManager.java
@@ -16,6 +16,7 @@ import envoy.server.net.ConnectionManager;
* Created: 1 Jan 2020
*
* @author Leon Hofmeister
+ * @author Maximilian Käfer
* @since Envoy Server Standalone v0.1-alpha
*/
public class PersistenceManager {
@@ -36,7 +37,7 @@ public class PersistenceManager {
ConnectionManager.getInstance()
.getOnlineUsers()
.stream()
- .map(this::getUserById)
+ .map(this::getUserByID)
.forEach(user -> { user.setStatus(UserStatus.OFFLINE); user.setLastSeen(new Date()); entityManager.merge(user); });
transaction.commit();
}));
@@ -49,12 +50,12 @@ public class PersistenceManager {
public static PersistenceManager getInstance() { return persistenceManager; }
/**
- * Adds a {@link User} to the database.
+ * Adds a {@link Contact} to the database.
*
- * @param user the {@link User} to add to the database
+ * @param contact the {@link Contact} to add to the database
* @since Envoy Server Standalone v0.1-alpha
*/
- public void addUser(User user) { persist(user); }
+ public void addContact(Contact contact) { persist(contact); }
/**
* Adds a {@link Message} to the database.
@@ -73,12 +74,12 @@ public class PersistenceManager {
public void addConfigItem(ConfigItem configItem) { persist(configItem); }
/**
- * Updates a {@link User} in the database
+ * Updates a {@link Contact} in the database
*
- * @param user the {@link User} to add to the database
+ * @param contact the {@link Contact} to add to the database
* @since Envoy Server Standalone v0.1-alpha
*/
- public void updateUser(User user) { merge(user); }
+ public void updateContact(Contact contact) { merge(contact); }
/**
* Updates a {@link Message} in the database.
@@ -97,12 +98,12 @@ public class PersistenceManager {
public void updateConfigItem(ConfigItem configItem) { merge(configItem); }
/**
- * Deletes a {@link User} in the database.
+ * Deletes a {@link Contact} in the database.
*
- * @param user the {@link User} to delete
+ * @param contact the {@link Contact} to delete
* @since Envoy Server Standalone v0.1-alpha
*/
- public void deleteUser(User user) { remove(user); }
+ public void deleteContact(Contact contact) { remove(contact); }
/**
* Deletes a {@link Message} in the database.
@@ -113,13 +114,31 @@ public class PersistenceManager {
public void deleteMessage(Message message) { remove(message); }
/**
- * Searches for a {@link User} with a specific id.
+ * Searches for a {@link User} with a specific ID.
*
* @param id the id to search for
- * @return the user with the specified id
+ * @return the user with the specified ID or {@code null} if none was found
* @since Envoy Server Standalone v0.1-alpha
*/
- public User getUserById(long id) { return entityManager.find(User.class, id); }
+ public User getUserByID(long id) { return entityManager.find(User.class, id); }
+
+ /**
+ * Searches for a {@link Group} with a specific ID.
+ *
+ * @param id the id to search for
+ * @return the group with the specified ID or {@code null} if none was found
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public Group getGroupByID(long id) { return entityManager.find(Group.class, id); }
+
+ /**
+ * Searches for a {@link Contact} with a specific ID.
+ *
+ * @param id the id to search for
+ * @return the contact with the specified ID or {@code null} if none was found
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public Contact getContactByID(long id) { return entityManager.find(Contact.class, id); }
/**
* Searched for a {@link User} with a specific name.
@@ -129,34 +148,50 @@ public class PersistenceManager {
* @since Envoy Server Standalone v0.1-alpha
*/
public User getUserByName(String name) {
- return (User) entityManager.createNamedQuery("getUserByName").setParameter("name", name).getSingleResult();
+ return (User) entityManager.createNamedQuery(User.findByName).setParameter("name", name).getSingleResult();
+ }
+
+ /**
+ * Searched for a {@link Group} with a specific name.
+ *
+ * @param name the name of the group
+ * @return the group with the specified name
+ * @since Envoy Server Standalone v0.1-alpha
+ */
+ public Group getGroupByName(String name) {
+ return (Group) entityManager.createNamedQuery(Group.findByName).setParameter("name", name).getSingleResult();
}
/**
* Searches for a {@link Message} with a specific id.
*
* @param id the id to search for
- * @return the message with the specified id
+ * @return the message with the specified ID or {@code null} if none is found
* @since Envoy Server Standalone v0.1-alpha
*/
- public Message getMessageById(long id) { return entityManager.find(Message.class, id); }
+ public Message getMessageByID(long id) { return entityManager.find(Message.class, id); }
/**
* @param key the name of this {@link ConfigItem}
* @return the {@link ConfigItem} with the given name
* @since Envoy Server Standalone v0.1-alpha
*/
- public ConfigItem getConfigItemById(String key) { return entityManager.find(ConfigItem.class, key); }
+ public ConfigItem getConfigItemByID(String key) { return entityManager.find(ConfigItem.class, key); }
/**
- * Returns all messages received while being offline.
+ * Returns all messages received while being offline or the ones that have
+ * changed.
*
- * @param user - the user who wants to receive his unread messages
+ * @param user the user who wants to receive his unread messages
* @return all messages that the client does not yet have (unread messages)
* @since Envoy Server Standalone v0.1-alpha
*/
- public List getUnreadMessages(User user) {
- return entityManager.createNamedQuery("getUnreadMessages").setParameter("recipient", user).getResultList();
+ public List getPendingMessages(User user) {
+ return entityManager
+ .createNamedQuery(Message.getPending)
+ .setParameter("user", user)
+ .setParameter("lastSeen", user.getLastSeen())
+ .getResultList();
}
/**
@@ -170,33 +205,34 @@ public class PersistenceManager {
* @since Envoy Server Standalone v0.1-alpha
*/
public List searchUsers(String searchPhrase, long userId) {
- return entityManager.createNamedQuery("searchUsers")
+ return entityManager.createNamedQuery(
+ User.searchByName)
.setParameter("searchPhrase", searchPhrase + "%")
- .setParameter("context", getUserById(userId))
+ .setParameter("context", getUserByID(userId))
.getResultList();
}
/**
- * Adds a user to the contact list of another user and vice versa.
+ * Adds a contact to the contact list of another contact and vice versa.
*
- * @param userId1 the ID of the first user
- * @param userId2 the ID of the second user
+ * @param contactID1 the ID of the first contact
+ * @param contactID2 the ID of the second contact
* @since Envoy Server Standalone v0.1-alpha
*/
- public void addContact(long userId1, long userId2) {
+ public void addContactBidirectional(long contactID1, long contactID2) {
// Get users by ID
- User u1 = getUserById(userId1);
- User u2 = getUserById(userId2);
+ Contact c1 = getContactByID(contactID1);
+ Contact c2 = getContactByID(contactID2);
// Add users to each others contact lists
- u1.getContacts().add(u2);
- u2.getContacts().add(u1);
+ c1.getContacts().add(c2);
+ c2.getContacts().add(c1);
// Synchronize changes with the database
transaction.begin();
- entityManager.merge(u1);
- entityManager.merge(u2);
+ entityManager.merge(c1);
+ entityManager.merge(c2);
transaction.commit();
}
@@ -206,7 +242,7 @@ public class PersistenceManager {
* @since Envoy Server Standalone v0.1-alpha
*/
public List getContacts(User user) {
- return entityManager.createNamedQuery("getContactsOfUser").setParameter("user", user).getResultList();
+ return entityManager.createNamedQuery(User.findContacts).setParameter("user", user).getResultList();
}
private void persist(Object obj) {
diff --git a/src/main/java/envoy/server/data/User.java b/src/main/java/envoy/server/data/User.java
index 327a030..f1076c1 100755
--- a/src/main/java/envoy/server/data/User.java
+++ b/src/main/java/envoy/server/data/User.java
@@ -1,15 +1,17 @@
package envoy.server.data;
import java.util.Date;
-import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
import javax.persistence.*;
+import envoy.data.User.UserStatus;
+
/**
- * This class serves as a way to let Hibernate communicate with the server
- * without bringing the dependency of JPA/Hibernate into the client.
- * It will be referenced as "database user" to clarify between the different
- * user objects.
+ * This class enables the storage of user specific data inside a database using
+ * Hibernate. Its objects will be referred to as database users as opposed to
+ * the common user objects present on both the client and the server.
*
* Project: envoy-server-standalone
* File: User.java
@@ -21,83 +23,69 @@ import javax.persistence.*;
*/
@Entity
@Table(name = "users")
-@NamedQueries(
- { @NamedQuery(query = "SELECT u FROM User u WHERE u.name = :name", name = "getUserByName"), @NamedQuery(
- query = "SELECT u.contacts FROM User u WHERE u = :user",
- name = "getContactsOfUser"
- ), @NamedQuery(
- query = "SELECT u FROM User u WHERE (lower(u.name) LIKE lower(:searchPhrase) AND u <> :context AND NOT :context in elements(u.contacts))",
- name = "searchUsers"
- ) }
-)
-public class User {
+@NamedQueries({
+ @NamedQuery(
+ name = User.findByName,
+ query = "SELECT u FROM User u WHERE u.name = :name"
+ ),
+ @NamedQuery(
+ name = User.findContacts,
+ query = "SELECT u.contacts FROM User u WHERE u = :user"
+ ),
+ @NamedQuery(
+ name = User.searchByName,
+ query = "SELECT u FROM User u WHERE (lower(u.name) LIKE lower(:searchPhrase) AND u <> :context AND :context NOT MEMBER OF u.contacts)"
+ )
+})
+public class User extends Contact {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private long id;
- private String name;
- private byte[] passwordHash;
+ /**
+ * Named query retrieving a user by name (parameter {@code :name}).
+ *
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public static final String findByName = "User.findByName";
+
+ /**
+ * Named query retrieving the contacts of a given user (parameter
+ * {@code :user}).
+ *
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public static final String findContacts = "User.findContacts";
+
+ /**
+ * Named query searching for users with a name like a search phrase (parameter
+ * {@code :searchPhrase}) that are not in the contact list of a given user
+ * (parameter {@code :context}).
+ *
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public static final String searchByName = "User.searchByName";
+
+ private byte[] passwordHash;
@Temporal(TemporalType.TIMESTAMP)
- private Date lastSeen;
- private envoy.data.User.UserStatus status;
+ private Date lastSeen;
- @ManyToMany(targetEntity = User.class, cascade = CascadeType.ALL)
- private List contacts;
+ private UserStatus status;
/**
- * Creates an instance of {@link User}.
- *
- * @since Envoy Server Standalone v0.1-alpha
+ * {@inheritDoc}
*/
- public User() {}
-
- /**
- * Creates an instance of {@link User}.
- *
- * @param user the {@link envoy.data.User} to convert
- * @since Envoy Server Standalone v0.1-alpha
- */
- public User(envoy.data.User user) {
- id = user.getID();
- name = user.getName();
- status = user.getStatus();
+ @Override
+ public envoy.data.User toCommon() {
+ return new envoy.data.User(id, name, status, contacts.parallelStream().map(Contact::toFlatCommon).collect(Collectors.toSet()));
}
/**
- * @return a database {@link User} converted into an {@link envoy.data.User}
- * @since Envoy Server Standalone v0.1-alpha
+ * {@inheritDoc}
*/
- public envoy.data.User toCommonUser() { return new envoy.data.User(id, name, status); }
+ @Override
+ protected envoy.data.User toFlatCommon() { return new envoy.data.User(id, name, status, Set.of()); }
/**
- * @return the id of a {link envoy.data.User}
- * @since Envoy Server Standalone v0.1-alpha
- */
- public long getId() { return id; }
-
- /**
- * @param id the id to set
- * @since Envoy Server Standalone v0.1-alpha
- * @see User#getId
- */
- public void setId(long id) { this.id = id; }
-
- /**
- * @return the name of a {link envoy.data.User}
- * @since Envoy Server Standalone v0.1-alpha
- */
- public String getName() { return name; }
-
- /**
- * @param name the username to set
- * @since Envoy Server Standalone v0.1-alpha
- * @see User#getName()
- */
- public void setName(String name) { this.name = name; }
-
- /**
- * @return the passwordHash of a {link envoy.data.User}
+ * @return the password hash
* @since Envoy Server Standalone v0.1-alpha
*/
public byte[] getPasswordHash() { return passwordHash; }
@@ -105,46 +93,30 @@ public class User {
/**
* @param passwordHash the password hash to set
* @since Envoy Server Standalone v0.1-alpha
- * @see User#getPasswordHash()
*/
public void setPasswordHash(byte[] passwordHash) { this.passwordHash = passwordHash; }
/**
- * @return the last date an {link envoy.data.User} has been online
+ * @return the last date the user has been online
* @since Envoy Server Standalone v0.1-alpha
*/
public Date getLastSeen() { return lastSeen; }
/**
- * @param lastSeen the latest date at which has been seen to set
+ * @param lastSeen the latest date at which the user has been online to set
* @since Envoy Server Standalone v0.1-alpha
- * @see User#getLastSeen()
*/
public void setLastSeen(Date lastSeen) { this.lastSeen = lastSeen; }
/**
- * @return the status of a {link envoy.data.User}
+ * @return the status
* @since Envoy Server Standalone v0.1-alpha
*/
- public envoy.data.User.UserStatus getStatus() { return status; }
+ public UserStatus getStatus() { return status; }
/**
* @param status the status to set
* @since Envoy Server Standalone v0.1-alpha
- * @see User#getStatus()
*/
- public void setStatus(envoy.data.User.UserStatus status) { this.status = status; }
-
- /**
- * @return the contacts of a {link envoy.data.User}
- * @since Envoy Server Standalone v0.1-alpha
- */
- public List getContacts() { return contacts; }
-
- /**
- * @param contacts the contacts to set
- * @since Envoy Server Standalone v0.1-alpha
- * @see User#getContacts()
- */
- public void setContacts(List contacts) { this.contacts = contacts; }
+ public void setStatus(UserStatus status) { this.status = status; }
}
diff --git a/src/main/java/envoy/server/net/ConnectionManager.java b/src/main/java/envoy/server/net/ConnectionManager.java
index e8ca932..6d9beea 100755
--- a/src/main/java/envoy/server/net/ConnectionManager.java
+++ b/src/main/java/envoy/server/net/ConnectionManager.java
@@ -1,10 +1,12 @@
package envoy.server.net;
import java.util.*;
+import java.util.stream.Collectors;
import com.jenkov.nioserver.ISocketIdListener;
import envoy.data.User.UserStatus;
+import envoy.server.data.Group;
import envoy.server.data.PersistenceManager;
import envoy.server.processors.UserStatusChangeProcessor;
@@ -44,60 +46,69 @@ public class ConnectionManager implements ISocketIdListener {
public static ConnectionManager getInstance() { return connectionManager; }
@Override
- public void socketCancelled(long socketId) {
- if (!pendingSockets.remove(socketId)) {
+ public void socketCancelled(long socketID) {
+ if (!pendingSockets.remove(socketID)) {
// Notify contacts of this users offline-going
- envoy.server.data.User user = PersistenceManager.getInstance().getUserById(getUserIdBySocketId(socketId));
+ envoy.server.data.User user = PersistenceManager.getInstance().getUserByID(getUserIdBySocketID(socketID));
user.setStatus(UserStatus.OFFLINE);
user.setLastSeen(new Date());
UserStatusChangeProcessor.updateUserStatus(user);
// Remove the socket
- sockets.entrySet().removeIf(e -> e.getValue() == socketId);
+ sockets.entrySet().removeIf(e -> e.getValue() == socketID);
}
}
@Override
- public void socketRegistered(long socketId) { pendingSockets.add(socketId); }
+ public void socketRegistered(long socketID) { pendingSockets.add(socketID); }
/**
* Associates a socket ID with a user ID.
*
- * @param userId the user ID
- * @param socketId the socket ID
+ * @param userID the user ID
+ * @param socketID the socket ID
* @since Envoy Server Standalone v0.1-alpha
*/
- public void registerUser(long userId, long socketId) {
- sockets.put(userId, socketId);
- pendingSockets.remove(socketId);
+ public void registerUser(long userID, long socketID) {
+ sockets.put(userID, socketID);
+ pendingSockets.remove(socketID);
}
/**
- * @param userId the ID of the user registered at a socket
+ * @param userID the ID of the user registered at a socket
* @return the ID of the socket
* @since Envoy Server Standalone v0.1-alpha
*/
- public long getSocketId(long userId) { return sockets.get(userId); }
+ public long getSocketID(long userID) { return sockets.get(userID); }
/**
- * @param socketId the id of the socket whose User is needed
+ * @param socketID the id of the socket whose User is needed
* @return the userId associated with this socketId
* @since Envoy Server Standalone v0.1-alpha
*/
- public long getUserIdBySocketId(long socketId) {
- return sockets.entrySet().stream().filter(entry -> entry.getValue().equals(socketId)).findFirst().get().getKey();
+ public long getUserIdBySocketID(long socketID) {
+ return sockets.entrySet().stream().filter(entry -> entry.getValue().equals(socketID)).findFirst().get().getKey();
}
/**
- * @param userId the ID of the user to check for
+ * @param userID the ID of the user to check for
* @return {@code true} if the user is online
* @since Envoy Server Standalone v0.1-alpha
*/
- public boolean isOnline(long userId) { return sockets.containsKey(userId); }
+ public boolean isOnline(long userID) { return sockets.containsKey(userID); }
/**
- * @return the userId of all users who are currently online
+ * @return the userIDs of all users who are currently online
* @since Envoy Server Standalone v0.1-alpha
*/
public Set getOnlineUsers() { return sockets.keySet(); }
+
+ /**
+ * @param group the group to search for
+ * @return a set of all IDs of currently active members in this group
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public Set getOnlineUsersOfGroup(Group group) {
+ return group.getContacts().stream().map(envoy.server.data.Contact::getID).filter(this::isOnline).collect(Collectors.toSet());
+ }
}
diff --git a/src/main/java/envoy/server/net/ObjectMessageProcessor.java b/src/main/java/envoy/server/net/ObjectMessageProcessor.java
index a35f955..8fb120d 100755
--- a/src/main/java/envoy/server/net/ObjectMessageProcessor.java
+++ b/src/main/java/envoy/server/net/ObjectMessageProcessor.java
@@ -4,12 +4,14 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Set;
+import java.util.logging.Logger;
import com.jenkov.nioserver.IMessageProcessor;
import com.jenkov.nioserver.Message;
import com.jenkov.nioserver.WriteProxy;
import envoy.server.processors.ObjectProcessor;
+import envoy.util.EnvoyLog;
/**
* Handles incoming objects.
@@ -25,6 +27,8 @@ public class ObjectMessageProcessor implements IMessageProcessor {
private final Set> processors;
+ private static final Logger logger = EnvoyLog.getLogger(ObjectMessageProcessor.class);
+
/**
* The constructor to set the {@link ObjectProcessor}s.
*
@@ -39,11 +43,11 @@ public class ObjectMessageProcessor implements IMessageProcessor {
try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(message.sharedArray, message.offset + 4, message.length - 4))) {
Object obj = in.readObject();
if (obj == null) {
- System.out.println("received a null object");
+ logger.warning("Received a null object");
return;
}
- System.out.println("Read object: " + obj);
+ logger.fine("Received " + obj);
// Process object
processors.stream().filter(p -> p.getInputClass().isInstance(obj)).forEach((@SuppressWarnings("rawtypes") ObjectProcessor p) -> {
diff --git a/src/main/java/envoy/server/net/ObjectWriteProxy.java b/src/main/java/envoy/server/net/ObjectWriteProxy.java
index 825daeb..1e1c76b 100755
--- a/src/main/java/envoy/server/net/ObjectWriteProxy.java
+++ b/src/main/java/envoy/server/net/ObjectWriteProxy.java
@@ -1,10 +1,12 @@
package envoy.server.net;
import java.io.IOException;
+import java.util.logging.Logger;
import com.jenkov.nioserver.Message;
import com.jenkov.nioserver.WriteProxy;
+import envoy.util.EnvoyLog;
import envoy.util.SerializationUtils;
/**
@@ -21,6 +23,8 @@ public class ObjectWriteProxy {
private final WriteProxy writeProxy;
+ private static final Logger logger = EnvoyLog.getLogger(ObjectWriteProxy.class);
+
/**
* Creates an instance of {@link ObjectWriteProxy}.
*
@@ -30,21 +34,22 @@ public class ObjectWriteProxy {
public ObjectWriteProxy(WriteProxy writeProxy) { this.writeProxy = writeProxy; }
/**
- * @param recipientSocketId the socket id of the recipient
+ * @param recipientSocketID the socket id of the recipient
* @param obj the object to return to the client
* @throws IOException if the serialization of the object failed
* @since Envoy Server Standalone v0.1-alpha
*/
- public void write(long recipientSocketId, Object obj) throws IOException {
+ public void write(long recipientSocketID, Object obj) throws IOException {
// Create message targeted at the client
- Message response = writeProxy.getMessage();
- response.socketId = recipientSocketId;
+ final Message response = writeProxy.getMessage();
+ response.socketId = recipientSocketID;
+ logger.fine("Sending " + obj);
// Serialize object to byte array
- byte[] objBytes = SerializationUtils.writeToByteArray(obj);
+ final byte[] objBytes = SerializationUtils.writeToByteArray(obj);
// Acquire object length in bytes
- byte[] objLen = SerializationUtils.intToBytes(objBytes.length);
+ final byte[] objLen = SerializationUtils.intToBytes(objBytes.length);
response.writeToMessage(objLen);
response.writeToMessage(objBytes);
diff --git a/src/main/java/envoy/server/processors/ContactOperationProcessor.java b/src/main/java/envoy/server/processors/ContactOperationProcessor.java
index e0f0645..9e181ae 100755
--- a/src/main/java/envoy/server/processors/ContactOperationProcessor.java
+++ b/src/main/java/envoy/server/processors/ContactOperationProcessor.java
@@ -1,13 +1,14 @@
package envoy.server.processors;
import java.io.IOException;
-import java.util.Arrays;
+import java.util.logging.Logger;
-import envoy.data.Contacts;
-import envoy.event.ContactOperationEvent;
+import envoy.event.ElementOperation;
+import envoy.event.contact.ContactOperationEvent;
import envoy.server.data.PersistenceManager;
import envoy.server.net.ConnectionManager;
import envoy.server.net.ObjectWriteProxy;
+import envoy.util.EnvoyLog;
/**
* Project: envoy-server-standalone
@@ -20,23 +21,25 @@ import envoy.server.net.ObjectWriteProxy;
public class ContactOperationProcessor implements ObjectProcessor {
private static final ConnectionManager connectionManager = ConnectionManager.getInstance();
+ private static final Logger logger = EnvoyLog.getLogger(ContactOperationProcessor.class);
@Override
public void process(ContactOperationEvent evt, long socketId, ObjectWriteProxy writeProxy) throws IOException {
switch (evt.getOperationType()) {
case ADD:
- final long userId = ConnectionManager.getInstance().getUserIdBySocketId(socketId);
+ final long userID = ConnectionManager.getInstance().getUserIdBySocketID(socketId);
final long contactId = evt.get().getID();
- System.out.printf("Adding user %s to the contact list of user %d.%n", evt.get(), userId);
- PersistenceManager.getInstance().addContact(userId, contactId);
+ logger.fine(String.format("Adding user %s to the contact list of user %d.%n", evt.get(), userID));
+ PersistenceManager.getInstance().addContactBidirectional(userID, contactId);
// Notify the contact if online
- if (ConnectionManager.getInstance().isOnline(contactId)) writeProxy.write(connectionManager.getSocketId(contactId),
- new Contacts(Arrays.asList(PersistenceManager.getInstance().getUserById(userId).toCommonUser())));
+ if (ConnectionManager.getInstance().isOnline(contactId))
+ writeProxy.write(connectionManager.getSocketID(contactId),
+ new ContactOperationEvent(PersistenceManager.getInstance().getUserByID(userID).toCommon(), ElementOperation.ADD));
break;
default:
- System.err.printf("Received %s with an unsupported operation.%n", evt);
+ logger.warning(String.format("Received %s with an unsupported operation.%n", evt));
}
}
diff --git a/src/main/java/envoy/server/processors/ContactsRequestEventProcessor.java b/src/main/java/envoy/server/processors/ContactSearchProcessor.java
similarity index 66%
rename from src/main/java/envoy/server/processors/ContactsRequestEventProcessor.java
rename to src/main/java/envoy/server/processors/ContactSearchProcessor.java
index 6ed4746..3f7b7bc 100755
--- a/src/main/java/envoy/server/processors/ContactsRequestEventProcessor.java
+++ b/src/main/java/envoy/server/processors/ContactSearchProcessor.java
@@ -3,9 +3,9 @@ package envoy.server.processors;
import java.io.IOException;
import java.util.stream.Collectors;
-import envoy.data.Contacts;
-import envoy.event.ContactSearchRequest;
-import envoy.event.ContactSearchResult;
+import envoy.data.Contact;
+import envoy.event.contact.ContactSearchRequest;
+import envoy.event.contact.ContactSearchResult;
import envoy.server.data.PersistenceManager;
import envoy.server.data.User;
import envoy.server.net.ConnectionManager;
@@ -13,29 +13,29 @@ import envoy.server.net.ObjectWriteProxy;
/**
* Project: envoy-server-standalone
- * File: ContactsRequestEventProcessor.java
+ * File: ContactSearchProcessor.java
* Created: 08.02.2020
*
* @author Kai S. K. Engelbart
* @author Maximilian Käfer
* @since Envoy Server Standalone v0.1-alpha
*/
-public class ContactsRequestEventProcessor implements ObjectProcessor {
+public class ContactSearchProcessor implements ObjectProcessor {
/**
- * Writes a {@link Contacts} list to the client containing all {@link User}s
+ * Writes a list of contacts to the client containing all {@link Contact}s
* matching the search phrase contained inside the request. The client and their
* contacts are excluded from the result.
*
* @since Envoy Server Standalone v0.1-alpha
*/
@Override
- public void process(ContactSearchRequest request, long socketId, ObjectWriteProxy writeProxy) throws IOException {
- writeProxy.write(socketId,
+ public void process(ContactSearchRequest request, long socketID, ObjectWriteProxy writeProxy) throws IOException {
+ writeProxy.write(socketID,
new ContactSearchResult(PersistenceManager.getInstance()
- .searchUsers(request.get(), ConnectionManager.getInstance().getUserIdBySocketId(socketId))
+ .searchUsers(request.get(), ConnectionManager.getInstance().getUserIdBySocketID(socketID))
.stream()
- .map(User::toCommonUser)
+ .map(User::toCommon)
.collect(Collectors.toList())));
}
diff --git a/src/main/java/envoy/server/processors/GroupCreationProcessor.java b/src/main/java/envoy/server/processors/GroupCreationProcessor.java
new file mode 100644
index 0000000..9ea11fe
--- /dev/null
+++ b/src/main/java/envoy/server/processors/GroupCreationProcessor.java
@@ -0,0 +1,53 @@
+package envoy.server.processors;
+
+import java.io.IOException;
+import java.util.HashSet;
+
+import envoy.event.ElementOperation;
+import envoy.event.GroupCreationEvent;
+import envoy.event.contact.ContactOperationEvent;
+import envoy.server.data.Contact;
+import envoy.server.data.PersistenceManager;
+import envoy.server.net.ConnectionManager;
+import envoy.server.net.ObjectWriteProxy;
+
+/**
+ * Project: envoy-server-standalone
+ * File: GroupCreationProcessor.java
+ * Created: 26.03.2020
+ *
+ * @author Maximilian Käfer
+ * @since Envoy Server Standalone v0.1-beta
+ */
+public class GroupCreationProcessor implements ObjectProcessor {
+
+ private final PersistenceManager persistenceManager = PersistenceManager.getInstance();
+ private final ConnectionManager connectionManager = ConnectionManager.getInstance();
+
+ @Override
+ public void process(GroupCreationEvent input, long socketID, ObjectWriteProxy writeProxy) throws IOException {
+ envoy.server.data.Group group = new envoy.server.data.Group();
+ group.setName(input.get());
+ group.setContacts(new HashSet<>());
+ input.getInitialMemberIDs().stream().map(persistenceManager::getUserByID).forEach(group.getContacts()::add);
+ group.getContacts().add(persistenceManager.getContactByID(connectionManager.getUserIdBySocketID(socketID)));
+ group.getContacts().forEach(c -> c.getContacts().add(group));
+ group.getContacts().add(persistenceManager.getUserByID(connectionManager.getUserIdBySocketID(socketID)));
+ persistenceManager.addContact(group);
+ group.getContacts()
+ .stream()
+ .map(Contact::getID)
+ .filter(connectionManager::isOnline)
+ .map(connectionManager::getSocketID)
+ .forEach(memberSocketID -> {
+ try {
+ writeProxy.write(memberSocketID, new ContactOperationEvent(group.toCommon(), ElementOperation.ADD));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ });
+ }
+
+ @Override
+ public Class getInputClass() { return GroupCreationEvent.class; }
+}
diff --git a/src/main/java/envoy/server/processors/GroupMessageProcessor.java b/src/main/java/envoy/server/processors/GroupMessageProcessor.java
new file mode 100644
index 0000000..809df61
--- /dev/null
+++ b/src/main/java/envoy/server/processors/GroupMessageProcessor.java
@@ -0,0 +1,67 @@
+package envoy.server.processors;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.logging.Logger;
+
+import javax.persistence.EntityExistsException;
+
+import envoy.data.GroupMessage;
+import envoy.data.Message.MessageStatus;
+import envoy.server.data.PersistenceManager;
+import envoy.server.net.ConnectionManager;
+import envoy.server.net.ObjectWriteProxy;
+import envoy.util.EnvoyLog;
+
+/**
+ * Project: envoy-server-standalone
+ * File: GroupMessageProcessor.java
+ * Created: 18.04.2020
+ *
+ * @author Maximilian Käfer
+ * @since Envoy Server Standalone v0.1-beta
+ */
+public class GroupMessageProcessor implements ObjectProcessor {
+
+ private static final Logger logger = EnvoyLog.getLogger(GroupCreationProcessor.class);
+
+ @Override
+ public void process(GroupMessage groupMessage, long socketID, ObjectWriteProxy writeProxy) {
+ groupMessage.nextStatus();
+ ConnectionManager connectionManager = ConnectionManager.getInstance();
+
+ final var members = PersistenceManager.getInstance().getGroupByID(groupMessage.getRecipientID()).getContacts();
+ groupMessage.getMemberStatuses().replaceAll((id, oldStatus) -> MessageStatus.SENT);
+ members.forEach(user -> setMemberStatus(connectionManager, groupMessage, user.getID()));
+
+ // Checks if all memberMessageStatuses are RECEIVED and if so sets the
+ // groupMessage Status to RECEIVED.
+
+ members.forEach(user -> { sendToMember(connectionManager, groupMessage, user.getID(), writeProxy); });
+
+ try {
+ PersistenceManager.getInstance().addMessage(new envoy.server.data.GroupMessage(groupMessage, new Date()));
+ } catch (EntityExistsException e) {
+ logger.warning("Received a groupMessage with an ID that already exists");
+ }
+ }
+
+ private void sendToMember(ConnectionManager connectionManager, GroupMessage groupMessage, long memberID, ObjectWriteProxy writeProxy) {
+ if (connectionManager.isOnline(memberID)) try {
+ // If recipient is online, send the groupMessage directly
+ writeProxy.write(connectionManager.getSocketID(memberID), groupMessage);
+ } catch (IOException e) {
+ logger.warning("Recipient online. Failed to send message" + groupMessage.getID());
+ e.printStackTrace();
+ }
+ }
+
+ private void setMemberStatus(ConnectionManager connectionManager, GroupMessage groupMessage, long memberID) {
+ if (connectionManager.isOnline(memberID))
+ // Update the message status of the member to RECEIVED
+ groupMessage.getMemberStatuses().replace(memberID, MessageStatus.RECEIVED);
+ }
+
+ @Override
+ public Class getInputClass() { return GroupMessage.class; }
+}
diff --git a/src/main/java/envoy/server/processors/GroupResizeProcessor.java b/src/main/java/envoy/server/processors/GroupResizeProcessor.java
new file mode 100644
index 0000000..79c2be6
--- /dev/null
+++ b/src/main/java/envoy/server/processors/GroupResizeProcessor.java
@@ -0,0 +1,61 @@
+package envoy.server.processors;
+
+import java.io.IOException;
+
+import envoy.event.GroupResizeEvent;
+import envoy.server.data.Contact;
+import envoy.server.data.PersistenceManager;
+import envoy.server.net.ConnectionManager;
+import envoy.server.net.ObjectWriteProxy;
+
+/**
+ * Project: envoy-server-standalone
+ * File: GroupResizeProcessor.java
+ * Created: 03.04.2020
+ *
+ * @author Maximilian Käfer
+ * @since Envoy Server Standalone v0.1-beta
+ */
+public class GroupResizeProcessor implements ObjectProcessor {
+
+ private static final PersistenceManager persistenceManager = PersistenceManager.getInstance();
+ private static final ConnectionManager connectionManager = ConnectionManager.getInstance();
+
+ @Override
+ public void process(GroupResizeEvent input, long socketID, ObjectWriteProxy writeProxy) throws IOException {
+
+ // Acquire the group to resize from the database
+ var group = persistenceManager.getGroupByID(input.getGroupID());
+
+ // Perform the desired operation
+ switch (input.getOperation()) {
+ case ADD:
+ group.getContacts().add(persistenceManager.getUserByID(input.get().getID()));
+ break;
+ case REMOVE:
+ group.getContacts().remove(persistenceManager.getUserByID(input.get().getID()));
+ break;
+ }
+
+ // Update the group in the database
+ persistenceManager.updateContact(group);
+
+ // Send the updated group to all of its members
+ var commonGroup = group.toCommon();
+ group.getContacts()
+ .stream()
+ .map(Contact::getID)
+ .filter(connectionManager::isOnline)
+ .map(connectionManager::getSocketID)
+ .forEach(memberSocketID -> {
+ try {
+ writeProxy.write(memberSocketID, commonGroup);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ });
+ }
+
+ @Override
+ public Class getInputClass() { return GroupResizeEvent.class; }
+}
diff --git a/src/main/java/envoy/server/processors/IDGeneratorRequestProcessor.java b/src/main/java/envoy/server/processors/IDGeneratorRequestProcessor.java
index 7800c9c..e30f18d 100755
--- a/src/main/java/envoy/server/processors/IDGeneratorRequestProcessor.java
+++ b/src/main/java/envoy/server/processors/IDGeneratorRequestProcessor.java
@@ -1,12 +1,14 @@
package envoy.server.processors;
import java.io.IOException;
+import java.util.logging.Logger;
import envoy.data.IDGenerator;
import envoy.event.IDGeneratorRequest;
import envoy.server.data.ConfigItem;
import envoy.server.data.PersistenceManager;
import envoy.server.net.ObjectWriteProxy;
+import envoy.util.EnvoyLog;
/**
* Project: envoy-server-standalone
@@ -14,25 +16,41 @@ import envoy.server.net.ObjectWriteProxy;
* Created: 28 Jan 2020
*
* @author Kai S. K. Engelbart
+ * @author Maximilian Käfer
* @since Envoy Server Standalone v0.1-alpha
*/
public class IDGeneratorRequestProcessor implements ObjectProcessor {
private static final long ID_RANGE = 200;
+ private static final Logger logger = EnvoyLog.getLogger(IDGeneratorRequestProcessor.class);
@Override
public Class getInputClass() { return IDGeneratorRequest.class; }
@Override
- public void process(IDGeneratorRequest input, long socketId, ObjectWriteProxy writeProxy) throws IOException {
- System.out.println("Received id generation request.");
+ public void process(IDGeneratorRequest input, long socketID, ObjectWriteProxy writeProxy) throws IOException {
+ logger.fine("Received id generation request.");
+ var generator = createIDGenerator();
+ logger.info("Sending new id generator " + generator);
+ writeProxy.write(socketID, generator);
+ }
- ConfigItem currentId = PersistenceManager.getInstance().getConfigItemById("currentMessageId");
- IDGenerator generator = new IDGenerator(Integer.parseInt(currentId.getValue()), ID_RANGE);
- currentId.setValue(String.valueOf(Integer.parseInt(currentId.getValue()) + ID_RANGE));
- PersistenceManager.getInstance().updateConfigItem(currentId);
+ /**
+ * @return a new IDGenerator
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public static IDGenerator createIDGenerator() { return createIDGenerator(ID_RANGE); }
- System.out.println("Sending new id generator " + generator);
- writeProxy.write(socketId, generator);
+ /**
+ * @param range of IDs used by the new IDGenerator
+ * @return a new IDGenerator with a specific range of IDs
+ * @since Envoy Server Standalone v0.1-beta
+ */
+ public static IDGenerator createIDGenerator(long range) {
+ ConfigItem currentID = PersistenceManager.getInstance().getConfigItemByID("currentMessageId");
+ IDGenerator generator = new IDGenerator(Integer.parseInt(currentID.getValue()), range);
+ currentID.setValue(String.valueOf(Integer.parseInt(currentID.getValue()) + range));
+ PersistenceManager.getInstance().updateConfigItem(currentID);
+ return generator;
}
}
diff --git a/src/main/java/envoy/server/processors/LoginCredentialProcessor.java b/src/main/java/envoy/server/processors/LoginCredentialProcessor.java
index 1bc736f..7e33f2b 100755
--- a/src/main/java/envoy/server/processors/LoginCredentialProcessor.java
+++ b/src/main/java/envoy/server/processors/LoginCredentialProcessor.java
@@ -2,20 +2,21 @@ package envoy.server.processors;
import java.io.IOException;
import java.util.*;
-import java.util.stream.Collectors;
+import java.util.logging.Logger;
import javax.persistence.NoResultException;
-import envoy.data.Contacts;
import envoy.data.LoginCredentials;
import envoy.data.Message.MessageStatus;
import envoy.data.User;
import envoy.data.User.UserStatus;
import envoy.event.HandshakeRejectionEvent;
+import envoy.event.MessageStatusChangeEvent;
import envoy.server.data.Message;
import envoy.server.data.PersistenceManager;
import envoy.server.net.ConnectionManager;
import envoy.server.net.ObjectWriteProxy;
+import envoy.util.EnvoyLog;
/**
* This {@link ObjectProcessor} handles {@link LoginCredentials}.
@@ -33,55 +34,61 @@ public class LoginCredentialProcessor implements ObjectProcessor pendingMessages = PersistenceManager.getInstance().getUnreadMessages(user);
- for (Message msg : pendingMessages) {
- System.out.println("Sending message " + msg.toCommonMessage());
- writeProxy.write(socketId, msg.toCommonMessage());
- msg.setReceivedDate(new Date());
- msg.setStatus(MessageStatus.RECEIVED);
- PersistenceManager.getInstance().updateMessage(msg);
- }
+ logger.fine("Sending user...");
+ writeProxy.write(socketID, user.toCommon());
+ logger.fine("Acquiring pending messages for the client...");
+ List pendingMessages = PersistenceManager.getInstance().getPendingMessages(user);
+ for (Message msg : pendingMessages)
+ if (msg.getStatus() == MessageStatus.SENT) {
+ logger.info("Sending message " + msg.toCommon());
+ writeProxy.write(socketID, msg.toCommon());
+ msg.setReceivedDate(new Date());
+ msg.setStatus(MessageStatus.RECEIVED);
+ if (connectionManager.isOnline(msg.getSender().getID())) {
+ var evt = new MessageStatusChangeEvent(msg.toCommon());
+ logger.info("Sending messageStatusChangeEvent to sender " + evt);
+ writeProxy.write(connectionManager.getSocketID(msg.getSender().getID()), evt);
+ }
+ PersistenceManager.getInstance().updateMessage(msg);
+ } else {
+ var evt = new MessageStatusChangeEvent(msg.toCommon());
+ logger.info("Sending messageStatusChangeEvent " + evt);
+ writeProxy.write(socketID, evt);
+ }
}
@Override
public Class getInputClass() { return LoginCredentials.class; }
- private envoy.server.data.User getUser(LoginCredentials credentials, long socketId, ObjectWriteProxy writeProxy) throws IOException {
- return credentials.isRegistration() ? newUser(credentials, socketId, writeProxy) : checkForExistingUser(credentials, socketId, writeProxy);
+ private envoy.server.data.User getUser(LoginCredentials credentials, long socketID, ObjectWriteProxy writeProxy) throws IOException {
+ return credentials.isRegistration() ? newUser(credentials, socketID, writeProxy) : checkForExistingUser(credentials, socketID, writeProxy);
}
/**
* @param credentials the input to evaluate
- * @param socketId the socket ID at which the client performing the handshake
+ * @param socketID the socket ID at which the client performing the handshake
* is connected
* @param writeProxy the {@link ObjectWriteProxy} to use if login was not
* successful
@@ -89,34 +96,34 @@ public class LoginCredentialProcessor implements ObjectProcessor());
- persistenceManager.addUser(user);
+ user.setContacts(new HashSet<>());
+ persistenceManager.addContact(user);
return user;
}
}
diff --git a/src/main/java/envoy/server/processors/MessageProcessor.java b/src/main/java/envoy/server/processors/MessageProcessor.java
index 13dc49a..42c111a 100755
--- a/src/main/java/envoy/server/processors/MessageProcessor.java
+++ b/src/main/java/envoy/server/processors/MessageProcessor.java
@@ -2,12 +2,16 @@ package envoy.server.processors;
import java.io.IOException;
import java.util.Date;
+import java.util.logging.Logger;
+
+import javax.persistence.EntityExistsException;
import envoy.data.Message;
-import envoy.event.MessageStatusChangeEvent;
+import envoy.data.Message.MessageStatus;
import envoy.server.data.PersistenceManager;
import envoy.server.net.ConnectionManager;
import envoy.server.net.ObjectWriteProxy;
+import envoy.util.EnvoyLog;
/**
* This {@link ObjectProcessor} handles incoming {@link Message}s.
@@ -17,28 +21,41 @@ import envoy.server.net.ObjectWriteProxy;
* Created: 30.12.2019
*
* @author Kai S. K. Engelbart
+ * @author Maximilian Käfer
* @since Envoy Server Standalone v0.1-alpha
*/
public class MessageProcessor implements ObjectProcessor {
- @Override
- public void process(Message message, long socketId, ObjectWriteProxy writeProxy) {
+ private static final Logger logger = EnvoyLog.getLogger(MessageProcessor.class);
- ConnectionManager connectionManager = ConnectionManager.getInstance();
+ @Override
+ public void process(Message message, long socketID, ObjectWriteProxy writeProxy) {
+ if (message.getStatus() != MessageStatus.WAITING) {
+ logger.warning("Received message with invalid status: " + message);
+ return;
+ }
message.nextStatus();
+ ConnectionManager connectionManager = ConnectionManager.getInstance();
+
+ sendToUser(connectionManager, message, writeProxy);
+ try {
+ PersistenceManager.getInstance().addMessage(new envoy.server.data.Message(message));
+ } catch (EntityExistsException e) {
+ logger.warning("Received a message with an id that already exists");
+ }
+ }
+
+ private void sendToUser(ConnectionManager connectionManager, Message message, ObjectWriteProxy writeProxy) {
if (connectionManager.isOnline(message.getRecipientID())) try {
// If recipient is online, send the message directly
- writeProxy.write(connectionManager.getSocketId(message.getRecipientID()), message);
-
+ writeProxy.write(connectionManager.getSocketID(message.getRecipientID()), message);
// Update the message status to RECEIVED
message.setReceivedDate(new Date());
message.nextStatus();
- writeProxy.write(socketId, new MessageStatusChangeEvent(message));
} catch (IOException e) {
- System.err.println("Recipient online. Failed to send message" + message.getID());
+ logger.warning("Recipient online. Failed to send message" + message.getID());
e.printStackTrace();
}
- PersistenceManager.getInstance().addMessage(new envoy.server.data.Message(message));
}
@Override
diff --git a/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java b/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java
index 80c9ceb..2ca7c46 100755
--- a/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java
+++ b/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java
@@ -23,18 +23,18 @@ public class MessageStatusChangeProcessor implements ObjectProcessorenvoy-server-standalone
+ * File: NameChangeProcessor.java
+ * Created: 26 Mar 2020
+ *
+ * @author Leon Hofmeister
+ * @since Envoy Server Standalone v0.1-beta
+ */
+public class NameChangeProcessor implements ObjectProcessor {
+
+ @Override
+ public void process(NameChangeEvent input, long socketID, ObjectWriteProxy writeProxy) throws IOException {
+ PersistenceManager persistenceManager = PersistenceManager.getInstance();
+ ConnectionManager connectionManager = ConnectionManager.getInstance();
+ Contact toUpdate = persistenceManager.getContactByID(input.getID());
+ toUpdate.setName(input.get());
+ persistenceManager.updateContact(toUpdate);
+
+ // notifying online contacts of this client of his name change
+ toUpdate.getContacts().stream().filter(contact -> (contact instanceof User && connectionManager.isOnline(contact.getID()))).forEach(user -> {
+ try {
+ writeProxy.write(user.getID(), input);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ });
+ }
+
+ @Override
+ public Class getInputClass() { return NameChangeEvent.class; }
+}
diff --git a/src/main/java/envoy/server/processors/ObjectProcessor.java b/src/main/java/envoy/server/processors/ObjectProcessor.java
index 91204b2..a542d8f 100755
--- a/src/main/java/envoy/server/processors/ObjectProcessor.java
+++ b/src/main/java/envoy/server/processors/ObjectProcessor.java
@@ -26,10 +26,10 @@ public interface ObjectProcessor {
/**
* @param input the request object
- * @param socketId the ID of the socket from which the object was received
+ * @param socketID the ID of the socket from which the object was received
* @param writeProxy the object that allows writing to a client
* @throws IOException if something went wrong during processing
* @since Envoy Server Standalone v0.1-alpha
*/
- void process(T input, long socketId, ObjectWriteProxy writeProxy) throws IOException;
+ void process(T input, long socketID, ObjectWriteProxy writeProxy) throws IOException;
}
diff --git a/src/main/java/envoy/server/processors/UserStatusChangeProcessor.java b/src/main/java/envoy/server/processors/UserStatusChangeProcessor.java
index 08c44e0..f4d56a7 100755
--- a/src/main/java/envoy/server/processors/UserStatusChangeProcessor.java
+++ b/src/main/java/envoy/server/processors/UserStatusChangeProcessor.java
@@ -1,6 +1,7 @@
package envoy.server.processors;
import java.io.IOException;
+import java.util.logging.Logger;
import envoy.data.User.UserStatus;
import envoy.event.UserStatusChangeEvent;
@@ -8,6 +9,7 @@ import envoy.server.data.PersistenceManager;
import envoy.server.data.User;
import envoy.server.net.ConnectionManager;
import envoy.server.net.ObjectWriteProxy;
+import envoy.util.EnvoyLog;
/**
* This processor handles incoming {@link UserStatusChangeEvent}.
@@ -24,18 +26,19 @@ public class UserStatusChangeProcessor implements ObjectProcessor getInputClass() { return UserStatusChangeEvent.class; }
@Override
- public void process(UserStatusChangeEvent input, long socketId, ObjectWriteProxy writeProxy) throws IOException {
+ public void process(UserStatusChangeEvent input, long socketID, ObjectWriteProxy writeProxy) throws IOException {
// new status should not equal old status
- if (input.get().equals(persistenceManager.getUserById(input.getID()).getStatus())) {
- System.out.println("Received an unnecessary UserStatusChangeEvent");
+ if (input.get().equals(persistenceManager.getUserByID(input.getID()).getStatus())) {
+ logger.warning("Received an unnecessary UserStatusChangeEvent");
return;
}
updateUserStatus(input);
-
}
/**
@@ -47,10 +50,11 @@ public class UserStatusChangeProcessor implements ObjectProcessor
-
-
+
+
+ value="org.postgresql.Driver" />
-
+ value="jdbc:postgresql://localhost/envoy" />
+
+ value="envoy" />
+
+
-
+ value="org.hibernate.dialect.PostgreSQL95Dialect" />
+
-
-
-
\ No newline at end of file
+