More work on JPA server
This commit is contained in:
parent
4d0b7ba84c
commit
10dc8b39aa
|
@ -97,3 +97,283 @@ org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=warning
|
||||||
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
|
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
|
||||||
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
|
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
|
||||||
org.eclipse.jdt.core.compiler.source=1.6
|
org.eclipse.jdt.core.compiler.source=1.6
|
||||||
|
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
|
||||||
|
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
|
||||||
|
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
|
||||||
|
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
|
||||||
|
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
|
||||||
|
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
|
||||||
|
org.eclipse.jdt.core.formatter.comment.format_header=false
|
||||||
|
org.eclipse.jdt.core.formatter.comment.format_html=true
|
||||||
|
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
|
||||||
|
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
|
||||||
|
org.eclipse.jdt.core.formatter.comment.format_source_code=true
|
||||||
|
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
|
||||||
|
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
|
||||||
|
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
|
||||||
|
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
|
||||||
|
org.eclipse.jdt.core.formatter.comment.line_length=120
|
||||||
|
org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
|
||||||
|
org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
|
||||||
|
org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
|
||||||
|
org.eclipse.jdt.core.formatter.compact_else_if=true
|
||||||
|
org.eclipse.jdt.core.formatter.continuation_indentation=2
|
||||||
|
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
|
||||||
|
org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
|
||||||
|
org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
|
||||||
|
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
|
||||||
|
org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
|
||||||
|
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
|
||||||
|
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
|
||||||
|
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
|
||||||
|
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
|
||||||
|
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
|
||||||
|
org.eclipse.jdt.core.formatter.indent_empty_lines=false
|
||||||
|
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
|
||||||
|
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
|
||||||
|
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||||
|
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
|
||||||
|
org.eclipse.jdt.core.formatter.indentation.size=4
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
|
||||||
|
org.eclipse.jdt.core.formatter.join_lines_in_comments=true
|
||||||
|
org.eclipse.jdt.core.formatter.join_wrapped_lines=true
|
||||||
|
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
|
||||||
|
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
|
||||||
|
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
|
||||||
|
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
|
||||||
|
org.eclipse.jdt.core.formatter.lineSplit=280
|
||||||
|
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
|
||||||
|
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
|
||||||
|
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
|
||||||
|
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||||
|
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
|
||||||
|
org.eclipse.jdt.core.formatter.tabulation.char=tab
|
||||||
|
org.eclipse.jdt.core.formatter.tabulation.size=4
|
||||||
|
org.eclipse.jdt.core.formatter.use_on_off_tags=true
|
||||||
|
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
||||||
|
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
|
||||||
|
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
|
||||||
|
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
formatter_profile=_James
|
||||||
|
formatter_settings_version=12
|
|
@ -75,6 +75,10 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IComposite
|
||||||
|
|
||||||
myNameToChild = new HashMap<String, BaseRuntimeChildDefinition>();
|
myNameToChild = new HashMap<String, BaseRuntimeChildDefinition>();
|
||||||
for (BaseRuntimeChildDefinition next : myChildren) {
|
for (BaseRuntimeChildDefinition next : myChildren) {
|
||||||
|
if (next instanceof RuntimeChildChoiceDefinition) {
|
||||||
|
String key = ((RuntimeChildChoiceDefinition) next).getElementName()+"[x]";
|
||||||
|
myNameToChild.put(key, next);
|
||||||
|
}
|
||||||
for (String nextName : next.getValidChildNames()) {
|
for (String nextName : next.getValidChildNames()) {
|
||||||
if (myNameToChild.containsKey(nextName)) {
|
if (myNameToChild.containsKey(nextName)) {
|
||||||
throw new ConfigurationException("Duplicate child name: " + nextName);
|
throw new ConfigurationException("Duplicate child name: " + nextName);
|
||||||
|
|
|
@ -36,40 +36,228 @@ public class DateRangeParam implements IQueryParameterAnd {
|
||||||
private QualifiedDateParam myUpperBound;
|
private QualifiedDateParam myUpperBound;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic constructor. Values must be supplied by calling {@link #setLowerBound(QualifiedDateParam)} and {@link #setUpperBound(QualifiedDateParam)}
|
* Basic constructor. Values must be supplied by calling {@link #setLowerBound(QualifiedDateParam)} and
|
||||||
|
* {@link #setUpperBound(QualifiedDateParam)}
|
||||||
*/
|
*/
|
||||||
public DateRangeParam() {
|
public DateRangeParam() {
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor which takes two strings representing the lower and upper bounds of the range
|
* Constructor which takes two Dates representing the lower and upper bounds of the range (inclusive on both ends)
|
||||||
*
|
*
|
||||||
* @param theLowerBound
|
* @param theLowerBound
|
||||||
* A qualified date param representing the lower date bound (optionally may include time), e.g. "2011-02-22" or "2011-02-22T13:12:00"
|
* A qualified date param representing the lower date bound (optionally may include time), e.g.
|
||||||
|
* "2011-02-22" or "2011-02-22T13:12:00". Will be treated inclusively.
|
||||||
* @param theLowerBound
|
* @param theLowerBound
|
||||||
* A qualified date param representing the upper date bound (optionally may include time), e.g. "2011-02-22" or "2011-02-22T13:12:00"
|
* A qualified date param representing the upper date bound (optionally may include time), e.g.
|
||||||
|
* "2011-02-22" or "2011-02-22T13:12:00". Will be treated inclusively.
|
||||||
|
*/
|
||||||
|
public DateRangeParam(Date theLowerBound, Date theUpperBound) {
|
||||||
|
setRangeFromDatesInclusive(theLowerBound, theUpperBound);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the range from a single date param. If theDateParam has no qualifier, treats it as the lower and upper bound
|
||||||
|
* (e.g. 2011-01-02 would match any time on that day). If theDateParam has a qualifier, treats it as either the
|
||||||
|
* lower or upper bound, with no opposite bound.
|
||||||
|
*/
|
||||||
|
public DateRangeParam(QualifiedDateParam theDateParam) {
|
||||||
|
if (theDateParam == null) {
|
||||||
|
throw new NullPointerException("theDateParam can not be null");
|
||||||
|
}
|
||||||
|
if (theDateParam.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("theDateParam can not be empty");
|
||||||
|
}
|
||||||
|
if (theDateParam.getComparator() == null) {
|
||||||
|
setRangeFromDatesInclusive(theDateParam.getValueAsString(), theDateParam.getValueAsString());
|
||||||
|
} else {
|
||||||
|
switch (theDateParam.getComparator()) {
|
||||||
|
case GREATERTHAN:
|
||||||
|
case GREATERTHAN_OR_EQUALS:
|
||||||
|
myLowerBound = theDateParam;
|
||||||
|
myUpperBound = null;
|
||||||
|
break;
|
||||||
|
case LESSTHAN:
|
||||||
|
case LESSTHAN_OR_EQUALS:
|
||||||
|
myLowerBound = null;
|
||||||
|
myUpperBound = theDateParam;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Should not happen
|
||||||
|
throw new IllegalStateException("Unknown comparator:" + theDateParam.getComparator() + ". This is a bug.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
validateAndThrowDataFormatExceptionIfInvalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor which takes two strings representing the lower and upper bounds of the range (inclusive on both ends)
|
||||||
|
*
|
||||||
|
* @param theLowerBound
|
||||||
|
* A qualified date param representing the lower date bound (optionally may include time), e.g.
|
||||||
|
* "2011-02-22" or "2011-02-22T13:12:00"
|
||||||
|
* @param theLowerBound
|
||||||
|
* A qualified date param representing the upper date bound (optionally may include time), e.g.
|
||||||
|
* "2011-02-22" or "2011-02-22T13:12:00"
|
||||||
*/
|
*/
|
||||||
public DateRangeParam(String theLowerBound, String theUpperBound) {
|
public DateRangeParam(String theLowerBound, String theUpperBound) {
|
||||||
|
setRangeFromDatesInclusive(theLowerBound, theUpperBound);
|
||||||
|
}
|
||||||
|
|
||||||
|
public QualifiedDateParam getLowerBound() {
|
||||||
|
return myLowerBound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getLowerBoundAsInstant() {
|
||||||
|
if (myLowerBound == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Date retVal = myLowerBound.getValue();
|
||||||
|
if (myLowerBound.getComparator() != null) {
|
||||||
|
switch (myLowerBound.getComparator()) {
|
||||||
|
case GREATERTHAN:
|
||||||
|
retVal = myLowerBound.getPrecision().add(retVal, 1);
|
||||||
|
break;
|
||||||
|
case GREATERTHAN_OR_EQUALS:
|
||||||
|
break;
|
||||||
|
case LESSTHAN:
|
||||||
|
case LESSTHAN_OR_EQUALS:
|
||||||
|
throw new IllegalStateException("Unvalid lower bound comparator: " + myLowerBound.getComparator());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QualifiedDateParam getUpperBound() {
|
||||||
|
return myUpperBound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getUpperBoundAsInstant() {
|
||||||
|
if (myUpperBound == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Date retVal = myUpperBound.getValue();
|
||||||
|
if (myUpperBound.getComparator() != null) {
|
||||||
|
switch (myUpperBound.getComparator()) {
|
||||||
|
case LESSTHAN:
|
||||||
|
retVal = new Date(retVal.getTime() - 1L);
|
||||||
|
break;
|
||||||
|
case LESSTHAN_OR_EQUALS:
|
||||||
|
retVal = myUpperBound.getPrecision().add(retVal, 1);
|
||||||
|
retVal = new Date(retVal.getTime() - 1L);
|
||||||
|
break;
|
||||||
|
case GREATERTHAN_OR_EQUALS:
|
||||||
|
case GREATERTHAN:
|
||||||
|
throw new IllegalStateException("Unvalid upper bound comparator: " + myUpperBound.getComparator());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<List<String>> getValuesAsQueryTokens() {
|
||||||
|
ArrayList<List<String>> retVal = new ArrayList<List<String>>();
|
||||||
|
if (myLowerBound != null) {
|
||||||
|
retVal.add(Collections.singletonList(myLowerBound.getValueAsQueryToken()));
|
||||||
|
}
|
||||||
|
if (myUpperBound != null) {
|
||||||
|
retVal.add(Collections.singletonList(myUpperBound.getValueAsQueryToken()));
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLowerBound(QualifiedDateParam theLowerBound) {
|
||||||
|
myLowerBound = theLowerBound;
|
||||||
|
validateAndThrowDataFormatExceptionIfInvalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the range from a pair of dates, inclusive on both ends
|
||||||
|
*
|
||||||
|
* @param theLowerBound
|
||||||
|
* A qualified date param representing the lower date bound (optionally may include time), e.g.
|
||||||
|
* "2011-02-22" or "2011-02-22T13:12:00". Will be treated inclusively.
|
||||||
|
* @param theLowerBound
|
||||||
|
* A qualified date param representing the upper date bound (optionally may include time), e.g.
|
||||||
|
* "2011-02-22" or "2011-02-22T13:12:00". Will be treated inclusively.
|
||||||
|
*/
|
||||||
|
public void setRangeFromDatesInclusive(Date theLowerBound, Date theUpperBound) {
|
||||||
myLowerBound = new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, theLowerBound);
|
myLowerBound = new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, theLowerBound);
|
||||||
myUpperBound = new QualifiedDateParam(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS, theUpperBound);
|
myUpperBound = new QualifiedDateParam(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS, theUpperBound);
|
||||||
validateAndThrowDataFormatExceptionIfInvalid();
|
validateAndThrowDataFormatExceptionIfInvalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor which takes two Dates representing the lower and upper bounds of the range
|
* Sets the range from a pair of dates, inclusive on both ends
|
||||||
*
|
*
|
||||||
* @param theLowerBound
|
* @param theLowerBound
|
||||||
* A qualified date param representing the lower date bound (optionally may include time), e.g. "2011-02-22" or "2011-02-22T13:12:00"
|
* A qualified date param representing the lower date bound (optionally may include time), e.g.
|
||||||
|
* "2011-02-22" or "2011-02-22T13:12:00". Will be treated inclusively.
|
||||||
* @param theLowerBound
|
* @param theLowerBound
|
||||||
* A qualified date param representing the upper date bound (optionally may include time), e.g. "2011-02-22" or "2011-02-22T13:12:00"
|
* A qualified date param representing the upper date bound (optionally may include time), e.g.
|
||||||
|
* "2011-02-22" or "2011-02-22T13:12:00". Will be treated inclusively.
|
||||||
*/
|
*/
|
||||||
public DateRangeParam(Date theLowerBound, Date theUpperBound) {
|
public void setRangeFromDatesInclusive(String theLowerBound, String theUpperBound) {
|
||||||
myLowerBound = new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, theLowerBound);
|
myLowerBound = new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, theLowerBound);
|
||||||
myUpperBound = new QualifiedDateParam(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS, theUpperBound);
|
myUpperBound = new QualifiedDateParam(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS, theUpperBound);
|
||||||
validateAndThrowDataFormatExceptionIfInvalid();
|
validateAndThrowDataFormatExceptionIfInvalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setUpperBound(QualifiedDateParam theUpperBound) {
|
||||||
|
myUpperBound = theUpperBound;
|
||||||
|
validateAndThrowDataFormatExceptionIfInvalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValuesAsQueryTokens(List<List<String>> theParameters) throws InvalidRequestException {
|
||||||
|
for (List<String> paramList : theParameters) {
|
||||||
|
if (paramList.size() == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (paramList.size() > 1) {
|
||||||
|
throw new InvalidRequestException("DateRange parameter does not suppport OR queries");
|
||||||
|
}
|
||||||
|
String param = paramList.get(0);
|
||||||
|
QualifiedDateParam parsed = new QualifiedDateParam();
|
||||||
|
parsed.setValueAsQueryToken(param);
|
||||||
|
addParam(parsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addParam(QualifiedDateParam theParsed) throws InvalidRequestException {
|
||||||
|
if (theParsed.getComparator() == null) {
|
||||||
|
if (myLowerBound != null || myUpperBound != null) {
|
||||||
|
throw new InvalidRequestException("Can not have multiple date range parameters for the same param without a qualifier");
|
||||||
|
}
|
||||||
|
|
||||||
|
myLowerBound = theParsed;
|
||||||
|
myUpperBound = theParsed;
|
||||||
|
// TODO: in this case, should set lower and upper to exact moments
|
||||||
|
// using specified precision
|
||||||
|
} else {
|
||||||
|
|
||||||
|
switch (theParsed.getComparator()) {
|
||||||
|
case GREATERTHAN:
|
||||||
|
case GREATERTHAN_OR_EQUALS:
|
||||||
|
if (myLowerBound != null) {
|
||||||
|
throw new InvalidRequestException("Can not have multiple date range parameters for the same param that specify a lower bound");
|
||||||
|
}
|
||||||
|
myLowerBound = theParsed;
|
||||||
|
break;
|
||||||
|
case LESSTHAN:
|
||||||
|
case LESSTHAN_OR_EQUALS:
|
||||||
|
if (myUpperBound != null) {
|
||||||
|
throw new InvalidRequestException("Can not have multiple date range parameters for the same param that specify an upper bound");
|
||||||
|
}
|
||||||
|
myUpperBound = theParsed;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new InvalidRequestException("Unknown comparator: " + theParsed.getComparator());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void validateAndThrowDataFormatExceptionIfInvalid() {
|
private void validateAndThrowDataFormatExceptionIfInvalid() {
|
||||||
boolean haveLowerBound = myLowerBound != null && myLowerBound.isEmpty() == false;
|
boolean haveLowerBound = myLowerBound != null && myLowerBound.isEmpty() == false;
|
||||||
|
@ -112,119 +300,4 @@ public class DateRangeParam implements IQueryParameterAnd {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addParam(QualifiedDateParam theParsed) throws InvalidRequestException {
|
|
||||||
if (theParsed.getComparator() == null) {
|
|
||||||
if (myLowerBound != null || myUpperBound != null) {
|
|
||||||
throw new InvalidRequestException("Can not have multiple date range parameters for the same param without a qualifier");
|
|
||||||
}
|
|
||||||
|
|
||||||
myLowerBound = theParsed;
|
|
||||||
myUpperBound = theParsed;
|
|
||||||
// TODO: in this case, should set lower and upper to exact moments using specified precision
|
|
||||||
} else {
|
|
||||||
|
|
||||||
switch (theParsed.getComparator()) {
|
|
||||||
case GREATERTHAN:
|
|
||||||
case GREATERTHAN_OR_EQUALS:
|
|
||||||
if (myLowerBound != null) {
|
|
||||||
throw new InvalidRequestException("Can not have multiple date range parameters for the same param that specify a lower bound");
|
|
||||||
}
|
|
||||||
myLowerBound = theParsed;
|
|
||||||
break;
|
|
||||||
case LESSTHAN:
|
|
||||||
case LESSTHAN_OR_EQUALS:
|
|
||||||
if (myUpperBound != null) {
|
|
||||||
throw new InvalidRequestException("Can not have multiple date range parameters for the same param that specify an upper bound");
|
|
||||||
}
|
|
||||||
myUpperBound = theParsed;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new InvalidRequestException("Unknown comparator: " + theParsed.getComparator());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public QualifiedDateParam getLowerBound() {
|
|
||||||
return myLowerBound;
|
|
||||||
}
|
|
||||||
|
|
||||||
public QualifiedDateParam getUpperBound() {
|
|
||||||
return myUpperBound;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<List<String>> getValuesAsQueryTokens() {
|
|
||||||
ArrayList<List<String>> retVal = new ArrayList<List<String>>();
|
|
||||||
if (myLowerBound != null) {
|
|
||||||
retVal.add(Collections.singletonList(myLowerBound.getValueAsQueryToken()));
|
|
||||||
}
|
|
||||||
if (myUpperBound != null) {
|
|
||||||
retVal.add(Collections.singletonList(myUpperBound.getValueAsQueryToken()));
|
|
||||||
}
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLowerBound(QualifiedDateParam theLowerBound) {
|
|
||||||
myLowerBound = theLowerBound;
|
|
||||||
validateAndThrowDataFormatExceptionIfInvalid();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUpperBound(QualifiedDateParam theUpperBound) {
|
|
||||||
myUpperBound = theUpperBound;
|
|
||||||
validateAndThrowDataFormatExceptionIfInvalid();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setValuesAsQueryTokens(List<List<String>> theParameters) throws InvalidRequestException {
|
|
||||||
for (List<String> paramList : theParameters) {
|
|
||||||
if (paramList.size() == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (paramList.size() > 1) {
|
|
||||||
throw new InvalidRequestException("DateRange parameter does not suppport OR queries");
|
|
||||||
}
|
|
||||||
String param = paramList.get(0);
|
|
||||||
QualifiedDateParam parsed = new QualifiedDateParam();
|
|
||||||
parsed.setValueAsQueryToken(param);
|
|
||||||
addParam(parsed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getLowerBoundAsInstant() {
|
|
||||||
Date retVal = myLowerBound.getValue();
|
|
||||||
if (myLowerBound.getComparator() != null) {
|
|
||||||
switch (myLowerBound.getComparator()) {
|
|
||||||
case GREATERTHAN:
|
|
||||||
retVal = myLowerBound.getPrecision().add(retVal, 1);
|
|
||||||
break;
|
|
||||||
case GREATERTHAN_OR_EQUALS:
|
|
||||||
break;
|
|
||||||
case LESSTHAN:
|
|
||||||
case LESSTHAN_OR_EQUALS:
|
|
||||||
throw new IllegalStateException("Unvalid lower bound comparator: " + myLowerBound.getComparator());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getUpperBoundAsInstant() {
|
|
||||||
Date retVal = myUpperBound.getValue();
|
|
||||||
if (myUpperBound.getComparator() != null) {
|
|
||||||
switch (myUpperBound.getComparator()) {
|
|
||||||
case LESSTHAN:
|
|
||||||
retVal = new Date(retVal.getTime() - 1L);
|
|
||||||
break;
|
|
||||||
case LESSTHAN_OR_EQUALS:
|
|
||||||
retVal = myUpperBound.getPrecision().add(retVal, 1);
|
|
||||||
retVal = new Date(retVal.getTime() - 1L);
|
|
||||||
break;
|
|
||||||
case GREATERTHAN_OR_EQUALS:
|
|
||||||
case GREATERTHAN:
|
|
||||||
throw new IllegalStateException("Unvalid upper bound comparator: " + myUpperBound.getComparator());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,15 @@ public class QualifiedDateParam extends DateTimeDt implements IQueryParameterTyp
|
||||||
setValueAsString(theDate);
|
setValueAsString(theDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor which takes a complete [qualifier]{date} string.
|
||||||
|
*
|
||||||
|
* @param theString The string
|
||||||
|
*/
|
||||||
|
public QualifiedDateParam(String theString) {
|
||||||
|
setValueAsQueryToken(theString);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the comparator, or <code>null</code> if none has been set
|
* Returns the comparator, or <code>null</code> if none has been set
|
||||||
*/
|
*/
|
||||||
|
@ -70,6 +79,17 @@ public class QualifiedDateParam extends DateTimeDt implements IQueryParameterTyp
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if no date/time is specified. Note that this method
|
||||||
|
* does not check the comparator, so a QualifiedDateParam with only a comparator
|
||||||
|
* and no date/time is considered empty.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
// Just here to provide a javadoc
|
||||||
|
return super.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
public void setComparator(QuantityCompararatorEnum theComparator) {
|
public void setComparator(QuantityCompararatorEnum theComparator) {
|
||||||
myComparator = theComparator;
|
myComparator = theComparator;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,32 @@ public class FhirTerser {
|
||||||
|
|
||||||
private FhirContext myContext;
|
private FhirContext myContext;
|
||||||
|
|
||||||
|
public BaseRuntimeChildDefinition getDefinition(Class<? extends IResource> theResourceType, String thePath) {
|
||||||
|
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResourceType);
|
||||||
|
|
||||||
|
BaseRuntimeElementCompositeDefinition<?> currentDef = def;
|
||||||
|
|
||||||
|
List<String> parts = Arrays.asList(thePath.split("\\."));
|
||||||
|
List<String> subList = parts.subList(1, parts.size() );
|
||||||
|
if (subList.size()< 1) {
|
||||||
|
throw new ConfigurationException("Invalid path: " + thePath);
|
||||||
|
}
|
||||||
|
return getDefinition(currentDef, subList);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private BaseRuntimeChildDefinition getDefinition(BaseRuntimeElementCompositeDefinition<?> theCurrentDef, List<String> theSubList) {
|
||||||
|
BaseRuntimeChildDefinition nextDef = theCurrentDef.getChildByNameOrThrowDataFormatException(theSubList.get(0));
|
||||||
|
|
||||||
|
if (theSubList.size() == 1) {
|
||||||
|
return nextDef;
|
||||||
|
} else {
|
||||||
|
BaseRuntimeElementCompositeDefinition<?> cmp=(BaseRuntimeElementCompositeDefinition<?>) nextDef.getChildByName(theSubList.get(0));
|
||||||
|
return getDefinition(cmp, theSubList.subList(1, theSubList.size() ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public List<Object> getValues(IResource theResource, String thePath) {
|
public List<Object> getValues(IResource theResource, String thePath) {
|
||||||
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
|
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
|
||||||
|
|
||||||
|
@ -57,7 +83,8 @@ public class FhirTerser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Object> getValues(BaseRuntimeElementCompositeDefinition<?> theCurrentDef, Object theCurrentObj, List<String> theSubList) {
|
private List<Object> getValues(BaseRuntimeElementCompositeDefinition<?> theCurrentDef, Object theCurrentObj, List<String> theSubList) {
|
||||||
BaseRuntimeChildDefinition nextDef = theCurrentDef.getChildByNameOrThrowDataFormatException(theSubList.get(0));
|
String name = theSubList.get(0);
|
||||||
|
BaseRuntimeChildDefinition nextDef = theCurrentDef.getChildByNameOrThrowDataFormatException(name);
|
||||||
List<? extends IElement> values = nextDef.getAccessor().getValues(theCurrentObj);
|
List<? extends IElement> values = nextDef.getAccessor().getValues(theCurrentObj);
|
||||||
List<Object> retVal = new ArrayList<Object>();
|
List<Object> retVal = new ArrayList<Object>();
|
||||||
|
|
||||||
|
|
|
@ -18,18 +18,25 @@ public class DateRangeParamTest {
|
||||||
|
|
||||||
private static SimpleDateFormat ourFmt;
|
private static SimpleDateFormat ourFmt;
|
||||||
|
|
||||||
@BeforeClass
|
@Test
|
||||||
public static void beforeClass() {
|
public void testDay() throws Exception {
|
||||||
ourFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSS");
|
assertEquals(parse("2011-01-01 00:00:00.0000"), create(">=2011-01-01", "<2011-01-02").getLowerBoundAsInstant());
|
||||||
|
assertEquals(parseM1("2011-01-02 00:00:00.0000"), create(">=2011-01-01", "<2011-01-02").getUpperBoundAsInstant());
|
||||||
|
|
||||||
|
assertEquals(parse("2011-01-02 00:00:00.0000"), create(">2011-01-01", "<=2011-01-02").getLowerBoundAsInstant());
|
||||||
|
assertEquals(parseM1("2011-01-03 00:00:00.0000"), create(">2011-01-01", "<=2011-01-02").getUpperBoundAsInstant());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testYear() throws Exception {
|
public void testFromQualifiedDateParam() throws Exception {
|
||||||
assertEquals(parse("2011-01-01 00:00:00.0000"), create(">=2011", "<2012").getLowerBoundAsInstant());
|
assertEquals(parse("2011-01-01 00:00:00.0000"), create("2011-01-01").getLowerBoundAsInstant());
|
||||||
assertEquals(parseM1("2012-01-01 00:00:00.0000"), create(">=2011", "<2012").getUpperBoundAsInstant());
|
assertEquals(parseM1("2011-01-02 00:00:00.0000"), create("2011-01-01").getUpperBoundAsInstant());
|
||||||
|
|
||||||
assertEquals(parse("2012-01-01 00:00:00.0000"), create(">2011", "<=2012").getLowerBoundAsInstant());
|
assertEquals(parse("2011-01-01 00:00:00.0000"), create(">=2011-01-01").getLowerBoundAsInstant());
|
||||||
assertEquals(parseM1("2014-01-01 00:00:00.0000"), create(">2011", "<=2013").getUpperBoundAsInstant());
|
assertEquals(null, create(">=2011-01-01").getUpperBoundAsInstant());
|
||||||
|
|
||||||
|
assertEquals(null, create("<=2011-01-01").getLowerBoundAsInstant());
|
||||||
|
assertEquals(parseM1("2011-01-02 00:00:00.0000"), create("<=2011-01-01").getUpperBoundAsInstant());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -41,15 +48,6 @@ public class DateRangeParamTest {
|
||||||
assertEquals(parseM1("2011-03-01 00:00:00.0000"), create(">2011-01", "<=2011-02").getUpperBoundAsInstant());
|
assertEquals(parseM1("2011-03-01 00:00:00.0000"), create(">2011-01", "<=2011-02").getUpperBoundAsInstant());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDay() throws Exception {
|
|
||||||
assertEquals(parse("2011-01-01 00:00:00.0000"), create(">=2011-01-01", "<2011-01-02").getLowerBoundAsInstant());
|
|
||||||
assertEquals(parseM1("2011-01-02 00:00:00.0000"), create(">=2011-01-01", "<2011-01-02").getUpperBoundAsInstant());
|
|
||||||
|
|
||||||
assertEquals(parse("2011-01-02 00:00:00.0000"), create(">2011-01-01", "<=2011-01-02").getLowerBoundAsInstant());
|
|
||||||
assertEquals(parseM1("2011-01-03 00:00:00.0000"), create(">2011-01-01", "<=2011-01-02").getUpperBoundAsInstant());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSecond() throws Exception {
|
public void testSecond() throws Exception {
|
||||||
assertEquals(parse("2011-01-01 00:00:00.0000"), create(">=2011-01-01T00:00:00", "<2011-01-01T01:00:00").getLowerBoundAsInstant());
|
assertEquals(parse("2011-01-01 00:00:00.0000"), create(">=2011-01-01T00:00:00", "<2011-01-01T01:00:00").getLowerBoundAsInstant());
|
||||||
|
@ -59,6 +57,19 @@ public class DateRangeParamTest {
|
||||||
assertEquals(parseM1("2011-01-01 02:00:01.0000"), create(">2011-01-01T00:00:00", "<=2011-01-01T02:00:00").getUpperBoundAsInstant());
|
assertEquals(parseM1("2011-01-01 02:00:01.0000"), create(">2011-01-01T00:00:00", "<=2011-01-01T02:00:00").getUpperBoundAsInstant());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testYear() throws Exception {
|
||||||
|
assertEquals(parse("2011-01-01 00:00:00.0000"), create(">=2011", "<2012").getLowerBoundAsInstant());
|
||||||
|
assertEquals(parseM1("2012-01-01 00:00:00.0000"), create(">=2011", "<2012").getUpperBoundAsInstant());
|
||||||
|
|
||||||
|
assertEquals(parse("2012-01-01 00:00:00.0000"), create(">2011", "<=2012").getLowerBoundAsInstant());
|
||||||
|
assertEquals(parseM1("2014-01-01 00:00:00.0000"), create(">2011", "<=2013").getUpperBoundAsInstant());
|
||||||
|
}
|
||||||
|
|
||||||
|
private DateRangeParam create(String theString) {
|
||||||
|
return new DateRangeParam(new QualifiedDateParam(theString));
|
||||||
|
}
|
||||||
|
|
||||||
private Date parse(String theString) throws ParseException {
|
private Date parse(String theString) throws ParseException {
|
||||||
return ourFmt.parse(theString);
|
return ourFmt.parse(theString);
|
||||||
}
|
}
|
||||||
|
@ -71,6 +82,11 @@ public class DateRangeParamTest {
|
||||||
return new Date(ourFmt.parse(theString).getTime() + 1L);
|
return new Date(ourFmt.parse(theString).getTime() + 1L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() {
|
||||||
|
ourFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSS");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static DateRangeParam create(String theLower, String theUpper) throws InvalidRequestException {
|
private static DateRangeParam create(String theLower, String theUpper) throws InvalidRequestException {
|
||||||
DateRangeParam p = new DateRangeParam();
|
DateRangeParam p = new DateRangeParam();
|
||||||
|
|
|
@ -1,430 +0,0 @@
|
||||||
package ca.uhn.fhir.jpa.dao;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.PersistenceContext;
|
|
||||||
import javax.persistence.PersistenceContextType;
|
|
||||||
import javax.persistence.TypedQuery;
|
|
||||||
import javax.persistence.criteria.CriteriaBuilder;
|
|
||||||
import javax.persistence.criteria.CriteriaQuery;
|
|
||||||
import javax.persistence.criteria.Join;
|
|
||||||
import javax.persistence.criteria.JoinType;
|
|
||||||
import javax.persistence.criteria.Predicate;
|
|
||||||
import javax.persistence.criteria.Root;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Required;
|
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
|
||||||
import org.springframework.transaction.TransactionStatus;
|
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
import org.springframework.transaction.support.TransactionCallback;
|
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
|
||||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
|
||||||
import ca.uhn.fhir.jpa.entity.BaseHasResource;
|
|
||||||
import ca.uhn.fhir.jpa.entity.BaseResourceTable;
|
|
||||||
import ca.uhn.fhir.jpa.entity.BaseTag;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceHistoryTable;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamToken;
|
|
||||||
import ca.uhn.fhir.model.api.IDatatype;
|
|
||||||
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
|
||||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
|
||||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
|
||||||
import ca.uhn.fhir.model.api.Tag;
|
|
||||||
import ca.uhn.fhir.model.api.TagList;
|
|
||||||
import ca.uhn.fhir.model.dstu.composite.CodeableConceptDt;
|
|
||||||
import ca.uhn.fhir.model.dstu.composite.CodingDt;
|
|
||||||
import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
|
|
||||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
|
||||||
import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
|
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
|
||||||
import ca.uhn.fhir.model.primitive.StringDt;
|
|
||||||
import ca.uhn.fhir.parser.IParser;
|
|
||||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
|
||||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
|
||||||
import ca.uhn.fhir.util.FhirTerser;
|
|
||||||
|
|
||||||
public class CopyOfFhirResourceDao<T extends IResource, X extends BaseResourceTable<T>> implements IFhirResourceDao<T> {
|
|
||||||
|
|
||||||
private FhirContext myCtx;
|
|
||||||
@PersistenceContext(name = "FHIR_UT", type = PersistenceContextType.TRANSACTION, unitName = "FHIR_UT")
|
|
||||||
private EntityManager myEntityManager;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private PlatformTransactionManager myPlatformTransactionManager;
|
|
||||||
|
|
||||||
private Class<T> myResourceType;
|
|
||||||
private Class<X> myTableType;
|
|
||||||
|
|
||||||
private void addTokenPredicate(CriteriaQuery<X> theCriteriaQuery, List<IQueryParameterType> theOrParams, Root<X> theFrom, CriteriaBuilder theBuilder) {
|
|
||||||
if (theOrParams == null || theOrParams.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (theOrParams.size() > 1) {
|
|
||||||
throw new UnsupportedOperationException("Multiple values not yet supported"); // TODO: implement
|
|
||||||
}
|
|
||||||
|
|
||||||
IQueryParameterType params = theOrParams.get(0);
|
|
||||||
|
|
||||||
String code;
|
|
||||||
String system;
|
|
||||||
if (params instanceof IdentifierDt) {
|
|
||||||
IdentifierDt id = (IdentifierDt) params;
|
|
||||||
system = id.getSystem().getValueAsString();
|
|
||||||
code = id.getValue().getValue();
|
|
||||||
} else if (params instanceof CodingDt) {
|
|
||||||
CodingDt id = (CodingDt) params;
|
|
||||||
system = id.getSystem().getValueAsString();
|
|
||||||
code = id.getCode().getValue();
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Invalid token type: " + params.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
Join<Object, Object> join = theFrom.join("myParamsToken", JoinType.LEFT);
|
|
||||||
ArrayList<Predicate> predicates = (new ArrayList<Predicate>());
|
|
||||||
|
|
||||||
if (system != null) {
|
|
||||||
predicates.add(theBuilder.equal(join.get("mySystem"), system));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (code != null) {
|
|
||||||
predicates.add(theBuilder.equal(join.get("myValue"), code));
|
|
||||||
}
|
|
||||||
|
|
||||||
theCriteriaQuery.where(predicates.toArray(new Predicate[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.SUPPORTS)
|
|
||||||
@Override
|
|
||||||
public MethodOutcome create(T theResource) {
|
|
||||||
|
|
||||||
final X entity = toEntity(theResource);
|
|
||||||
|
|
||||||
entity.setPublished(new Date());
|
|
||||||
entity.setUpdated(entity.getPublished());
|
|
||||||
|
|
||||||
final List<ResourceIndexedSearchParamString> stringParams = extractSearchParamStrings(entity, theResource);
|
|
||||||
final List<ResourceIndexedSearchParamToken> tokenParams = extractSearchParamTokens(entity, theResource);
|
|
||||||
|
|
||||||
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
|
|
||||||
template.execute(new TransactionCallback<X>() {
|
|
||||||
@Override
|
|
||||||
public X doInTransaction(TransactionStatus theStatus) {
|
|
||||||
myEntityManager.persist(entity);
|
|
||||||
for (ResourceIndexedSearchParamString next : stringParams) {
|
|
||||||
myEntityManager.persist(next);
|
|
||||||
}
|
|
||||||
for (ResourceIndexedSearchParamToken next : tokenParams) {
|
|
||||||
myEntityManager.persist(next);
|
|
||||||
}
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
MethodOutcome outcome = toMethodOutcome(entity);
|
|
||||||
return outcome;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<ResourceIndexedSearchParamString> extractSearchParamStrings(X theEntity, T theResource) {
|
|
||||||
ArrayList<ResourceIndexedSearchParamString> retVal = new ArrayList<ResourceIndexedSearchParamString>();
|
|
||||||
|
|
||||||
RuntimeResourceDefinition def = myCtx.getResourceDefinition(theResource);
|
|
||||||
FhirTerser t = myCtx.newTerser();
|
|
||||||
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
|
|
||||||
if (nextSpDef.getParamType() != SearchParamTypeEnum.STRING) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (nextSpDef.getPath().isEmpty()) {
|
|
||||||
continue; // TODO: implement phoenetic, and any others that have no path
|
|
||||||
}
|
|
||||||
|
|
||||||
String nextPath = nextSpDef.getPath();
|
|
||||||
List<Object> values = t.getValues(theResource, nextPath);
|
|
||||||
for (Object nextObject : values) {
|
|
||||||
if (((IDatatype) nextObject).isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (nextObject instanceof IPrimitiveDatatype<?>) {
|
|
||||||
IPrimitiveDatatype<?> nextValue = (IPrimitiveDatatype<?>) nextObject;
|
|
||||||
ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(nextSpDef.getName(), nextValue.getValueAsString());
|
|
||||||
nextEntity.setResource(theEntity);
|
|
||||||
retVal.add(nextEntity);
|
|
||||||
} else if (nextObject instanceof HumanNameDt) {
|
|
||||||
for (StringDt nextName : ((HumanNameDt) nextObject).getFamily()) {
|
|
||||||
if (nextName.isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(nextSpDef.getName(), nextName.getValueAsString());
|
|
||||||
nextEntity.setResource(theEntity);
|
|
||||||
retVal.add(nextEntity);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<ResourceIndexedSearchParamToken> extractSearchParamTokens(X theEntity, T theResource) {
|
|
||||||
ArrayList<ResourceIndexedSearchParamToken> retVal = new ArrayList<ResourceIndexedSearchParamToken>();
|
|
||||||
|
|
||||||
RuntimeResourceDefinition def = myCtx.getResourceDefinition(theResource);
|
|
||||||
FhirTerser t = myCtx.newTerser();
|
|
||||||
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
|
|
||||||
if (nextSpDef.getParamType() != SearchParamTypeEnum.TOKEN) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String nextPath = nextSpDef.getPath();
|
|
||||||
List<Object> values = t.getValues(theResource, nextPath);
|
|
||||||
for (Object nextObject : values) {
|
|
||||||
ResourceIndexedSearchParamToken nextEntity;
|
|
||||||
if (nextObject instanceof IdentifierDt) {
|
|
||||||
IdentifierDt nextValue = (IdentifierDt) nextObject;
|
|
||||||
if (nextValue.isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
nextEntity = new ResourceIndexedSearchParamToken(nextSpDef.getName(), nextValue.getSystem().getValueAsString(), nextValue.getValue().getValue());
|
|
||||||
} else if (nextObject instanceof IPrimitiveDatatype<?>) {
|
|
||||||
IPrimitiveDatatype<?> nextValue = (IPrimitiveDatatype<?>) nextObject;
|
|
||||||
if (nextValue.isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
nextEntity = new ResourceIndexedSearchParamToken(nextSpDef.getName(), null, nextValue.getValueAsString());
|
|
||||||
} else if (nextObject instanceof CodeableConceptDt) {
|
|
||||||
CodeableConceptDt nextCC = (CodeableConceptDt) nextObject;
|
|
||||||
for (CodingDt nextCoding : nextCC.getCoding()) {
|
|
||||||
if (nextCoding.isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
nextEntity = new ResourceIndexedSearchParamToken(nextSpDef.getName(), nextCoding.getSystem().getValueAsString(), nextCoding.getCode().getValue());
|
|
||||||
nextEntity.setResource(theEntity);
|
|
||||||
retVal.add(nextEntity);
|
|
||||||
}
|
|
||||||
nextEntity = null;
|
|
||||||
} else {
|
|
||||||
throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass());
|
|
||||||
}
|
|
||||||
if (nextEntity != null) {
|
|
||||||
nextEntity.setResource(theEntity);
|
|
||||||
retVal.add(nextEntity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.REQUIRED)
|
|
||||||
@Override
|
|
||||||
public List<T> history(IdDt theId) {
|
|
||||||
ArrayList<T> retVal = new ArrayList<T>();
|
|
||||||
|
|
||||||
String resourceType = myCtx.getResourceDefinition(myResourceType).getName();
|
|
||||||
TypedQuery<ResourceHistoryTable> q = myEntityManager.createQuery(ResourceHistoryTable.Q_GETALL, ResourceHistoryTable.class);
|
|
||||||
q.setParameter("PID", theId.asLong());
|
|
||||||
q.setParameter("RESTYPE", resourceType);
|
|
||||||
|
|
||||||
// TypedQuery<ResourceHistoryTable> query =
|
|
||||||
// myEntityManager.createQuery(criteriaQuery);
|
|
||||||
List<ResourceHistoryTable> results = q.getResultList();
|
|
||||||
for (ResourceHistoryTable next : results) {
|
|
||||||
retVal.add(toResource(next));
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
retVal.add(read(theId));
|
|
||||||
} catch (ResourceNotFoundException e) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retVal.isEmpty()) {
|
|
||||||
throw new ResourceNotFoundException(theId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void populateResourceIntoEntity(T theResource, X retVal) {
|
|
||||||
retVal.setResource(myCtx.newJsonParser().encodeResourceToString(theResource));
|
|
||||||
retVal.setEncoding(EncodingEnum.JSON);
|
|
||||||
|
|
||||||
TagList tagList = (TagList) theResource.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST);
|
|
||||||
if (tagList != null) {
|
|
||||||
for (Tag next : tagList) {
|
|
||||||
retVal.addTag(next.getTerm(), next.getLabel(), next.getScheme());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void postConstruct() throws Exception {
|
|
||||||
myResourceType = myTableType.newInstance().getResourceType();
|
|
||||||
myCtx = new FhirContext(myResourceType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.REQUIRED)
|
|
||||||
@Override
|
|
||||||
public T read(IdDt theId) {
|
|
||||||
X entity = readEntity(theId);
|
|
||||||
|
|
||||||
T retVal = toResource(entity);
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
private X readEntity(IdDt theId) {
|
|
||||||
X entity = (X) myEntityManager.find(myTableType, theId.asLong());
|
|
||||||
if (entity == null) {
|
|
||||||
throw new ResourceNotFoundException(theId);
|
|
||||||
}
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<T> search(Map<String, IQueryParameterType> theParams) {
|
|
||||||
Map<String, List<List<IQueryParameterType>>> map = new HashMap<String, List<List<IQueryParameterType>>>();
|
|
||||||
for (Entry<String, IQueryParameterType> nextEntry : theParams.entrySet()) {
|
|
||||||
map.put(nextEntry.getKey(), new ArrayList<List<IQueryParameterType>>());
|
|
||||||
map.get(nextEntry.getKey()).add(Collections.singletonList(nextEntry.getValue()));
|
|
||||||
}
|
|
||||||
return searchWithAndOr(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<T> search(String theSpName, IQueryParameterType theValue) {
|
|
||||||
return search(Collections.singletonMap(theSpName, theValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<T> searchWithAndOr(Map<String, List<List<IQueryParameterType>>> theParams) {
|
|
||||||
Map<String, List<List<IQueryParameterType>>> params = theParams;
|
|
||||||
if (params == null) {
|
|
||||||
params = Collections.emptyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
|
||||||
CriteriaQuery<X> cq = builder.createQuery(myTableType);
|
|
||||||
Root<X> from = cq.from(myTableType);
|
|
||||||
|
|
||||||
RuntimeResourceDefinition resourceDef = myCtx.getResourceDefinition(myResourceType);
|
|
||||||
|
|
||||||
for (Entry<String, List<List<IQueryParameterType>>> nextParamEntry : params.entrySet()) {
|
|
||||||
String nextParamName = nextParamEntry.getKey();
|
|
||||||
RuntimeSearchParam nextParamDef = resourceDef.getSearchParam(nextParamName);
|
|
||||||
if (nextParamDef != null) {
|
|
||||||
if (nextParamDef.getParamType() == SearchParamTypeEnum.TOKEN) {
|
|
||||||
for (List<IQueryParameterType> nextAnd : nextParamEntry.getValue()) {
|
|
||||||
addTokenPredicate(cq, nextAnd, from, builder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute the query and make sure we return distinct results
|
|
||||||
|
|
||||||
Set<Long> pids = new HashSet<Long>();
|
|
||||||
|
|
||||||
TypedQuery<X> q = myEntityManager.createQuery(cq);
|
|
||||||
List<T> retVal = new ArrayList<>();
|
|
||||||
for (X next : q.getResultList()) {
|
|
||||||
T resource = toResource(next);
|
|
||||||
if (pids.contains(next.getIdAsLong())) {
|
|
||||||
continue;
|
|
||||||
}else {
|
|
||||||
pids.add(next.getIdAsLong());
|
|
||||||
}
|
|
||||||
|
|
||||||
retVal.add(resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Required
|
|
||||||
public void setTableType(Class<X> theTableType) {
|
|
||||||
myTableType = theTableType;
|
|
||||||
}
|
|
||||||
|
|
||||||
private X toEntity(T theResource) {
|
|
||||||
X retVal;
|
|
||||||
try {
|
|
||||||
retVal = myTableType.newInstance();
|
|
||||||
} catch (InstantiationException | IllegalAccessException e) {
|
|
||||||
throw new InternalErrorException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
populateResourceIntoEntity(theResource, retVal);
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
private MethodOutcome toMethodOutcome(final X entity) {
|
|
||||||
MethodOutcome outcome = new MethodOutcome();
|
|
||||||
outcome.setId(entity.getId());
|
|
||||||
outcome.setVersionId(entity.getVersion());
|
|
||||||
return outcome;
|
|
||||||
}
|
|
||||||
|
|
||||||
private T toResource(BaseHasResource theEntity) {
|
|
||||||
String resourceText = theEntity.getResource();
|
|
||||||
IParser parser = theEntity.getEncoding().newParser(myCtx);
|
|
||||||
T retVal = parser.parseResource(myResourceType, resourceText);
|
|
||||||
retVal.setId(theEntity.getId());
|
|
||||||
retVal.getResourceMetadata().put(ResourceMetadataKeyEnum.VERSION_ID, theEntity.getVersion());
|
|
||||||
retVal.getResourceMetadata().put(ResourceMetadataKeyEnum.PUBLISHED, theEntity.getPublished());
|
|
||||||
retVal.getResourceMetadata().put(ResourceMetadataKeyEnum.UPDATED, theEntity.getUpdated());
|
|
||||||
if (theEntity.getTags().size() > 0) {
|
|
||||||
TagList tagList = new TagList();
|
|
||||||
for (BaseTag next : theEntity.getTags()) {
|
|
||||||
tagList.add(new Tag(next.getTerm(), next.getLabel(), next.getScheme()));
|
|
||||||
}
|
|
||||||
retVal.getResourceMetadata().put(ResourceMetadataKeyEnum.TAG_LIST, tagList);
|
|
||||||
}
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.SUPPORTS)
|
|
||||||
@Override
|
|
||||||
public MethodOutcome update(final T theResource, final IdDt theId) {
|
|
||||||
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
|
|
||||||
X savedEntity = template.execute(new TransactionCallback<X>() {
|
|
||||||
@Override
|
|
||||||
public X doInTransaction(TransactionStatus theStatus) {
|
|
||||||
final X entity = readEntity(theId);
|
|
||||||
final ResourceHistoryTable existing = entity.toHistory(myCtx);
|
|
||||||
|
|
||||||
populateResourceIntoEntity(theResource, entity);
|
|
||||||
myEntityManager.persist(existing);
|
|
||||||
|
|
||||||
entity.setUpdated(new Date());
|
|
||||||
myEntityManager.persist(entity);
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return toMethodOutcome(savedEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -17,6 +17,7 @@ import javax.persistence.PersistenceContextType;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
import javax.persistence.criteria.CriteriaBuilder;
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
import javax.persistence.criteria.CriteriaQuery;
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
|
import javax.persistence.criteria.Expression;
|
||||||
import javax.persistence.criteria.Predicate;
|
import javax.persistence.criteria.Predicate;
|
||||||
import javax.persistence.criteria.Root;
|
import javax.persistence.criteria.Root;
|
||||||
|
|
||||||
|
@ -37,6 +38,8 @@ import ca.uhn.fhir.jpa.entity.BaseHasResource;
|
||||||
import ca.uhn.fhir.jpa.entity.BaseResourceTable;
|
import ca.uhn.fhir.jpa.entity.BaseResourceTable;
|
||||||
import ca.uhn.fhir.jpa.entity.BaseTag;
|
import ca.uhn.fhir.jpa.entity.BaseTag;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceHistoryTable;
|
import ca.uhn.fhir.jpa.entity.ResourceHistoryTable;
|
||||||
|
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamDate;
|
||||||
|
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamNumber;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
|
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamToken;
|
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamToken;
|
||||||
import ca.uhn.fhir.model.api.IDatatype;
|
import ca.uhn.fhir.model.api.IDatatype;
|
||||||
|
@ -50,12 +53,15 @@ import ca.uhn.fhir.model.dstu.composite.CodeableConceptDt;
|
||||||
import ca.uhn.fhir.model.dstu.composite.CodingDt;
|
import ca.uhn.fhir.model.dstu.composite.CodingDt;
|
||||||
import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
|
import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
|
||||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||||
|
import ca.uhn.fhir.model.dstu.composite.QuantityDt;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
|
import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
|
||||||
|
import ca.uhn.fhir.model.primitive.BaseDateTimeDt;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.model.primitive.StringDt;
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
import ca.uhn.fhir.parser.IParser;
|
import ca.uhn.fhir.parser.IParser;
|
||||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
import ca.uhn.fhir.rest.gclient.QuantityParam;
|
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||||
|
import ca.uhn.fhir.rest.param.QualifiedDateParam;
|
||||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||||
|
@ -72,8 +78,387 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
||||||
|
|
||||||
private Class<T> myResourceType;
|
private Class<T> myResourceType;
|
||||||
private Class<X> myTableType;
|
private Class<X> myTableType;
|
||||||
|
private String myResourceName;
|
||||||
|
|
||||||
private Set<Long> addTokenPredicate(Set<Long> thePids, List<IQueryParameterType> theOrParams) {
|
@Transactional(propagation = Propagation.SUPPORTS)
|
||||||
|
@Override
|
||||||
|
public MethodOutcome create(T theResource) {
|
||||||
|
|
||||||
|
final X entity = toEntity(theResource);
|
||||||
|
|
||||||
|
entity.setPublished(new Date());
|
||||||
|
entity.setUpdated(entity.getPublished());
|
||||||
|
|
||||||
|
final List<ResourceIndexedSearchParamString> stringParams = extractSearchParamStrings(entity, theResource);
|
||||||
|
final List<ResourceIndexedSearchParamToken> tokenParams = extractSearchParamTokens(entity, theResource);
|
||||||
|
final List<ResourceIndexedSearchParamNumber> numberParams = extractSearchParamNumber(entity, theResource);
|
||||||
|
final List<ResourceIndexedSearchParamDate> dateParams = extractSearchParamDates(entity, theResource);
|
||||||
|
|
||||||
|
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
|
||||||
|
template.execute(new TransactionCallback<X>() {
|
||||||
|
@Override
|
||||||
|
public X doInTransaction(TransactionStatus theStatus) {
|
||||||
|
myEntityManager.persist(entity);
|
||||||
|
for (ResourceIndexedSearchParamString next : stringParams) {
|
||||||
|
myEntityManager.persist(next);
|
||||||
|
}
|
||||||
|
for (ResourceIndexedSearchParamToken next : tokenParams) {
|
||||||
|
myEntityManager.persist(next);
|
||||||
|
}
|
||||||
|
for (ResourceIndexedSearchParamNumber next : numberParams) {
|
||||||
|
myEntityManager.persist(next);
|
||||||
|
}
|
||||||
|
for (ResourceIndexedSearchParamDate next : dateParams) {
|
||||||
|
myEntityManager.persist(next);
|
||||||
|
}
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MethodOutcome outcome = toMethodOutcome(entity);
|
||||||
|
return outcome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(propagation = Propagation.REQUIRED)
|
||||||
|
@Override
|
||||||
|
public List<T> history(IdDt theId) {
|
||||||
|
ArrayList<T> retVal = new ArrayList<T>();
|
||||||
|
|
||||||
|
String resourceType = myCtx.getResourceDefinition(myResourceType).getName();
|
||||||
|
TypedQuery<ResourceHistoryTable> q = myEntityManager.createQuery(ResourceHistoryTable.Q_GETALL, ResourceHistoryTable.class);
|
||||||
|
q.setParameter("PID", theId.asLong());
|
||||||
|
q.setParameter("RESTYPE", resourceType);
|
||||||
|
|
||||||
|
// TypedQuery<ResourceHistoryTable> query =
|
||||||
|
// myEntityManager.createQuery(criteriaQuery);
|
||||||
|
List<ResourceHistoryTable> results = q.getResultList();
|
||||||
|
for (ResourceHistoryTable next : results) {
|
||||||
|
retVal.add(toResource(next));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
retVal.add(read(theId));
|
||||||
|
} catch (ResourceNotFoundException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retVal.isEmpty()) {
|
||||||
|
throw new ResourceNotFoundException(theId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void postConstruct() throws Exception {
|
||||||
|
myResourceType = myTableType.newInstance().getResourceType();
|
||||||
|
myCtx = new FhirContext(myResourceType);
|
||||||
|
myResourceName = myCtx.getResourceDefinition(myResourceType).getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(propagation = Propagation.REQUIRED)
|
||||||
|
@Override
|
||||||
|
public T read(IdDt theId) {
|
||||||
|
X entity = readEntity(theId);
|
||||||
|
|
||||||
|
T retVal = toResource(entity);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<T> search(Map<String, IQueryParameterType> theParams) {
|
||||||
|
Map<String, List<List<IQueryParameterType>>> map = new HashMap<String, List<List<IQueryParameterType>>>();
|
||||||
|
for (Entry<String, IQueryParameterType> nextEntry : theParams.entrySet()) {
|
||||||
|
map.put(nextEntry.getKey(), new ArrayList<List<IQueryParameterType>>());
|
||||||
|
map.get(nextEntry.getKey()).add(Collections.singletonList(nextEntry.getValue()));
|
||||||
|
}
|
||||||
|
return searchWithAndOr(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<T> search(String theSpName, IQueryParameterType theValue) {
|
||||||
|
return search(Collections.singletonMap(theSpName, theValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<T> searchWithAndOr(Map<String, List<List<IQueryParameterType>>> theParams) {
|
||||||
|
Map<String, List<List<IQueryParameterType>>> params = theParams;
|
||||||
|
if (params == null) {
|
||||||
|
params = Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
RuntimeResourceDefinition resourceDef = myCtx.getResourceDefinition(myResourceType);
|
||||||
|
|
||||||
|
Set<Long> pids = new HashSet<Long>();
|
||||||
|
|
||||||
|
for (Entry<String, List<List<IQueryParameterType>>> nextParamEntry : params.entrySet()) {
|
||||||
|
String nextParamName = nextParamEntry.getKey();
|
||||||
|
RuntimeSearchParam nextParamDef = resourceDef.getSearchParam(nextParamName);
|
||||||
|
if (nextParamDef != null) {
|
||||||
|
if (nextParamDef.getParamType() == SearchParamTypeEnum.TOKEN) {
|
||||||
|
for (List<IQueryParameterType> nextAnd : nextParamEntry.getValue()) {
|
||||||
|
pids = addPredicateToken(pids, nextAnd);
|
||||||
|
if (pids.isEmpty()) {
|
||||||
|
return new ArrayList<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (nextParamDef.getParamType() == SearchParamTypeEnum.STRING) {
|
||||||
|
for (List<IQueryParameterType> nextAnd : nextParamEntry.getValue()) {
|
||||||
|
pids = addPredicateString(pids, nextAnd);
|
||||||
|
if (pids.isEmpty()) {
|
||||||
|
return new ArrayList<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (nextParamDef.getParamType() == SearchParamTypeEnum.QUANTITY) {
|
||||||
|
for (List<IQueryParameterType> nextAnd : nextParamEntry.getValue()) {
|
||||||
|
pids = addPredicateQuantity(pids, nextAnd);
|
||||||
|
if (pids.isEmpty()) {
|
||||||
|
return new ArrayList<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (nextParamDef.getParamType() == SearchParamTypeEnum.DATE) {
|
||||||
|
for (List<IQueryParameterType> nextAnd : nextParamEntry.getValue()) {
|
||||||
|
pids = addPredicateDate(pids, nextAnd);
|
||||||
|
if (pids.isEmpty()) {
|
||||||
|
return new ArrayList<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Don't know how to handle parameter of type: " + nextParamDef.getParamType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the query and make sure we return distinct results
|
||||||
|
{
|
||||||
|
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<X> cq = builder.createQuery(myTableType);
|
||||||
|
Root<X> from = cq.from(myTableType);
|
||||||
|
if (!params.isEmpty()) {
|
||||||
|
cq.where(from.get("myId").in(pids));
|
||||||
|
}
|
||||||
|
TypedQuery<X> q = myEntityManager.createQuery(cq);
|
||||||
|
|
||||||
|
List<T> retVal = new ArrayList<>();
|
||||||
|
for (X next : q.getResultList()) {
|
||||||
|
T resource = toResource(next);
|
||||||
|
retVal.add(resource);
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Required
|
||||||
|
public void setTableType(Class<X> theTableType) {
|
||||||
|
myTableType = theTableType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(propagation = Propagation.SUPPORTS)
|
||||||
|
@Override
|
||||||
|
public MethodOutcome update(final T theResource, final IdDt theId) {
|
||||||
|
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
|
||||||
|
X savedEntity = template.execute(new TransactionCallback<X>() {
|
||||||
|
@Override
|
||||||
|
public X doInTransaction(TransactionStatus theStatus) {
|
||||||
|
final X entity = readEntity(theId);
|
||||||
|
final ResourceHistoryTable existing = entity.toHistory(myCtx);
|
||||||
|
|
||||||
|
populateResourceIntoEntity(theResource, entity);
|
||||||
|
myEntityManager.persist(existing);
|
||||||
|
|
||||||
|
entity.setUpdated(new Date());
|
||||||
|
myEntityManager.persist(entity);
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return toMethodOutcome(savedEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<Long> addPredicateQuantity(Set<Long> thePids, List<IQueryParameterType> theOrParams) {
|
||||||
|
if (theOrParams == null || theOrParams.isEmpty()) {
|
||||||
|
return thePids;
|
||||||
|
}
|
||||||
|
|
||||||
|
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<Long> cq = builder.createQuery(Long.class);
|
||||||
|
Root<ResourceIndexedSearchParamNumber> from = cq.from(ResourceIndexedSearchParamNumber.class);
|
||||||
|
cq.select(from.get("myResourcePid").as(Long.class));
|
||||||
|
|
||||||
|
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
||||||
|
for (IQueryParameterType nextOr : theOrParams) {
|
||||||
|
IQueryParameterType params = nextOr;
|
||||||
|
|
||||||
|
if (params instanceof QuantityDt) {
|
||||||
|
QuantityDt id = (QuantityDt) params;
|
||||||
|
|
||||||
|
Predicate system;
|
||||||
|
if (id.getSystem().isEmpty()) {
|
||||||
|
system = builder.isNull(from.get("mySystem"));
|
||||||
|
} else {
|
||||||
|
system = builder.equal(from.get("mySystem"), id.getSystem().getValueAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
Predicate code;
|
||||||
|
if (id.getCode().isEmpty()) {
|
||||||
|
code = builder.isNull(from.get("myUnits"));
|
||||||
|
} else {
|
||||||
|
code = builder.equal(from.get("myUnits"), id.getUnits().getValueAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
Predicate num;
|
||||||
|
if (id.getComparator().getValueAsEnum() == null) {
|
||||||
|
num = builder.equal(from.get("myValue"), id.getValue().getValue());
|
||||||
|
} else {
|
||||||
|
switch (id.getComparator().getValueAsEnum()) {
|
||||||
|
case GREATERTHAN:
|
||||||
|
Expression<Number> path = from.get("myValue");
|
||||||
|
Number value = id.getValue().getValue();
|
||||||
|
num = builder.gt(path, value);
|
||||||
|
break;
|
||||||
|
case GREATERTHAN_OR_EQUALS:
|
||||||
|
path = from.get("myValue");
|
||||||
|
value = id.getValue().getValue();
|
||||||
|
num = builder.ge(path, value);
|
||||||
|
break;
|
||||||
|
case LESSTHAN:
|
||||||
|
path = from.get("myValue");
|
||||||
|
value = id.getValue().getValue();
|
||||||
|
num = builder.lt(path, value);
|
||||||
|
break;
|
||||||
|
case LESSTHAN_OR_EQUALS:
|
||||||
|
path = from.get("myValue");
|
||||||
|
value = id.getValue().getValue();
|
||||||
|
num = builder.le(path, value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException(id.getComparator().getValueAsString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Predicate singleCode = builder.and(system, code, num);
|
||||||
|
codePredicates.add(singleCode);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Invalid token type: " + params.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Predicate masterCodePredicate = builder.or(codePredicates.toArray(new Predicate[0]));
|
||||||
|
|
||||||
|
Predicate type = builder.equal(from.get("myResourceType"), myResourceName);
|
||||||
|
if (thePids.size() > 0) {
|
||||||
|
Predicate inPids = (from.get("myResourcePid").in(thePids));
|
||||||
|
cq.where(builder.and(type, inPids, masterCodePredicate));
|
||||||
|
} else {
|
||||||
|
cq.where(builder.and(type, masterCodePredicate));
|
||||||
|
}
|
||||||
|
|
||||||
|
TypedQuery<Long> q = myEntityManager.createQuery(cq);
|
||||||
|
return new HashSet<Long>(q.getResultList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<Long> addPredicateDate(Set<Long> thePids, List<IQueryParameterType> theOrParams) {
|
||||||
|
if (theOrParams == null || theOrParams.isEmpty()) {
|
||||||
|
return thePids;
|
||||||
|
}
|
||||||
|
|
||||||
|
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<Long> cq = builder.createQuery(Long.class);
|
||||||
|
Root<ResourceIndexedSearchParamDate> from = cq.from(ResourceIndexedSearchParamDate.class);
|
||||||
|
cq.select(from.get("myResourcePid").as(Long.class));
|
||||||
|
|
||||||
|
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
||||||
|
for (IQueryParameterType nextOr : theOrParams) {
|
||||||
|
IQueryParameterType params = nextOr;
|
||||||
|
|
||||||
|
if (params instanceof QualifiedDateParam) {
|
||||||
|
QualifiedDateParam id = (QualifiedDateParam) params;
|
||||||
|
DateRangeParam range = new DateRangeParam(id);
|
||||||
|
addPredicateDateFromRange(builder, from, codePredicates, range);
|
||||||
|
} else if (params instanceof DateRangeParam) {
|
||||||
|
DateRangeParam range = (DateRangeParam) params;
|
||||||
|
addPredicateDateFromRange(builder, from, codePredicates, range);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Invalid token type: " + params.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Predicate masterCodePredicate = builder.or(codePredicates.toArray(new Predicate[0]));
|
||||||
|
|
||||||
|
Predicate type = builder.equal(from.get("myResourceType"), myResourceName);
|
||||||
|
if (thePids.size() > 0) {
|
||||||
|
Predicate inPids = (from.get("myResourcePid").in(thePids));
|
||||||
|
cq.where(builder.and(type, inPids, masterCodePredicate));
|
||||||
|
} else {
|
||||||
|
cq.where(builder.and(type, masterCodePredicate));
|
||||||
|
}
|
||||||
|
|
||||||
|
TypedQuery<Long> q = myEntityManager.createQuery(cq);
|
||||||
|
return new HashSet<Long>(q.getResultList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPredicateDateFromRange(CriteriaBuilder builder, Root<ResourceIndexedSearchParamDate> from, List<Predicate> codePredicates, DateRangeParam range) {
|
||||||
|
Predicate singleCode;
|
||||||
|
Date lowerBound = range.getLowerBoundAsInstant();
|
||||||
|
Date upperBound = range.getUpperBoundAsInstant();
|
||||||
|
|
||||||
|
if (lowerBound != null && upperBound != null) {
|
||||||
|
Predicate low = builder.greaterThanOrEqualTo(from.<Date> get("myValueLow"), lowerBound);
|
||||||
|
Predicate high = builder.lessThanOrEqualTo(from.<Date> get("myValueHigh"), upperBound);
|
||||||
|
singleCode = builder.and(low, high);
|
||||||
|
} else if (lowerBound != null) {
|
||||||
|
singleCode = builder.greaterThanOrEqualTo(from.<Date> get("myValueLow"), lowerBound);
|
||||||
|
} else {
|
||||||
|
singleCode = builder.lessThanOrEqualTo(from.<Date> get("myValueHigh"), upperBound);
|
||||||
|
}
|
||||||
|
|
||||||
|
codePredicates.add(singleCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<Long> addPredicateString(Set<Long> thePids, List<IQueryParameterType> theOrParams) {
|
||||||
|
if (theOrParams == null || theOrParams.isEmpty()) {
|
||||||
|
return thePids;
|
||||||
|
}
|
||||||
|
|
||||||
|
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<Long> cq = builder.createQuery(Long.class);
|
||||||
|
Root<ResourceIndexedSearchParamString> from = cq.from(ResourceIndexedSearchParamString.class);
|
||||||
|
cq.select(from.get("myResourcePid").as(Long.class));
|
||||||
|
|
||||||
|
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
||||||
|
for (IQueryParameterType nextOr : theOrParams) {
|
||||||
|
IQueryParameterType params = nextOr;
|
||||||
|
|
||||||
|
String string;
|
||||||
|
if (params instanceof IPrimitiveDatatype<?>) {
|
||||||
|
IPrimitiveDatatype<?> id = (IPrimitiveDatatype<?>) params;
|
||||||
|
string = id.getValueAsString();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Invalid token type: " + params.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
Predicate singleCode = builder.equal(from.get("myValue"), string);
|
||||||
|
codePredicates.add(singleCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
Predicate masterCodePredicate = builder.or(codePredicates.toArray(new Predicate[0]));
|
||||||
|
|
||||||
|
Predicate type = builder.equal(from.get("myResourceType"), myResourceName);
|
||||||
|
if (thePids.size() > 0) {
|
||||||
|
Predicate inPids = (from.get("myResourcePid").in(thePids));
|
||||||
|
cq.where(builder.and(type, inPids, masterCodePredicate));
|
||||||
|
} else {
|
||||||
|
cq.where(builder.and(type, masterCodePredicate));
|
||||||
|
}
|
||||||
|
|
||||||
|
TypedQuery<Long> q = myEntityManager.createQuery(cq);
|
||||||
|
return new HashSet<Long>(q.getResultList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<Long> addPredicateToken(Set<Long> thePids, List<IQueryParameterType> theOrParams) {
|
||||||
if (theOrParams == null || theOrParams.isEmpty()) {
|
if (theOrParams == null || theOrParams.isEmpty()) {
|
||||||
return thePids;
|
return thePids;
|
||||||
}
|
}
|
||||||
|
@ -114,126 +499,18 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
||||||
|
|
||||||
Predicate masterCodePredicate = builder.or(codePredicates.toArray(new Predicate[0]));
|
Predicate masterCodePredicate = builder.or(codePredicates.toArray(new Predicate[0]));
|
||||||
|
|
||||||
|
Predicate type = builder.equal(from.get("myResourceType"), myResourceName);
|
||||||
if (thePids.size() > 0) {
|
if (thePids.size() > 0) {
|
||||||
Predicate inPids = (from.get("myResourcePid").in(thePids));
|
Predicate inPids = (from.get("myResourcePid").in(thePids));
|
||||||
cq.where(builder.and(inPids, masterCodePredicate));
|
cq.where(builder.and(type, inPids, masterCodePredicate));
|
||||||
} else {
|
} else {
|
||||||
cq.where(masterCodePredicate);
|
cq.where(builder.and(type, masterCodePredicate));
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedQuery<Long> q = myEntityManager.createQuery(cq);
|
TypedQuery<Long> q = myEntityManager.createQuery(cq);
|
||||||
return new HashSet<Long>(q.getResultList());
|
return new HashSet<Long>(q.getResultList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<Long> addStringPredicate(Set<Long> thePids, List<IQueryParameterType> theOrParams) {
|
|
||||||
if (theOrParams == null || theOrParams.isEmpty()) {
|
|
||||||
return thePids;
|
|
||||||
}
|
|
||||||
|
|
||||||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
|
||||||
CriteriaQuery<Long> cq = builder.createQuery(Long.class);
|
|
||||||
Root<ResourceIndexedSearchParamString> from = cq.from(ResourceIndexedSearchParamString.class);
|
|
||||||
cq.select(from.get("myResourcePid").as(Long.class));
|
|
||||||
|
|
||||||
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
|
||||||
for (IQueryParameterType nextOr : theOrParams) {
|
|
||||||
IQueryParameterType params = nextOr;
|
|
||||||
|
|
||||||
String string;
|
|
||||||
if (params instanceof IPrimitiveDatatype<?>) {
|
|
||||||
IPrimitiveDatatype<?> id = (IPrimitiveDatatype<?>) params;
|
|
||||||
string = id.getValueAsString();
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Invalid token type: " + params.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
Predicate singleCode = builder.equal(from.get("myValue"), string);
|
|
||||||
codePredicates.add(singleCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
Predicate masterCodePredicate = builder.or(codePredicates.toArray(new Predicate[0]));
|
|
||||||
|
|
||||||
if (thePids.size() > 0) {
|
|
||||||
Predicate inPids = (from.get("myResourcePid").in(thePids));
|
|
||||||
cq.where(builder.and(inPids, masterCodePredicate));
|
|
||||||
} else {
|
|
||||||
cq.where(masterCodePredicate);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypedQuery<Long> q = myEntityManager.createQuery(cq);
|
|
||||||
return new HashSet<Long>(q.getResultList());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Set<Long> addQuantityPredicate(Set<Long> thePids, List<IQueryParameterType> theOrParams) {
|
|
||||||
if (theOrParams == null || theOrParams.isEmpty()) {
|
|
||||||
return thePids;
|
|
||||||
}
|
|
||||||
|
|
||||||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
|
||||||
CriteriaQuery<Long> cq = builder.createQuery(Long.class);
|
|
||||||
Root<ResourceIndexedSearchParamString> from = cq.from(ResourceIndexedSearchParamString.class);
|
|
||||||
cq.select(from.get("myResourcePid").as(Long.class));
|
|
||||||
|
|
||||||
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
|
||||||
for (IQueryParameterType nextOr : theOrParams) {
|
|
||||||
IQueryParameterType params = nextOr;
|
|
||||||
|
|
||||||
String string;
|
|
||||||
if (params instanceof QuantityParam<?>) {
|
|
||||||
IPrimitiveDatatype<?> id = (IPrimitiveDatatype<?>) params;
|
|
||||||
string = id.getValueAsString();
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Invalid token type: " + params.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
Predicate singleCode = builder.equal(from.get("myValue"), string);
|
|
||||||
codePredicates.add(singleCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
Predicate masterCodePredicate = builder.or(codePredicates.toArray(new Predicate[0]));
|
|
||||||
|
|
||||||
if (thePids.size() > 0) {
|
|
||||||
Predicate inPids = (from.get("myResourcePid").in(thePids));
|
|
||||||
cq.where(builder.and(inPids, masterCodePredicate));
|
|
||||||
} else {
|
|
||||||
cq.where(masterCodePredicate);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypedQuery<Long> q = myEntityManager.createQuery(cq);
|
|
||||||
return new HashSet<Long>(q.getResultList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.SUPPORTS)
|
|
||||||
@Override
|
|
||||||
public MethodOutcome create(T theResource) {
|
|
||||||
|
|
||||||
final X entity = toEntity(theResource);
|
|
||||||
|
|
||||||
entity.setPublished(new Date());
|
|
||||||
entity.setUpdated(entity.getPublished());
|
|
||||||
|
|
||||||
final List<ResourceIndexedSearchParamString> stringParams = extractSearchParamStrings(entity, theResource);
|
|
||||||
final List<ResourceIndexedSearchParamToken> tokenParams = extractSearchParamTokens(entity, theResource);
|
|
||||||
|
|
||||||
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
|
|
||||||
template.execute(new TransactionCallback<X>() {
|
|
||||||
@Override
|
|
||||||
public X doInTransaction(TransactionStatus theStatus) {
|
|
||||||
myEntityManager.persist(entity);
|
|
||||||
for (ResourceIndexedSearchParamString next : stringParams) {
|
|
||||||
myEntityManager.persist(next);
|
|
||||||
}
|
|
||||||
for (ResourceIndexedSearchParamToken next : tokenParams) {
|
|
||||||
myEntityManager.persist(next);
|
|
||||||
}
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
MethodOutcome outcome = toMethodOutcome(entity);
|
|
||||||
return outcome;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<ResourceIndexedSearchParamString> extractSearchParamStrings(X theEntity, T theResource) {
|
private List<ResourceIndexedSearchParamString> extractSearchParamStrings(X theEntity, T theResource) {
|
||||||
ArrayList<ResourceIndexedSearchParamString> retVal = new ArrayList<ResourceIndexedSearchParamString>();
|
ArrayList<ResourceIndexedSearchParamString> retVal = new ArrayList<ResourceIndexedSearchParamString>();
|
||||||
|
|
||||||
|
@ -244,7 +521,8 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (nextSpDef.getPath().isEmpty()) {
|
if (nextSpDef.getPath().isEmpty()) {
|
||||||
continue; // TODO: implement phoenetic, and any others that have no path
|
continue; // TODO: implement phoenetic, and any others that have
|
||||||
|
// no path
|
||||||
}
|
}
|
||||||
|
|
||||||
String nextPath = nextSpDef.getPath();
|
String nextPath = nextSpDef.getPath();
|
||||||
|
@ -253,22 +531,72 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
||||||
if (((IDatatype) nextObject).isEmpty()) {
|
if (((IDatatype) nextObject).isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String resourceName = nextSpDef.getName();
|
||||||
|
boolean multiType = false;
|
||||||
|
if (nextPath.endsWith("[x]")) {
|
||||||
|
multiType = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (nextObject instanceof IPrimitiveDatatype<?>) {
|
if (nextObject instanceof IPrimitiveDatatype<?>) {
|
||||||
IPrimitiveDatatype<?> nextValue = (IPrimitiveDatatype<?>) nextObject;
|
IPrimitiveDatatype<?> nextValue = (IPrimitiveDatatype<?>) nextObject;
|
||||||
ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(nextSpDef.getName(), nextValue.getValueAsString());
|
ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(resourceName, nextValue.getValueAsString());
|
||||||
nextEntity.setResource(theEntity);
|
nextEntity.setResource(theEntity, def.getName());
|
||||||
retVal.add(nextEntity);
|
retVal.add(nextEntity);
|
||||||
} else if (nextObject instanceof HumanNameDt) {
|
} else if (nextObject instanceof HumanNameDt) {
|
||||||
for (StringDt nextName : ((HumanNameDt) nextObject).getFamily()) {
|
for (StringDt nextName : ((HumanNameDt) nextObject).getFamily()) {
|
||||||
if (nextName.isEmpty()) {
|
if (nextName.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(nextSpDef.getName(), nextName.getValueAsString());
|
ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(resourceName, nextName.getValueAsString());
|
||||||
nextEntity.setResource(theEntity);
|
nextEntity.setResource(theEntity, def.getName());
|
||||||
retVal.add(nextEntity);
|
retVal.add(nextEntity);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass());
|
if (!multiType) {
|
||||||
|
throw new ConfigurationException("Search param " + resourceName + " is of unexpected datatype: " + nextObject.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<ResourceIndexedSearchParamNumber> extractSearchParamNumber(X theEntity, T theResource) {
|
||||||
|
ArrayList<ResourceIndexedSearchParamNumber> retVal = new ArrayList<ResourceIndexedSearchParamNumber>();
|
||||||
|
|
||||||
|
RuntimeResourceDefinition def = myCtx.getResourceDefinition(theResource);
|
||||||
|
FhirTerser t = myCtx.newTerser();
|
||||||
|
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
|
||||||
|
if (nextSpDef.getParamType() != SearchParamTypeEnum.NUMBER && nextSpDef.getParamType() != SearchParamTypeEnum.QUANTITY) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String nextPath = nextSpDef.getPath();
|
||||||
|
List<Object> values = t.getValues(theResource, nextPath);
|
||||||
|
for (Object nextObject : values) {
|
||||||
|
if (((IDatatype) nextObject).isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String resourceName = nextSpDef.getName();
|
||||||
|
boolean multiType = false;
|
||||||
|
if (nextPath.endsWith("[x]")) {
|
||||||
|
multiType = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextObject instanceof QuantityDt) {
|
||||||
|
QuantityDt nextValue = (QuantityDt) nextObject;
|
||||||
|
ResourceIndexedSearchParamNumber nextEntity = new ResourceIndexedSearchParamNumber(resourceName, nextValue.getValue().getValue(), nextValue.getSystem().getValueAsString(), nextValue.getUnits().getValue());
|
||||||
|
nextEntity.setResource(theEntity, def.getName());
|
||||||
|
retVal.add(nextEntity);
|
||||||
|
} else {
|
||||||
|
if (!multiType) {
|
||||||
|
throw new ConfigurationException("Search param " + resourceName + " is of unexpected datatype: " + nextObject.getClass());
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -287,6 +615,12 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
String nextPath = nextSpDef.getPath();
|
String nextPath = nextSpDef.getPath();
|
||||||
|
|
||||||
|
boolean multiType = false;
|
||||||
|
if (nextPath.endsWith("[x]")) {
|
||||||
|
multiType = true;
|
||||||
|
}
|
||||||
|
|
||||||
List<Object> values = t.getValues(theResource, nextPath);
|
List<Object> values = t.getValues(theResource, nextPath);
|
||||||
for (Object nextObject : values) {
|
for (Object nextObject : values) {
|
||||||
ResourceIndexedSearchParamToken nextEntity;
|
ResourceIndexedSearchParamToken nextEntity;
|
||||||
|
@ -309,15 +643,19 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
nextEntity = new ResourceIndexedSearchParamToken(nextSpDef.getName(), nextCoding.getSystem().getValueAsString(), nextCoding.getCode().getValue());
|
nextEntity = new ResourceIndexedSearchParamToken(nextSpDef.getName(), nextCoding.getSystem().getValueAsString(), nextCoding.getCode().getValue());
|
||||||
nextEntity.setResource(theEntity);
|
nextEntity.setResource(theEntity, def.getName());
|
||||||
retVal.add(nextEntity);
|
retVal.add(nextEntity);
|
||||||
}
|
}
|
||||||
nextEntity = null;
|
nextEntity = null;
|
||||||
} else {
|
} else {
|
||||||
throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass());
|
if (!multiType) {
|
||||||
|
throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass());
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (nextEntity != null) {
|
if (nextEntity != null) {
|
||||||
nextEntity.setResource(theEntity);
|
nextEntity.setResource(theEntity, def.getName());
|
||||||
retVal.add(nextEntity);
|
retVal.add(nextEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -326,31 +664,44 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.REQUIRED)
|
private List<ResourceIndexedSearchParamDate> extractSearchParamDates(X theEntity, T theResource) {
|
||||||
@Override
|
ArrayList<ResourceIndexedSearchParamDate> retVal = new ArrayList<ResourceIndexedSearchParamDate>();
|
||||||
public List<T> history(IdDt theId) {
|
|
||||||
ArrayList<T> retVal = new ArrayList<T>();
|
|
||||||
|
|
||||||
String resourceType = myCtx.getResourceDefinition(myResourceType).getName();
|
RuntimeResourceDefinition def = myCtx.getResourceDefinition(theResource);
|
||||||
TypedQuery<ResourceHistoryTable> q = myEntityManager.createQuery(ResourceHistoryTable.Q_GETALL, ResourceHistoryTable.class);
|
FhirTerser t = myCtx.newTerser();
|
||||||
q.setParameter("PID", theId.asLong());
|
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
|
||||||
q.setParameter("RESTYPE", resourceType);
|
if (nextSpDef.getParamType() != SearchParamTypeEnum.DATE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// TypedQuery<ResourceHistoryTable> query =
|
String nextPath = nextSpDef.getPath();
|
||||||
// myEntityManager.createQuery(criteriaQuery);
|
|
||||||
List<ResourceHistoryTable> results = q.getResultList();
|
|
||||||
for (ResourceHistoryTable next : results) {
|
|
||||||
retVal.add(toResource(next));
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
boolean multiType = false;
|
||||||
retVal.add(read(theId));
|
if (nextPath.endsWith("[x]")) {
|
||||||
} catch (ResourceNotFoundException e) {
|
multiType = true;
|
||||||
// ignore
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (retVal.isEmpty()) {
|
List<Object> values = t.getValues(theResource, nextPath);
|
||||||
throw new ResourceNotFoundException(theId);
|
for (Object nextObject : values) {
|
||||||
|
ResourceIndexedSearchParamDate nextEntity;
|
||||||
|
if (nextObject instanceof BaseDateTimeDt) {
|
||||||
|
BaseDateTimeDt nextValue = (BaseDateTimeDt) nextObject;
|
||||||
|
if (nextValue.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
nextEntity = new ResourceIndexedSearchParamDate(nextSpDef.getName(), nextValue.getValue(), nextValue.getValue());
|
||||||
|
} else {
|
||||||
|
if (!multiType) {
|
||||||
|
throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass());
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nextEntity != null) {
|
||||||
|
nextEntity.setResource(theEntity, def.getName());
|
||||||
|
retVal.add(nextEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
|
@ -369,21 +720,6 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void postConstruct() throws Exception {
|
|
||||||
myResourceType = myTableType.newInstance().getResourceType();
|
|
||||||
myCtx = new FhirContext(myResourceType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.REQUIRED)
|
|
||||||
@Override
|
|
||||||
public T read(IdDt theId) {
|
|
||||||
X entity = readEntity(theId);
|
|
||||||
|
|
||||||
T retVal = toResource(entity);
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
private X readEntity(IdDt theId) {
|
private X readEntity(IdDt theId) {
|
||||||
X entity = (X) myEntityManager.find(myTableType, theId.asLong());
|
X entity = (X) myEntityManager.find(myTableType, theId.asLong());
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
|
@ -392,81 +728,6 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<T> search(Map<String, IQueryParameterType> theParams) {
|
|
||||||
Map<String, List<List<IQueryParameterType>>> map = new HashMap<String, List<List<IQueryParameterType>>>();
|
|
||||||
for (Entry<String, IQueryParameterType> nextEntry : theParams.entrySet()) {
|
|
||||||
map.put(nextEntry.getKey(), new ArrayList<List<IQueryParameterType>>());
|
|
||||||
map.get(nextEntry.getKey()).add(Collections.singletonList(nextEntry.getValue()));
|
|
||||||
}
|
|
||||||
return searchWithAndOr(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<T> search(String theSpName, IQueryParameterType theValue) {
|
|
||||||
return search(Collections.singletonMap(theSpName, theValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<T> searchWithAndOr(Map<String, List<List<IQueryParameterType>>> theParams) {
|
|
||||||
Map<String, List<List<IQueryParameterType>>> params = theParams;
|
|
||||||
if (params == null) {
|
|
||||||
params = Collections.emptyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
RuntimeResourceDefinition resourceDef = myCtx.getResourceDefinition(myResourceType);
|
|
||||||
|
|
||||||
Set<Long> pids = new HashSet<Long>();
|
|
||||||
|
|
||||||
for (Entry<String, List<List<IQueryParameterType>>> nextParamEntry : params.entrySet()) {
|
|
||||||
String nextParamName = nextParamEntry.getKey();
|
|
||||||
RuntimeSearchParam nextParamDef = resourceDef.getSearchParam(nextParamName);
|
|
||||||
if (nextParamDef != null) {
|
|
||||||
if (nextParamDef.getParamType() == SearchParamTypeEnum.TOKEN) {
|
|
||||||
for (List<IQueryParameterType> nextAnd : nextParamEntry.getValue()) {
|
|
||||||
pids = addTokenPredicate(pids, nextAnd);
|
|
||||||
if (pids.isEmpty()) {
|
|
||||||
return new ArrayList<T>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (nextParamDef.getParamType() == SearchParamTypeEnum.STRING) {
|
|
||||||
for (List<IQueryParameterType> nextAnd : nextParamEntry.getValue()) {
|
|
||||||
pids = addStringPredicate(pids, nextAnd);
|
|
||||||
if (pids.isEmpty()) {
|
|
||||||
return new ArrayList<T>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (nextParamDef.getParamType() == SearchParamTypeEnum.QUANTITY) {
|
|
||||||
for (List<IQueryParameterType> nextAnd : nextParamEntry.getValue()) {
|
|
||||||
pids = addStringPredicate(pids, nextAnd);
|
|
||||||
if (pids.isEmpty()) {
|
|
||||||
return new ArrayList<T>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute the query and make sure we return distinct results
|
|
||||||
{
|
|
||||||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
|
||||||
CriteriaQuery<X> cq = builder.createQuery(myTableType);
|
|
||||||
cq.from(myTableType);
|
|
||||||
TypedQuery<X> q = myEntityManager.createQuery(cq);
|
|
||||||
List<T> retVal = new ArrayList<>();
|
|
||||||
for (X next : q.getResultList()) {
|
|
||||||
T resource = toResource(next);
|
|
||||||
retVal.add(resource);
|
|
||||||
}
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Required
|
|
||||||
public void setTableType(Class<X> theTableType) {
|
|
||||||
myTableType = theTableType;
|
|
||||||
}
|
|
||||||
|
|
||||||
private X toEntity(T theResource) {
|
private X toEntity(T theResource) {
|
||||||
X retVal;
|
X retVal;
|
||||||
try {
|
try {
|
||||||
|
@ -505,26 +766,4 @@ public class FhirResourceDao<T extends IResource, X extends BaseResourceTable<T>
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.SUPPORTS)
|
|
||||||
@Override
|
|
||||||
public MethodOutcome update(final T theResource, final IdDt theId) {
|
|
||||||
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
|
|
||||||
X savedEntity = template.execute(new TransactionCallback<X>() {
|
|
||||||
@Override
|
|
||||||
public X doInTransaction(TransactionStatus theStatus) {
|
|
||||||
final X entity = readEntity(theId);
|
|
||||||
final ResourceHistoryTable existing = entity.toHistory(myCtx);
|
|
||||||
|
|
||||||
populateResourceIntoEntity(theResource, entity);
|
|
||||||
myEntityManager.persist(existing);
|
|
||||||
|
|
||||||
entity.setUpdated(new Date());
|
|
||||||
myEntityManager.persist(entity);
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return toMethodOutcome(savedEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import javax.persistence.Id;
|
||||||
import javax.persistence.MappedSuperclass;
|
import javax.persistence.MappedSuperclass;
|
||||||
|
|
||||||
@MappedSuperclass
|
@MappedSuperclass
|
||||||
public abstract class BaseResourceIndexedSearchParam<T> implements Serializable {
|
public abstract class BaseResourceIndexedSearchParam implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@ -21,6 +21,9 @@ public abstract class BaseResourceIndexedSearchParam<T> implements Serializable
|
||||||
@Column(name="SP_NAME", length=100)
|
@Column(name="SP_NAME", length=100)
|
||||||
private String myName;
|
private String myName;
|
||||||
|
|
||||||
|
@Column(name = "RES_TYPE",length=100,nullable=false)
|
||||||
|
private String myResourceType;
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return myName;
|
return myName;
|
||||||
}
|
}
|
||||||
|
@ -31,11 +34,21 @@ public abstract class BaseResourceIndexedSearchParam<T> implements Serializable
|
||||||
|
|
||||||
public abstract BaseResourceTable<?> getResource();
|
public abstract BaseResourceTable<?> getResource();
|
||||||
|
|
||||||
public abstract void setResource(BaseResourceTable<?> theResource);
|
protected abstract void setResource(BaseResourceTable<?> theResource);
|
||||||
|
|
||||||
public abstract T getValue();
|
public void setResource(BaseResourceTable<?> theResource, String theResourceType) {
|
||||||
|
setResource(theResource);
|
||||||
|
setResourceType(theResourceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResourceType() {
|
||||||
|
return myResourceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResourceType(String theResourceType) {
|
||||||
|
myResourceType = theResourceType;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract void setValue(T theValue);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package ca.uhn.fhir.jpa.entity;
|
||||||
|
|
||||||
|
import javax.persistence.DiscriminatorValue;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@DiscriminatorValue("OBSERVATION")
|
||||||
|
public class ObservationResourceTable extends BaseResourceTable<Observation> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<Observation> getResourceType() {
|
||||||
|
return Observation.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -12,32 +12,53 @@ import javax.persistence.TemporalType;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "IDX_SP_DATE")
|
@Table(name = "IDX_SP_DATE")
|
||||||
public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchParam<Date> {
|
public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchParam {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Column(name = "SP_VALUE_HIGH", nullable = true)
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
public Date myValueHigh;
|
||||||
|
|
||||||
|
@Column(name = "SP_VALUE_LOW", nullable = true)
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
public Date myValueLow;
|
||||||
|
|
||||||
@ManyToOne(optional = false)
|
@ManyToOne(optional = false)
|
||||||
@JoinColumn(name = "RESOURCE_PID", nullable = false)
|
@JoinColumn(name = "RESOURCE_PID", nullable = false)
|
||||||
private BaseResourceTable<?> myResource;
|
private BaseResourceTable<?> myResource;
|
||||||
|
|
||||||
@Column(name = "SP_VALUE", nullable = true)
|
@Column(name = "RESOURCE_PID", insertable = false, updatable = false)
|
||||||
@Temporal(TemporalType.TIMESTAMP)
|
private Long myResourcePid;
|
||||||
public Date myValue;
|
|
||||||
|
public ResourceIndexedSearchParamDate(String theName, Date theLow, Date theHigh) {
|
||||||
|
setName(theName);
|
||||||
|
setValueLow(theLow);
|
||||||
|
setValueHigh(theHigh);
|
||||||
|
}
|
||||||
|
|
||||||
public BaseResourceTable<?> getResource() {
|
public BaseResourceTable<?> getResource() {
|
||||||
return myResource;
|
return myResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getValue() {
|
public Date getValueHigh() {
|
||||||
return myValue;
|
return myValueHigh;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setResource(BaseResourceTable<?> theResource) {
|
public Date getValueLow() {
|
||||||
|
return myValueLow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValueHigh(Date theValueHigh) {
|
||||||
|
myValueHigh = theValueHigh;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValueLow(Date theValueLow) {
|
||||||
|
myValueLow = theValueLow;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setResource(BaseResourceTable<?> theResource) {
|
||||||
myResource = theResource;
|
myResource = theResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setValue(Date theValue) {
|
|
||||||
myValue = theValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
package ca.uhn.fhir.jpa.entity;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "IDX_SP_NUMBER")
|
||||||
|
public class ResourceIndexedSearchParamNumber extends BaseResourceIndexedSearchParam {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Column(name = "SP_SYSTEM", nullable = true, length = 100)
|
||||||
|
public String mySystem;
|
||||||
|
|
||||||
|
@Column(name = "SP_UNITS", nullable = true, length = 100)
|
||||||
|
public String myUnits;
|
||||||
|
|
||||||
|
@Column(name = "SP_VALUE", nullable = true)
|
||||||
|
public BigDecimal myValue;
|
||||||
|
|
||||||
|
@ManyToOne(optional = false)
|
||||||
|
@JoinColumn(name = "RESOURCE_PID", nullable = false)
|
||||||
|
private BaseResourceTable<?> myResource;
|
||||||
|
|
||||||
|
@Column(name = "RESOURCE_PID", insertable = false, updatable = false)
|
||||||
|
private Long myResourcePid;
|
||||||
|
|
||||||
|
public ResourceIndexedSearchParamNumber(String theParamName, BigDecimal theValue, String theSystem, String theUnits) {
|
||||||
|
setName(theParamName);
|
||||||
|
setSystem(theSystem);
|
||||||
|
setValue(theValue);
|
||||||
|
setUnits(theUnits);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseResourceTable<?> getResource() {
|
||||||
|
return myResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSystem() {
|
||||||
|
return mySystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUnits() {
|
||||||
|
return myUnits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getValue() {
|
||||||
|
return myValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setResource(BaseResourceTable<?> theResource) {
|
||||||
|
myResource = theResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSystem(String theSystem) {
|
||||||
|
mySystem = theSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUnits(String theUnits) {
|
||||||
|
myUnits = theUnits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(BigDecimal theValue) {
|
||||||
|
myValue = theValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ import javax.persistence.Table;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "IDX_SP_STRING")
|
@Table(name = "IDX_SP_STRING")
|
||||||
public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchParam<String> {
|
public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchParam {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@ -17,6 +17,9 @@ public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchP
|
||||||
@JoinColumn(name = "RESOURCE_PID", nullable = false)
|
@JoinColumn(name = "RESOURCE_PID", nullable = false)
|
||||||
private BaseResourceTable<?> myResource;
|
private BaseResourceTable<?> myResource;
|
||||||
|
|
||||||
|
@Column(name = "RESOURCE_PID", insertable=false, updatable=false)
|
||||||
|
private Long myResourcePid;
|
||||||
|
|
||||||
@Column(name = "SP_VALUE", length = 100, nullable = true)
|
@Column(name = "SP_VALUE", length = 100, nullable = true)
|
||||||
public String myValue;
|
public String myValue;
|
||||||
|
|
||||||
|
@ -36,7 +39,7 @@ public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchP
|
||||||
return myValue;
|
return myValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setResource(BaseResourceTable<?> theResource) {
|
protected void setResource(BaseResourceTable<?> theResource) {
|
||||||
myResource = theResource;
|
myResource = theResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import javax.persistence.Table;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "IDX_SP_TOKEN")
|
@Table(name = "IDX_SP_TOKEN")
|
||||||
public class ResourceIndexedSearchParamToken extends BaseResourceIndexedSearchParam<String> {
|
public class ResourceIndexedSearchParamToken extends BaseResourceIndexedSearchParam {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ public class ResourceIndexedSearchParamToken extends BaseResourceIndexedSearchPa
|
||||||
return myValue;
|
return myValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setResource(BaseResourceTable<?> theResource) {
|
protected void setResource(BaseResourceTable<?> theResource) {
|
||||||
myResource = theResource;
|
myResource = theResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
package ca.uhn.fhir.jpa.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.ForeignKey;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "RES_LINK")
|
||||||
|
public class ResourceLink implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
@Id
|
||||||
|
private Long myId;
|
||||||
|
|
||||||
|
@Column(name = "SRC_PATH", length = 100, nullable = false)
|
||||||
|
private String mySourcePath;
|
||||||
|
|
||||||
|
@ManyToOne(optional = false)
|
||||||
|
@JoinColumn(name = "SRC_RESOURCE_PID", nullable = false, foreignKey = @ForeignKey(name = "FK_RES_LINK_SRC_RES"))
|
||||||
|
private BaseResourceTable<?> mySourceResource;
|
||||||
|
|
||||||
|
@Column(name = "SRC_RESOURCE_PID", insertable = false, updatable = false)
|
||||||
|
private Long mySourceResourcePid;
|
||||||
|
|
||||||
|
@ManyToOne(optional = false)
|
||||||
|
@JoinColumn(name = "TARGET_RESOURCE_PID", nullable = false, foreignKey = @ForeignKey(name = "FK_RES_LINK_TARGET_RES"))
|
||||||
|
private BaseResourceTable<?> myTargetResource;
|
||||||
|
|
||||||
|
@Column(name = "TARGET_RESOURCE_PID", insertable = false, updatable = false)
|
||||||
|
private Long myTargetResourcePid;
|
||||||
|
|
||||||
|
public String getSourcePath() {
|
||||||
|
return mySourcePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseResourceTable<?> getSourceResource() {
|
||||||
|
return mySourceResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getSourceResourcePid() {
|
||||||
|
return mySourceResourcePid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseResourceTable<?> getTargetResource() {
|
||||||
|
return myTargetResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getTargetResourcePid() {
|
||||||
|
return myTargetResourcePid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSourcePath(String theSourcePath) {
|
||||||
|
mySourcePath = theSourcePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSourceResource(BaseResourceTable<?> theSourceResource) {
|
||||||
|
mySourceResource = theSourceResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSourceResourcePid(Long theSourceResourcePid) {
|
||||||
|
mySourceResourcePid = theSourceResourcePid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTargetResource(BaseResourceTable<?> theTargetResource) {
|
||||||
|
myTargetResource = theTargetResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTargetResourcePid(Long theTargetResourcePid) {
|
||||||
|
myTargetResourcePid = theTargetResourcePid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package ca.uhn.fhir.jpa.entity;
|
package ca.uhn.fhir.jpa.entity;
|
||||||
|
|
||||||
import javax.annotation.Generated;
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.GenerationType;
|
import javax.persistence.GenerationType;
|
||||||
|
|
|
@ -21,16 +21,22 @@ import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||||
import ca.uhn.fhir.model.api.TagList;
|
import ca.uhn.fhir.model.api.TagList;
|
||||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||||
|
import ca.uhn.fhir.model.dstu.composite.QuantityDt;
|
||||||
|
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.AdministrativeGenderCodesEnum;
|
import ca.uhn.fhir.model.dstu.valueset.AdministrativeGenderCodesEnum;
|
||||||
|
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
|
||||||
|
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
import ca.uhn.fhir.model.primitive.StringDt;
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
|
import ca.uhn.fhir.rest.param.QualifiedDateParam;
|
||||||
|
|
||||||
public class FhirResourceDaoTest {
|
public class FhirResourceDaoTest {
|
||||||
|
|
||||||
private static ClassPathXmlApplicationContext ourCtx;
|
private static ClassPathXmlApplicationContext ourCtx;
|
||||||
private static IFhirResourceDao<Patient> ourPatientDao;
|
private static IFhirResourceDao<Patient> ourPatientDao;
|
||||||
|
private static IFhirResourceDao<Observation> ourObservationDao;
|
||||||
private static Date ourTestStarted;
|
private static Date ourTestStarted;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -39,6 +45,7 @@ public class FhirResourceDaoTest {
|
||||||
ourTestStarted = new Date();
|
ourTestStarted = new Date();
|
||||||
ourCtx = new ClassPathXmlApplicationContext("fhir-spring-test-config.xml");
|
ourCtx = new ClassPathXmlApplicationContext("fhir-spring-test-config.xml");
|
||||||
ourPatientDao = ourCtx.getBean("myPatientDao", IFhirResourceDao.class);
|
ourPatientDao = ourCtx.getBean("myPatientDao", IFhirResourceDao.class);
|
||||||
|
ourObservationDao = ourCtx.getBean("myObservationDao", IFhirResourceDao.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
|
@ -65,6 +72,53 @@ public class FhirResourceDaoTest {
|
||||||
assertTrue(updated.before(now));
|
assertTrue(updated.before(now));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPersistSearchParamObservationString() {
|
||||||
|
Observation obs = new Observation();
|
||||||
|
obs.getName().addCoding().setSystem("foo").setCode("testPersistSearchParamQuantity");
|
||||||
|
obs.setValue(new StringDt("AAAABBBB"));
|
||||||
|
|
||||||
|
ourObservationDao.create(obs);
|
||||||
|
|
||||||
|
List<Observation> found = ourObservationDao.search("value-string", new StringDt("AAAABBBB"));
|
||||||
|
assertEquals(1,found.size());
|
||||||
|
|
||||||
|
found = ourObservationDao.search("value-string", new StringDt("AAAABBBBCCC"));
|
||||||
|
assertEquals(0,found.size());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPersistSearchParamQuantity() {
|
||||||
|
Observation obs = new Observation();
|
||||||
|
obs.getName().addCoding().setSystem("foo").setCode("testPersistSearchParamQuantity");
|
||||||
|
obs.setValue(new QuantityDt(111));
|
||||||
|
|
||||||
|
ourObservationDao.create(obs);
|
||||||
|
|
||||||
|
List<Observation> found = ourObservationDao.search("value-quantity", new QuantityDt(111));
|
||||||
|
assertEquals(1,found.size());
|
||||||
|
|
||||||
|
found = ourObservationDao.search("value-quantity", new QuantityDt(112));
|
||||||
|
assertEquals(0,found.size());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPersistSearchParamDate() {
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.addIdentifier("urn:system", "001");
|
||||||
|
patient.setBirthDate(new DateTimeDt("2001-01-01"));
|
||||||
|
|
||||||
|
ourPatientDao.create(patient);
|
||||||
|
|
||||||
|
List<Patient> found = ourPatientDao.search("birthdate", new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN, "2000-01-01"));
|
||||||
|
assertEquals(1,found.size());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPersistSearchParams() {
|
public void testPersistSearchParams() {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
|
|
|
@ -17,6 +17,10 @@
|
||||||
<property name="tableType" value="ca.uhn.fhir.jpa.entity.PatientResourceTable"/>
|
<property name="tableType" value="ca.uhn.fhir.jpa.entity.PatientResourceTable"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="myObservationDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||||
|
<property name="tableType" value="ca.uhn.fhir.jpa.entity.ObservationResourceTable"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="myPersistenceDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" lazy-init="true">
|
<bean id="myPersistenceDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" lazy-init="true">
|
||||||
<property name="url" value="jdbc:derby:memory:myUnitTestDB;create=true" />
|
<property name="url" value="jdbc:derby:memory:myUnitTestDB;create=true" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
Loading…
Reference in New Issue