Formatted code
Added Eclipse formatter and cleanup configuration
This commit is contained in:
parent
ebcf32caea
commit
6ac4408ddf
43 changed files with 1196 additions and 963 deletions
56
cleanup.xml
Normal file
56
cleanup.xml
Normal file
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<profiles version="2">
|
||||
<profile kind="CleanUpProfile" name="ROME" version="2">
|
||||
<setting id="cleanup.remove_unused_private_fields" value="true"/>
|
||||
<setting id="cleanup.always_use_parentheses_in_expressions" value="false"/>
|
||||
<setting id="cleanup.never_use_blocks" value="false"/>
|
||||
<setting id="cleanup.remove_unused_private_methods" value="true"/>
|
||||
<setting id="cleanup.add_missing_deprecated_annotations" value="true"/>
|
||||
<setting id="cleanup.convert_to_enhanced_for_loop" value="true"/>
|
||||
<setting id="cleanup.remove_unnecessary_nls_tags" value="true"/>
|
||||
<setting id="cleanup.sort_members" value="false"/>
|
||||
<setting id="cleanup.remove_unused_local_variables" value="false"/>
|
||||
<setting id="cleanup.never_use_parentheses_in_expressions" value="true"/>
|
||||
<setting id="cleanup.remove_unused_private_members" value="false"/>
|
||||
<setting id="cleanup.remove_unnecessary_casts" value="true"/>
|
||||
<setting id="cleanup.make_parameters_final" value="true"/>
|
||||
<setting id="cleanup.use_this_for_non_static_field_access" value="true"/>
|
||||
<setting id="cleanup.remove_private_constructors" value="true"/>
|
||||
<setting id="cleanup.use_blocks" value="true"/>
|
||||
<setting id="cleanup.always_use_this_for_non_static_method_access" value="false"/>
|
||||
<setting id="cleanup.remove_trailing_whitespaces_all" value="true"/>
|
||||
<setting id="cleanup.always_use_this_for_non_static_field_access" value="false"/>
|
||||
<setting id="cleanup.use_this_for_non_static_field_access_only_if_necessary" value="true"/>
|
||||
<setting id="cleanup.add_default_serial_version_id" value="true"/>
|
||||
<setting id="cleanup.make_type_abstract_if_missing_method" value="false"/>
|
||||
<setting id="cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class" value="true"/>
|
||||
<setting id="cleanup.make_variable_declarations_final" value="true"/>
|
||||
<setting id="cleanup.add_missing_nls_tags" value="false"/>
|
||||
<setting id="cleanup.format_source_code" value="true"/>
|
||||
<setting id="cleanup.qualify_static_method_accesses_with_declaring_class" value="false"/>
|
||||
<setting id="cleanup.add_missing_override_annotations" value="true"/>
|
||||
<setting id="cleanup.remove_unused_private_types" value="true"/>
|
||||
<setting id="cleanup.add_missing_methods" value="false"/>
|
||||
<setting id="cleanup.make_local_variable_final" value="true"/>
|
||||
<setting id="cleanup.correct_indentation" value="true"/>
|
||||
<setting id="cleanup.add_missing_override_annotations_interface_methods" value="true"/>
|
||||
<setting id="cleanup.remove_unused_imports" value="true"/>
|
||||
<setting id="cleanup.remove_trailing_whitespaces_ignore_empty" value="false"/>
|
||||
<setting id="cleanup.make_private_fields_final" value="true"/>
|
||||
<setting id="cleanup.add_generated_serial_version_id" value="false"/>
|
||||
<setting id="cleanup.organize_imports" value="true"/>
|
||||
<setting id="cleanup.remove_trailing_whitespaces" value="true"/>
|
||||
<setting id="cleanup.sort_members_all" value="false"/>
|
||||
<setting id="cleanup.use_blocks_only_for_return_and_throw" value="false"/>
|
||||
<setting id="cleanup.add_missing_annotations" value="true"/>
|
||||
<setting id="cleanup.use_parentheses_in_expressions" value="true"/>
|
||||
<setting id="cleanup.qualify_static_field_accesses_with_declaring_class" value="false"/>
|
||||
<setting id="cleanup.use_this_for_non_static_method_access_only_if_necessary" value="true"/>
|
||||
<setting id="cleanup.use_this_for_non_static_method_access" value="true"/>
|
||||
<setting id="cleanup.qualify_static_member_accesses_through_instances_with_declaring_class" value="true"/>
|
||||
<setting id="cleanup.add_serial_version_id" value="false"/>
|
||||
<setting id="cleanup.format_source_code_changes_only" value="false"/>
|
||||
<setting id="cleanup.qualify_static_member_accesses_with_declaring_class" value="true"/>
|
||||
<setting id="cleanup.always_use_blocks" value="true"/>
|
||||
</profile>
|
||||
</profiles>
|
291
formatter.xml
Normal file
291
formatter.xml
Normal file
|
@ -0,0 +1,291 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<profiles version="12">
|
||||
<profile kind="CodeFormatterProfile" name="ROME" version="12">
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.source" value="1.7"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="160"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.7"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.7"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
|
||||
</profile>
|
||||
</profiles>
|
|
@ -16,24 +16,23 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class HttpStatusCodeException extends RuntimeException {
|
||||
|
||||
private final int status;
|
||||
|
||||
public HttpStatusCodeException(int status, String message, Throwable cause){
|
||||
public HttpStatusCodeException(final int status, final String message, final Throwable cause) {
|
||||
super(message, cause);
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public int getStatus(){
|
||||
return this.status;
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,33 +5,32 @@
|
|||
package org.rometools.certiorem.hub;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import org.rometools.fetcher.impl.FeedFetcherCache;
|
||||
import org.rometools.fetcher.impl.SyndFeedInfo;
|
||||
|
||||
/**
|
||||
* Wrapper FeedFetcherCache that wraps a backing FeedFetcherCache and makes sure that
|
||||
* any SyndFeedInfo used within it are replaced with a DeltaSyndFeedInfo which is capable of
|
||||
* tracking changes to entries in the underlying feed.
|
||||
* Wrapper FeedFetcherCache that wraps a backing FeedFetcherCache and makes sure that any SyndFeedInfo used within it are replaced with a DeltaSyndFeedInfo
|
||||
* which is capable of tracking changes to entries in the underlying feed.
|
||||
*
|
||||
* @author najmi
|
||||
*/
|
||||
public class DeltaFeedInfoCache implements FeedFetcherCache {
|
||||
|
||||
|
||||
FeedFetcherCache backingCache;
|
||||
|
||||
|
||||
public DeltaFeedInfoCache(FeedFetcherCache backingCache) {
|
||||
|
||||
public DeltaFeedInfoCache(final FeedFetcherCache backingCache) {
|
||||
this.backingCache = backingCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SyndFeedInfo getFeedInfo(URL feedUrl) {
|
||||
public SyndFeedInfo getFeedInfo(final URL feedUrl) {
|
||||
return backingCache.getFeedInfo(feedUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFeedInfo(URL feedUrl, SyndFeedInfo syndFeedInfo) {
|
||||
//Make sure that syndFeedInfo is an instance of DeltaSyndFeedInfo
|
||||
public void setFeedInfo(final URL feedUrl, SyndFeedInfo syndFeedInfo) {
|
||||
// Make sure that syndFeedInfo is an instance of DeltaSyndFeedInfo
|
||||
if (!(syndFeedInfo instanceof DeltaSyndFeedInfo)) {
|
||||
syndFeedInfo = new DeltaSyndFeedInfo(syndFeedInfo);
|
||||
}
|
||||
|
@ -40,12 +39,12 @@ public class DeltaFeedInfoCache implements FeedFetcherCache {
|
|||
|
||||
@Override
|
||||
public void clear() {
|
||||
backingCache.clear();
|
||||
backingCache.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SyndFeedInfo remove(URL feedUrl) {
|
||||
public SyndFeedInfo remove(final URL feedUrl) {
|
||||
return backingCache.remove(feedUrl);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
*/
|
||||
package org.rometools.certiorem.hub;
|
||||
|
||||
import com.sun.syndication.feed.synd.SyndEntry;
|
||||
import com.sun.syndication.feed.synd.SyndFeed;
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.ArrayList;
|
||||
|
@ -13,51 +11,55 @@ import java.util.Date;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.rometools.fetcher.impl.SyndFeedInfo;
|
||||
|
||||
import com.sun.syndication.feed.synd.SyndEntry;
|
||||
import com.sun.syndication.feed.synd.SyndFeed;
|
||||
|
||||
/**
|
||||
* Extends SyndFeedInfo to also track etags for individual entries.
|
||||
* This may be used with DeltaFeedInfoCache to only return feed with a subset of entries that have changed since last fetch.
|
||||
* Extends SyndFeedInfo to also track etags for individual entries. This may be used with DeltaFeedInfoCache to only return feed with a subset of entries that
|
||||
* have changed since last fetch.
|
||||
*
|
||||
* @author najmi
|
||||
*/
|
||||
public class DeltaSyndFeedInfo extends SyndFeedInfo {
|
||||
public class DeltaSyndFeedInfo extends SyndFeedInfo {
|
||||
Map<String, String> entryTagsMap = new HashMap<String, String>();
|
||||
Map<String, Boolean> changedMap = new HashMap<String, Boolean>();
|
||||
|
||||
private DeltaSyndFeedInfo() {
|
||||
|
||||
private DeltaSyndFeedInfo() {
|
||||
}
|
||||
|
||||
public DeltaSyndFeedInfo(SyndFeedInfo backingFeedInfo) {
|
||||
this.setETag(backingFeedInfo.getETag());
|
||||
this.setId(backingFeedInfo.getId());
|
||||
this.setLastModified(backingFeedInfo.getLastModified());
|
||||
this.setSyndFeed(backingFeedInfo.getSyndFeed());
|
||||
|
||||
public DeltaSyndFeedInfo(final SyndFeedInfo backingFeedInfo) {
|
||||
setETag(backingFeedInfo.getETag());
|
||||
setId(backingFeedInfo.getId());
|
||||
setLastModified(backingFeedInfo.getLastModified());
|
||||
setSyndFeed(backingFeedInfo.getSyndFeed());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a filtered version of the SyndFeed that only has entries that were changed in the last setSyndFeed() call.
|
||||
*
|
||||
* @return
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public synchronized SyndFeed getSyndFeed() {
|
||||
try {
|
||||
SyndFeed feed = (SyndFeed) super.getSyndFeed().clone();
|
||||
|
||||
List<SyndEntry> changedEntries = new ArrayList<SyndEntry>();
|
||||
|
||||
List<SyndEntry> entries = feed.getEntries();
|
||||
for (SyndEntry entry : entries) {
|
||||
final SyndFeed feed = (SyndFeed) super.getSyndFeed().clone();
|
||||
|
||||
final List<SyndEntry> changedEntries = new ArrayList<SyndEntry>();
|
||||
|
||||
final List<SyndEntry> entries = feed.getEntries();
|
||||
for (final SyndEntry entry : entries) {
|
||||
if (changedMap.containsKey(entry.getUri())) {
|
||||
changedEntries.add(entry);
|
||||
changedEntries.add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
feed.setEntries(changedEntries);
|
||||
|
||||
|
||||
return feed;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
} catch (final CloneNotSupportedException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
@ -65,58 +67,58 @@ public class DeltaSyndFeedInfo extends SyndFeedInfo {
|
|||
/**
|
||||
* Overrides super class method to update changedMap and entryTagsMap for tracking changed entries.
|
||||
*
|
||||
* @param feed
|
||||
* @param feed
|
||||
*/
|
||||
@Override
|
||||
public final synchronized void setSyndFeed(SyndFeed feed) {
|
||||
public final synchronized void setSyndFeed(final SyndFeed feed) {
|
||||
super.setSyndFeed(feed);
|
||||
|
||||
changedMap.clear();
|
||||
List<SyndEntry> entries = feed.getEntries();
|
||||
for (SyndEntry entry : entries) {
|
||||
String currentEntryTag = computeEntryTag(entry);
|
||||
String previousEntryTag = entryTagsMap.get(entry.getUri());
|
||||
|
||||
if ((previousEntryTag == null) || (!(currentEntryTag.equals(previousEntryTag)))) {
|
||||
//Entry has changed
|
||||
changedMap.clear();
|
||||
final List<SyndEntry> entries = feed.getEntries();
|
||||
for (final SyndEntry entry : entries) {
|
||||
final String currentEntryTag = computeEntryTag(entry);
|
||||
final String previousEntryTag = entryTagsMap.get(entry.getUri());
|
||||
|
||||
if (previousEntryTag == null || !currentEntryTag.equals(previousEntryTag)) {
|
||||
// Entry has changed
|
||||
changedMap.put(entry.getUri(), Boolean.TRUE);
|
||||
}
|
||||
entryTagsMap.put(entry.getUri(), currentEntryTag);
|
||||
}
|
||||
}
|
||||
|
||||
private String computeEntryTag(SyndEntry entry) {
|
||||
|
||||
//Following hash algorithm suggested by Robert Cooper needs to be evaluated in future.
|
||||
// int hash = ( entry.getUri() != null ? entry.getUri().hashCode() : entry.getLink().hashCode() ) ^
|
||||
// (entry.getUpdatedDate() != null ? entry.getUpdatedDate().hashCode() : entry.getPublishedDate().hashCode()) ^
|
||||
// entry.getTitle().hashCode() ^
|
||||
// entry.getDescription().hashCode();
|
||||
private String computeEntryTag(final SyndEntry entry) {
|
||||
|
||||
|
||||
String id = entry.getUri();
|
||||
// Following hash algorithm suggested by Robert Cooper needs to be evaluated in future.
|
||||
// int hash = ( entry.getUri() != null ? entry.getUri().hashCode() : entry.getLink().hashCode() ) ^
|
||||
// (entry.getUpdatedDate() != null ? entry.getUpdatedDate().hashCode() : entry.getPublishedDate().hashCode()) ^
|
||||
// entry.getTitle().hashCode() ^
|
||||
// entry.getDescription().hashCode();
|
||||
|
||||
final String id = entry.getUri();
|
||||
Date updateDate = entry.getUpdatedDate();
|
||||
Date publishedDate = entry.getPublishedDate();
|
||||
final Date publishedDate = entry.getPublishedDate();
|
||||
if (updateDate == null) {
|
||||
if (publishedDate != null) {
|
||||
updateDate = publishedDate;
|
||||
} else {
|
||||
//For misbehaving feeds that do not set updateDate or publishedDate we use current tiem which pretty mucg assures that it will be viewed as changed even when it is not
|
||||
} else {
|
||||
// For misbehaving feeds that do not set updateDate or publishedDate we use current tiem which pretty mucg assures that it will be viewed as
|
||||
// changed even when it is not
|
||||
updateDate = new Date();
|
||||
}
|
||||
}
|
||||
String key = id + ":" + entry.getUpdatedDate();
|
||||
return computeDigest(key);
|
||||
final String key = id + ":" + entry.getUpdatedDate();
|
||||
return computeDigest(key);
|
||||
}
|
||||
|
||||
private String computeDigest(String content) {
|
||||
|
||||
private String computeDigest(final String content) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA");
|
||||
byte[] digest = md.digest(content.getBytes());
|
||||
BigInteger bi = new BigInteger(digest);
|
||||
final MessageDigest md = MessageDigest.getInstance("SHA");
|
||||
final byte[] digest = md.digest(content.getBytes());
|
||||
final BigInteger bi = new BigInteger(digest);
|
||||
return bi.toString(16);
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,21 +18,9 @@
|
|||
|
||||
package org.rometools.certiorem.hub;
|
||||
|
||||
import com.sun.syndication.feed.synd.SyndFeed;
|
||||
|
||||
import org.rometools.certiorem.HttpStatusCodeException;
|
||||
import org.rometools.certiorem.hub.Notifier.SubscriptionSummaryCallback;
|
||||
import org.rometools.certiorem.hub.Verifier.VerificationCallback;
|
||||
import org.rometools.certiorem.hub.data.HubDAO;
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||
|
||||
import org.rometools.fetcher.FeedFetcher;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
@ -40,12 +28,20 @@ import java.util.Set;
|
|||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.rometools.certiorem.HttpStatusCodeException;
|
||||
import org.rometools.certiorem.hub.Notifier.SubscriptionSummaryCallback;
|
||||
import org.rometools.certiorem.hub.Verifier.VerificationCallback;
|
||||
import org.rometools.certiorem.hub.data.HubDAO;
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||
import org.rometools.fetcher.FeedFetcher;
|
||||
|
||||
import com.sun.syndication.feed.synd.SyndFeed;
|
||||
|
||||
/**
|
||||
* The basic business logic controller for the Hub implementation. It is intended
|
||||
* to be usable under a very thin servlet wrapper, or other, non-HTTP notification
|
||||
* methods you might want to use.
|
||||
*
|
||||
* The basic business logic controller for the Hub implementation. It is intended to be usable under a very thin servlet wrapper, or other, non-HTTP
|
||||
* notification methods you might want to use.
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class Hub {
|
||||
|
@ -66,6 +62,7 @@ public class Hub {
|
|||
|
||||
/**
|
||||
* Constructs a new Hub instance
|
||||
*
|
||||
* @param dao The persistence HubDAO to use
|
||||
* @param verifier The verification strategy to use.
|
||||
*/
|
||||
|
@ -74,122 +71,111 @@ public class Hub {
|
|||
this.verifier = verifier;
|
||||
this.notifier = notifier;
|
||||
this.fetcher = fetcher;
|
||||
this.validSchemes = STANDARD_SCHEMES;
|
||||
this.validPorts = Collections.EMPTY_SET;
|
||||
this.validTopics = Collections.EMPTY_SET;
|
||||
validSchemes = STANDARD_SCHEMES;
|
||||
validPorts = Collections.EMPTY_SET;
|
||||
validTopics = Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new Hub instance.
|
||||
*
|
||||
* @param dao The persistence HubDAO to use
|
||||
* @param verifier The verification strategy to use
|
||||
* @param validSchemes A list of valid URI schemes for callbacks (default: http, https)
|
||||
* @param validPorts A list of valid port numbers for callbacks (default: any)
|
||||
* @param validTopics A set of valid topic URIs which can be subscribed to (default: any)
|
||||
*/
|
||||
public Hub(final HubDAO dao, final Verifier verifier, final Notifier notifier, final FeedFetcher fetcher,
|
||||
final Set<String> validSchemes, final Set<Integer> validPorts, final Set<String> validTopics) {
|
||||
public Hub(final HubDAO dao, final Verifier verifier, final Notifier notifier, final FeedFetcher fetcher, final Set<String> validSchemes,
|
||||
final Set<Integer> validPorts, final Set<String> validTopics) {
|
||||
this.dao = dao;
|
||||
this.verifier = verifier;
|
||||
this.notifier = notifier;
|
||||
this.fetcher = fetcher;
|
||||
|
||||
Set<String> readOnlySchemes = Collections.unmodifiableSet(validSchemes);
|
||||
this.validSchemes = (readOnlySchemes == null) ? STANDARD_SCHEMES : readOnlySchemes;
|
||||
final Set<String> readOnlySchemes = Collections.unmodifiableSet(validSchemes);
|
||||
this.validSchemes = readOnlySchemes == null ? STANDARD_SCHEMES : readOnlySchemes;
|
||||
|
||||
Set<Integer> readOnlyPorts = Collections.unmodifiableSet(validPorts);
|
||||
this.validPorts = (readOnlyPorts == null) ? Collections.EMPTY_SET : readOnlyPorts;
|
||||
final Set<Integer> readOnlyPorts = Collections.unmodifiableSet(validPorts);
|
||||
this.validPorts = readOnlyPorts == null ? Collections.EMPTY_SET : readOnlyPorts;
|
||||
|
||||
Set<String> readOnlyTopics = Collections.unmodifiableSet(validTopics);
|
||||
this.validTopics = (readOnlyTopics == null) ? Collections.EMPTY_SET : readOnlyTopics;
|
||||
final Set<String> readOnlyTopics = Collections.unmodifiableSet(validTopics);
|
||||
this.validTopics = readOnlyTopics == null ? Collections.EMPTY_SET : readOnlyTopics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a notification to the subscribers
|
||||
*
|
||||
* @param requestHost the host name the hub is running on. (Used for the user agent)
|
||||
* @param topic the URL of the topic that was updated.
|
||||
* @throws HttpStatusCodeException a wrapper exception with a recommended status code for the request.
|
||||
*/
|
||||
public void sendNotification(String requestHost, final String topic) {
|
||||
assert this.validTopics.isEmpty() || this.validTopics.contains(topic) : "That topic is not supported by this hub. " +
|
||||
topic;
|
||||
public void sendNotification(final String requestHost, final String topic) {
|
||||
assert validTopics.isEmpty() || validTopics.contains(topic) : "That topic is not supported by this hub. " + topic;
|
||||
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "Sending notification for {0}", topic);
|
||||
try {
|
||||
List<?extends Subscriber> subscribers = dao.subscribersForTopic(topic);
|
||||
final List<? extends Subscriber> subscribers = dao.subscribersForTopic(topic);
|
||||
|
||||
if (subscribers.isEmpty()) {
|
||||
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "No subscribers to notify for {0}", topic);
|
||||
return;
|
||||
}
|
||||
|
||||
List<SubscriptionSummary> summaries = (List<SubscriptionSummary>) dao.summariesForTopic(topic);
|
||||
final List<SubscriptionSummary> summaries = (List<SubscriptionSummary>) dao.summariesForTopic(topic);
|
||||
int total = 0;
|
||||
StringBuilder hosts = new StringBuilder();
|
||||
final StringBuilder hosts = new StringBuilder();
|
||||
|
||||
for (SubscriptionSummary s : summaries) {
|
||||
for (final SubscriptionSummary s : summaries) {
|
||||
if (s.getSubscribers() > 0) {
|
||||
total += s.getSubscribers();
|
||||
hosts.append(" (")
|
||||
.append(s.getHost())
|
||||
.append("; ")
|
||||
.append(s.getSubscribers())
|
||||
.append(" subscribers)");
|
||||
hosts.append(" (").append(s.getHost()).append("; ").append(s.getSubscribers()).append(" subscribers)");
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder userAgent = new StringBuilder("ROME-Certiorem (+http://").append(requestHost)
|
||||
.append("; ")
|
||||
.append(total)
|
||||
.append(" subscribers)")
|
||||
.append(hosts);
|
||||
SyndFeed feed = fetcher.retrieveFeed(userAgent.toString(), new URL(topic));
|
||||
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "Got feed for {0} Sending to {1} subscribers.", new Object[]{topic, subscribers.size()});
|
||||
this.notifier.notifySubscribers((List<Subscriber>) subscribers, feed,
|
||||
new SubscriptionSummaryCallback() {
|
||||
@Override
|
||||
public void onSummaryInfo(SubscriptionSummary summary) {
|
||||
dao.handleSummary(topic, summary);
|
||||
}
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(Hub.class.getName())
|
||||
.log(Level.SEVERE, "Exception getting " + topic, ex);
|
||||
final StringBuilder userAgent = new StringBuilder("ROME-Certiorem (+http://").append(requestHost).append("; ").append(total)
|
||||
.append(" subscribers)").append(hosts);
|
||||
final SyndFeed feed = fetcher.retrieveFeed(userAgent.toString(), new URL(topic));
|
||||
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "Got feed for {0} Sending to {1} subscribers.", new Object[] { topic, subscribers.size() });
|
||||
notifier.notifySubscribers((List<Subscriber>) subscribers, feed, new SubscriptionSummaryCallback() {
|
||||
@Override
|
||||
public void onSummaryInfo(final SubscriptionSummary summary) {
|
||||
dao.handleSummary(topic, summary);
|
||||
}
|
||||
});
|
||||
} catch (final Exception ex) {
|
||||
Logger.getLogger(Hub.class.getName()).log(Level.SEVERE, "Exception getting " + topic, ex);
|
||||
throw new HttpStatusCodeException(500, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribes to a topic.
|
||||
*
|
||||
* @param callback Callback URI
|
||||
* @param topic Topic URI
|
||||
* @param verify Verification Type
|
||||
* @param lease_seconds Duration of the lease
|
||||
* @param secret Secret value
|
||||
* @param verify_token verify_token;
|
||||
* @return Boolean.TRUE if the subscription succeeded synchronously,
|
||||
* Boolean.FALSE if the subscription failed synchronously, or null if the request is asynchronous.
|
||||
* @return Boolean.TRUE if the subscription succeeded synchronously, Boolean.FALSE if the subscription failed synchronously, or null if the request is
|
||||
* asynchronous.
|
||||
* @throws HttpStatusCodeException a wrapper exception with a recommended status code for the request.
|
||||
*/
|
||||
public Boolean subscribe(String callback, String topic, String verify, long lease_seconds, String secret,
|
||||
String verify_token) {
|
||||
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "{0} wants to subscribe to {1}", new Object[]{callback, topic});
|
||||
public Boolean subscribe(final String callback, final String topic, final String verify, final long lease_seconds, final String secret,
|
||||
final String verify_token) {
|
||||
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "{0} wants to subscribe to {1}", new Object[] { callback, topic });
|
||||
try {
|
||||
try {
|
||||
assert callback != null : "Callback URL is required.";
|
||||
assert topic != null : "Topic URL is required.";
|
||||
|
||||
URI uri = new URI(callback);
|
||||
assert this.validSchemes.contains(uri.getScheme()) : "Not a valid protocol " + uri.getScheme();
|
||||
assert this.validPorts.isEmpty() || this.validPorts.contains(uri.getPort()) : "Not a valid port " +
|
||||
uri.getPort();
|
||||
assert this.validTopics.isEmpty() || this.validTopics.contains(topic) : "Not a supported topic " +
|
||||
topic;
|
||||
} catch (URISyntaxException ex) {
|
||||
final URI uri = new URI(callback);
|
||||
assert validSchemes.contains(uri.getScheme()) : "Not a valid protocol " + uri.getScheme();
|
||||
assert validPorts.isEmpty() || validPorts.contains(uri.getPort()) : "Not a valid port " + uri.getPort();
|
||||
assert validTopics.isEmpty() || validTopics.contains(topic) : "Not a supported topic " + topic;
|
||||
} catch (final URISyntaxException ex) {
|
||||
assert false : "Not a valid URI " + callback;
|
||||
}
|
||||
assert (verify != null) &&
|
||||
(verify.equals(Subscriber.VERIFY_ASYNC) || verify.equals(Subscriber.VERIFY_SYNC)) : "Unexpected verify value " +
|
||||
verify;
|
||||
assert verify != null && (verify.equals(Subscriber.VERIFY_ASYNC) || verify.equals(Subscriber.VERIFY_SYNC)) : "Unexpected verify value " + verify;
|
||||
|
||||
final Subscriber subscriber = new Subscriber();
|
||||
subscriber.setCallback(callback);
|
||||
|
@ -199,18 +185,19 @@ public class Hub {
|
|||
subscriber.setVerify(verify);
|
||||
subscriber.setVertifyToken(verify_token);
|
||||
|
||||
VerificationCallback verified = new VerificationCallback() {
|
||||
@Override
|
||||
public void onVerify(boolean verified) {
|
||||
if (verified) {
|
||||
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "Verified {0} subscribed to {1}", new Object[]{subscriber.getCallback(), subscriber.getTopic()});
|
||||
dao.addSubscriber(subscriber);
|
||||
}
|
||||
final VerificationCallback verified = new VerificationCallback() {
|
||||
@Override
|
||||
public void onVerify(final boolean verified) {
|
||||
if (verified) {
|
||||
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "Verified {0} subscribed to {1}",
|
||||
new Object[] { subscriber.getCallback(), subscriber.getTopic() });
|
||||
dao.addSubscriber(subscriber);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
if (Subscriber.VERIFY_SYNC.equals(subscriber.getVerify())) {
|
||||
boolean result = verifier.verifySubcribeSyncronously(subscriber);
|
||||
final boolean result = verifier.verifySubcribeSyncronously(subscriber);
|
||||
verified.onVerify(result);
|
||||
|
||||
return result;
|
||||
|
@ -219,33 +206,34 @@ public class Hub {
|
|||
|
||||
return null;
|
||||
}
|
||||
} catch (AssertionError ae) {
|
||||
} catch (final AssertionError ae) {
|
||||
throw new HttpStatusCodeException(400, ae.getMessage(), ae);
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
throw new HttpStatusCodeException(500, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean unsubscribe(final String callback, final String topic, String verify, String secret, String verifyToken) {
|
||||
public Boolean unsubscribe(final String callback, final String topic, final String verify, final String secret, final String verifyToken) {
|
||||
final Subscriber subscriber = dao.findSubscriber(topic, callback);
|
||||
if(subscriber == null){
|
||||
if (subscriber == null) {
|
||||
throw new HttpStatusCodeException(400, "Not a valid subscription.", null);
|
||||
}
|
||||
subscriber.setVertifyToken(verifyToken);
|
||||
subscriber.setSecret(secret);
|
||||
if(Subscriber.VERIFY_SYNC.equals(verify)){
|
||||
if (Subscriber.VERIFY_SYNC.equals(verify)) {
|
||||
|
||||
boolean ret = verifier.verifyUnsubcribeSyncronously(subscriber);
|
||||
if(ret){
|
||||
final boolean ret = verifier.verifyUnsubcribeSyncronously(subscriber);
|
||||
if (ret) {
|
||||
dao.removeSubscriber(topic, callback);
|
||||
}
|
||||
} else {
|
||||
verifier.verifyUnsubscribeAsyncronously(subscriber, new VerificationCallback(){
|
||||
verifier.verifyUnsubscribeAsyncronously(subscriber, new VerificationCallback() {
|
||||
|
||||
@Override
|
||||
public void onVerify(boolean verified) {
|
||||
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "Unsubscribe for {0} at {1} verified {2}", new Object[]{subscriber.getTopic(), subscriber.getCallback(), verified});
|
||||
if(verified){
|
||||
public void onVerify(final boolean verified) {
|
||||
Logger.getLogger(Hub.class.getName()).log(Level.FINE, "Unsubscribe for {0} at {1} verified {2}",
|
||||
new Object[] { subscriber.getTopic(), subscriber.getCallback(), verified });
|
||||
if (verified) {
|
||||
dao.removeSubscriber(topic, callback);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,22 +18,21 @@
|
|||
|
||||
package org.rometools.certiorem.hub;
|
||||
|
||||
import com.sun.syndication.feed.synd.SyndFeed;
|
||||
import java.util.List;
|
||||
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.syndication.feed.synd.SyndFeed;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public interface Notifier {
|
||||
/**
|
||||
* Instructs the notifier to begin sending notifications to the list of subscribers
|
||||
*
|
||||
*
|
||||
* @param subscribers Subscribers to notify
|
||||
* @param value The SyndFeed to send them
|
||||
* @param callback A callback that is invoked each time a subscriber is notified.
|
||||
|
@ -41,11 +40,11 @@ public interface Notifier {
|
|||
public void notifySubscribers(List<Subscriber> subscribers, SyndFeed value, SubscriptionSummaryCallback callback);
|
||||
|
||||
/**
|
||||
* A callback that is invoked each time a subscriber is notified.
|
||||
* A callback that is invoked each time a subscriber is notified.
|
||||
*/
|
||||
public static interface SubscriptionSummaryCallback {
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param summary A summary of the data received from the subscriber
|
||||
*/
|
||||
public void onSummaryInfo(SubscriptionSummary summary);
|
||||
|
|
|
@ -20,9 +20,9 @@ package org.rometools.certiorem.hub;
|
|||
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
|
||||
|
||||
/**
|
||||
* A strategy interface for verification of subscriptions.
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public interface Verifier {
|
||||
|
@ -38,6 +38,7 @@ public interface Verifier {
|
|||
|
||||
/**
|
||||
* Verifies a subscriber (possibly) asyncronously
|
||||
*
|
||||
* @param subscriber the Subscriber to verify
|
||||
* @param callback a callback with the result of the verification.
|
||||
*/
|
||||
|
@ -45,32 +46,34 @@ public interface Verifier {
|
|||
|
||||
/**
|
||||
* Verifies a subscriber syncronously
|
||||
* @param subscriber The subscriber data
|
||||
*
|
||||
* @param subscriber The subscriber data
|
||||
* @return boolean result;
|
||||
*/
|
||||
public boolean verifySubcribeSyncronously(Subscriber subscriber);
|
||||
|
||||
/**
|
||||
* Verifies am unsubscribe (possibly) asyncronously
|
||||
*
|
||||
* @param subscriber The subscriber data
|
||||
* @param callback result
|
||||
*/
|
||||
public void verifyUnsubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Verifies an unsubscribe syncronously
|
||||
* @param subscriber The subscriber data
|
||||
*
|
||||
* @param subscriber The subscriber data
|
||||
* @return boolean result;
|
||||
*/
|
||||
public boolean verifyUnsubcribeSyncronously(Subscriber subscriber);
|
||||
|
||||
|
||||
/**
|
||||
* An interface for capturing the result of a verification (subscribe or unsubscribe)
|
||||
*/
|
||||
public static interface VerificationCallback {
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param verified success state of the verification
|
||||
*/
|
||||
public void onVerify(boolean verified);
|
||||
|
|
|
@ -16,13 +16,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem.hub.data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public interface HubDAO {
|
||||
|
|
|
@ -20,9 +20,8 @@ package org.rometools.certiorem.hub.data;
|
|||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class Subscriber implements Serializable {
|
||||
|
@ -38,132 +37,132 @@ public class Subscriber implements Serializable {
|
|||
|
||||
/**
|
||||
* Set the value of callback
|
||||
*
|
||||
*
|
||||
* @param newcallback new value of callback
|
||||
*/
|
||||
public void setCallback(String newcallback) {
|
||||
this.callback = newcallback;
|
||||
public void setCallback(final String newcallback) {
|
||||
callback = newcallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of callback
|
||||
*
|
||||
*
|
||||
* @return the value of callback
|
||||
*/
|
||||
public String getCallback() {
|
||||
return this.callback;
|
||||
return callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of creationTime
|
||||
*
|
||||
*
|
||||
* @param newcreationTime new value of creationTime
|
||||
*/
|
||||
public void setCreationTime(long newcreationTime) {
|
||||
this.creationTime = newcreationTime;
|
||||
public void setCreationTime(final long newcreationTime) {
|
||||
creationTime = newcreationTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of creationTime
|
||||
*
|
||||
*
|
||||
* @return the value of creationTime
|
||||
*/
|
||||
public long getCreationTime() {
|
||||
return this.creationTime;
|
||||
return creationTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of leaseSeconds
|
||||
*
|
||||
*
|
||||
* @param newleaseSeconds new value of leaseSeconds
|
||||
*/
|
||||
public void setLeaseSeconds(long newleaseSeconds) {
|
||||
this.leaseSeconds = newleaseSeconds;
|
||||
public void setLeaseSeconds(final long newleaseSeconds) {
|
||||
leaseSeconds = newleaseSeconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of leaseSeconds
|
||||
*
|
||||
*
|
||||
* @return the value of leaseSeconds
|
||||
*/
|
||||
public long getLeaseSeconds() {
|
||||
return this.leaseSeconds;
|
||||
return leaseSeconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of secret
|
||||
*
|
||||
*
|
||||
* @param newsecret new value of secret
|
||||
*/
|
||||
public void setSecret(String newsecret) {
|
||||
this.secret = newsecret;
|
||||
public void setSecret(final String newsecret) {
|
||||
secret = newsecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of secret
|
||||
*
|
||||
*
|
||||
* @return the value of secret
|
||||
*/
|
||||
public String getSecret() {
|
||||
return this.secret;
|
||||
return secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of topic
|
||||
*
|
||||
*
|
||||
* @param newtopic new value of topic
|
||||
*/
|
||||
public void setTopic(String newtopic) {
|
||||
this.topic = newtopic;
|
||||
public void setTopic(final String newtopic) {
|
||||
topic = newtopic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of topic
|
||||
*
|
||||
*
|
||||
* @return the value of topic
|
||||
*/
|
||||
public String getTopic() {
|
||||
return this.topic;
|
||||
return topic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of verify
|
||||
*
|
||||
*
|
||||
* @param newverify new value of verify
|
||||
*/
|
||||
public void setVerify(String newverify) {
|
||||
this.verify = newverify;
|
||||
public void setVerify(final String newverify) {
|
||||
verify = newverify;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of verify
|
||||
*
|
||||
*
|
||||
* @return the value of verify
|
||||
*/
|
||||
public String getVerify() {
|
||||
return this.verify;
|
||||
return verify;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of vertifyToken
|
||||
*
|
||||
*
|
||||
* @param newvertifyToken new value of vertifyToken
|
||||
*/
|
||||
public void setVertifyToken(String newvertifyToken) {
|
||||
this.vertifyToken = newvertifyToken;
|
||||
public void setVertifyToken(final String newvertifyToken) {
|
||||
vertifyToken = newvertifyToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of vertifyToken
|
||||
*
|
||||
*
|
||||
* @return the value of vertifyToken
|
||||
*/
|
||||
public String getVertifyToken() {
|
||||
return this.vertifyToken;
|
||||
return vertifyToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
|
@ -174,31 +173,31 @@ public class Subscriber implements Serializable {
|
|||
|
||||
final Subscriber other = (Subscriber) obj;
|
||||
|
||||
if ((this.callback == null) ? (other.callback != null) : (!this.callback.equals(other.callback))) {
|
||||
if (callback == null ? other.callback != null : !callback.equals(other.callback)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((this.secret == null) ? (other.secret != null) : (!this.secret.equals(other.secret))) {
|
||||
if (secret == null ? other.secret != null : !secret.equals(other.secret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((this.topic == null) ? (other.topic != null) : (!this.topic.equals(other.topic))) {
|
||||
if (topic == null ? other.topic != null : !topic.equals(other.topic)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((this.verify == null) ? (other.verify != null) : (!this.verify.equals(other.verify))) {
|
||||
if (verify == null ? other.verify != null : !verify.equals(other.verify)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((this.vertifyToken == null) ? (other.vertifyToken != null) : (!this.vertifyToken.equals(other.vertifyToken))) {
|
||||
if (vertifyToken == null ? other.vertifyToken != null : !vertifyToken.equals(other.vertifyToken)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.creationTime != other.creationTime) {
|
||||
if (creationTime != other.creationTime) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.leaseSeconds != other.leaseSeconds) {
|
||||
if (leaseSeconds != other.leaseSeconds) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -208,13 +207,13 @@ public class Subscriber implements Serializable {
|
|||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = (67 * hash) + ((this.callback != null) ? this.callback.hashCode() : 0);
|
||||
hash = (67 * hash) + ((this.secret != null) ? this.secret.hashCode() : 0);
|
||||
hash = (67 * hash) + ((this.topic != null) ? this.topic.hashCode() : 0);
|
||||
hash = (67 * hash) + ((this.verify != null) ? this.verify.hashCode() : 0);
|
||||
hash = (67 * hash) + ((this.vertifyToken != null) ? this.vertifyToken.hashCode() : 0);
|
||||
hash = (67 * hash) + (int) (this.creationTime ^ (this.creationTime >>> 32));
|
||||
hash = (67 * hash) + (int) (this.leaseSeconds ^ (this.leaseSeconds >>> 32));
|
||||
hash = 67 * hash + (callback != null ? callback.hashCode() : 0);
|
||||
hash = 67 * hash + (secret != null ? secret.hashCode() : 0);
|
||||
hash = 67 * hash + (topic != null ? topic.hashCode() : 0);
|
||||
hash = 67 * hash + (verify != null ? verify.hashCode() : 0);
|
||||
hash = 67 * hash + (vertifyToken != null ? vertifyToken.hashCode() : 0);
|
||||
hash = 67 * hash + (int) (creationTime ^ creationTime >>> 32);
|
||||
hash = 67 * hash + (int) (leaseSeconds ^ leaseSeconds >>> 32);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
|
|
@ -20,9 +20,8 @@ package org.rometools.certiorem.hub.data;
|
|||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class SubscriptionSummary implements Serializable {
|
||||
|
@ -32,55 +31,55 @@ public class SubscriptionSummary implements Serializable {
|
|||
|
||||
/**
|
||||
* Set the value of host
|
||||
*
|
||||
*
|
||||
* @param newhost new value of host
|
||||
*/
|
||||
public void setHost(String newhost) {
|
||||
this.host = newhost;
|
||||
public void setHost(final String newhost) {
|
||||
host = newhost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of host
|
||||
*
|
||||
*
|
||||
* @return the value of host
|
||||
*/
|
||||
public String getHost() {
|
||||
return this.host;
|
||||
return host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of lastPublishSuccessful
|
||||
*
|
||||
*
|
||||
* @param newlastPublishSuccessful new value of lastPublishSuccessful
|
||||
*/
|
||||
public void setLastPublishSuccessful(boolean newlastPublishSuccessful) {
|
||||
this.lastPublishSuccessful = newlastPublishSuccessful;
|
||||
public void setLastPublishSuccessful(final boolean newlastPublishSuccessful) {
|
||||
lastPublishSuccessful = newlastPublishSuccessful;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of lastPublishSuccessful
|
||||
*
|
||||
*
|
||||
* @return the value of lastPublishSuccessful
|
||||
*/
|
||||
public boolean isLastPublishSuccessful() {
|
||||
return this.lastPublishSuccessful;
|
||||
return lastPublishSuccessful;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of subscribers
|
||||
*
|
||||
*
|
||||
* @param newsubscribers new value of subscribers
|
||||
*/
|
||||
public void setSubscribers(int newsubscribers) {
|
||||
this.subscribers = newsubscribers;
|
||||
public void setSubscribers(final int newsubscribers) {
|
||||
subscribers = newsubscribers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of subscribers
|
||||
*
|
||||
*
|
||||
* @return the value of subscribers
|
||||
*/
|
||||
public int getSubscribers() {
|
||||
return this.subscribers;
|
||||
return subscribers;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,12 +16,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem.hub.data.jpa;
|
||||
|
||||
import org.rometools.certiorem.hub.data.HubDAO;
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
@ -31,10 +27,13 @@ import javax.persistence.EntityManagerFactory;
|
|||
import javax.persistence.EntityTransaction;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.rometools.certiorem.hub.data.HubDAO;
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class JPADAO implements HubDAO {
|
||||
|
@ -48,41 +47,39 @@ public class JPADAO implements HubDAO {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Subscriber> subscribersForTopic(String topic) {
|
||||
LinkedList<JPASubscriber> result = new LinkedList<JPASubscriber>();
|
||||
EntityManager em = factory.createEntityManager();
|
||||
EntityTransaction tx = em.getTransaction();
|
||||
public List<? extends Subscriber> subscribersForTopic(final String topic) {
|
||||
final LinkedList<JPASubscriber> result = new LinkedList<JPASubscriber>();
|
||||
final EntityManager em = factory.createEntityManager();
|
||||
final EntityTransaction tx = em.getTransaction();
|
||||
tx.begin();
|
||||
|
||||
Query query = em.createNamedQuery("Subcriber.forTopic");
|
||||
final Query query = em.createNamedQuery("Subcriber.forTopic");
|
||||
query.setParameter("topic", topic);
|
||||
|
||||
try {
|
||||
for (JPASubscriber subscriber : (List<JPASubscriber>) query.getResultList()) {
|
||||
for (final JPASubscriber subscriber : (List<JPASubscriber>) query.getResultList()) {
|
||||
if (subscriber.getLeaseSeconds() == -1) {
|
||||
result.add(subscriber);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (subscriber.getSubscribedAt().getTime() < (System.currentTimeMillis() - (1000 * subscriber.getLeaseSeconds()))) {
|
||||
if (subscriber.getSubscribedAt().getTime() < System.currentTimeMillis() - 1000 * subscriber.getLeaseSeconds()) {
|
||||
subscriber.setExpired(true);
|
||||
} else {
|
||||
result.add(subscriber);
|
||||
}
|
||||
|
||||
if (subscriber.isExpired() && this.purgeExpired) {
|
||||
if (subscriber.isExpired() && purgeExpired) {
|
||||
em.remove(subscriber);
|
||||
}
|
||||
}
|
||||
} catch (NoResultException e) {
|
||||
} catch (final NoResultException e) {
|
||||
tx.rollback();
|
||||
em.close();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!tx.getRollbackOnly()) {
|
||||
tx.commit();
|
||||
} else {
|
||||
|
@ -95,12 +92,12 @@ public class JPADAO implements HubDAO {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Subscriber addSubscriber(Subscriber subscriber) {
|
||||
public Subscriber addSubscriber(final Subscriber subscriber) {
|
||||
assert subscriber != null : "Attempt to store a null subscriber";
|
||||
EntityManager em = factory.createEntityManager();
|
||||
EntityTransaction tx = em.getTransaction();
|
||||
final EntityManager em = factory.createEntityManager();
|
||||
final EntityTransaction tx = em.getTransaction();
|
||||
tx.begin();
|
||||
JPASubscriber data = new JPASubscriber();
|
||||
final JPASubscriber data = new JPASubscriber();
|
||||
data.copyFrom(subscriber);
|
||||
data.setId(UUID.randomUUID().toString());
|
||||
em.persist(data);
|
||||
|
@ -110,22 +107,22 @@ public class JPADAO implements HubDAO {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Subscriber findSubscriber(String topic, String callbackUrl) {
|
||||
public Subscriber findSubscriber(final String topic, final String callbackUrl) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSummary(String topic, SubscriptionSummary summary) {
|
||||
public void handleSummary(final String topic, final SubscriptionSummary summary) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends SubscriptionSummary> summariesForTopic(String topic) {
|
||||
public List<? extends SubscriptionSummary> summariesForTopic(final String topic) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSubscriber(String topic, String callback) {
|
||||
public void removeSubscriber(final String topic, final String callback) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,13 +16,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem.hub.data.jpa;
|
||||
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
@ -32,14 +28,14 @@ import javax.persistence.NamedQuery;
|
|||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
@Entity
|
||||
@NamedQueries({@NamedQuery(name = "Subcriber.forTopic", query = "SELECT o FROM JPASubscriber o WHERE o.topic = :topic AND o.expired = false ORDER BY o.subscribedAt")
|
||||
})
|
||||
@NamedQueries({ @NamedQuery(name = "Subcriber.forTopic", query = "SELECT o FROM JPASubscriber o WHERE o.topic = :topic AND o.expired = false ORDER BY o.subscribedAt") })
|
||||
public class JPASubscriber extends Subscriber implements Serializable {
|
||||
private Date subscribedAt = new Date();
|
||||
private String id;
|
||||
|
@ -47,65 +43,65 @@ public class JPASubscriber extends Subscriber implements Serializable {
|
|||
|
||||
/**
|
||||
* Set the value of expired
|
||||
*
|
||||
*
|
||||
* @param newexpired new value of expired
|
||||
*/
|
||||
public void setExpired(boolean newexpired) {
|
||||
this.expired = newexpired;
|
||||
public void setExpired(final boolean newexpired) {
|
||||
expired = newexpired;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of expired
|
||||
*
|
||||
*
|
||||
* @return the value of expired
|
||||
*/
|
||||
public boolean isExpired() {
|
||||
return this.expired;
|
||||
return expired;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of id
|
||||
*
|
||||
*
|
||||
* @param newid new value of id
|
||||
*/
|
||||
public void setId(String newid) {
|
||||
this.id = newid;
|
||||
public void setId(final String newid) {
|
||||
id = newid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of id
|
||||
*
|
||||
*
|
||||
* @return the value of id
|
||||
*/
|
||||
@Id
|
||||
public String getId() {
|
||||
return this.id;
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of subscribedAt
|
||||
*
|
||||
*
|
||||
* @param newsubscribedAt new value of subscribedAt
|
||||
*/
|
||||
public void setSubscribedAt(Date newsubscribedAt) {
|
||||
this.subscribedAt = newsubscribedAt;
|
||||
public void setSubscribedAt(final Date newsubscribedAt) {
|
||||
subscribedAt = newsubscribedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of subscribedAt
|
||||
*
|
||||
*
|
||||
* @return the value of subscribedAt
|
||||
*/
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
public Date getSubscribedAt() {
|
||||
return this.subscribedAt;
|
||||
return subscribedAt;
|
||||
}
|
||||
|
||||
public void copyFrom(Subscriber source) {
|
||||
this.setLeaseSeconds(source.getLeaseSeconds());
|
||||
this.setSecret(source.getSecret());
|
||||
this.setTopic(source.getTopic());
|
||||
this.setVerify(source.getVerify());
|
||||
this.setVertifyToken(source.getVertifyToken());
|
||||
public void copyFrom(final Subscriber source) {
|
||||
setLeaseSeconds(source.getLeaseSeconds());
|
||||
setSecret(source.getSecret());
|
||||
setTopic(source.getTopic());
|
||||
setVerify(source.getVerify());
|
||||
setVertifyToken(source.getVertifyToken());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,36 +18,35 @@
|
|||
|
||||
package org.rometools.certiorem.hub.data.ram;
|
||||
|
||||
import org.rometools.certiorem.hub.data.HubDAO;
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.rometools.certiorem.hub.data.HubDAO;
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||
|
||||
/**
|
||||
* A Simple In-Memory HubDAO for subscribers.
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class InMemoryHubDAO implements HubDAO {
|
||||
private ConcurrentHashMap<String, List<Subscriber>> subscribers = new ConcurrentHashMap<String, List<Subscriber>>();
|
||||
private ConcurrentHashMap<String, ConcurrentHashMap<String, SubscriptionSummary>> summaries = new ConcurrentHashMap<String, ConcurrentHashMap<String, SubscriptionSummary>>();
|
||||
private final ConcurrentHashMap<String, List<Subscriber>> subscribers = new ConcurrentHashMap<String, List<Subscriber>>();
|
||||
private final ConcurrentHashMap<String, ConcurrentHashMap<String, SubscriptionSummary>> summaries = new ConcurrentHashMap<String, ConcurrentHashMap<String, SubscriptionSummary>>();
|
||||
|
||||
@Override
|
||||
public Subscriber addSubscriber(Subscriber subscriber) {
|
||||
public Subscriber addSubscriber(final Subscriber subscriber) {
|
||||
assert subscriber != null : "Attempt to store a null subscriber";
|
||||
|
||||
List<Subscriber> subList = this.subscribers.get(subscriber.getTopic());
|
||||
List<Subscriber> subList = subscribers.get(subscriber.getTopic());
|
||||
|
||||
if (subList == null) {
|
||||
synchronized (this) {
|
||||
subList = new CopyOnWriteArrayList<Subscriber>();
|
||||
this.subscribers.put(subscriber.getTopic(), subList);
|
||||
subscribers.put(subscriber.getTopic(), subList);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,13 +56,13 @@ public class InMemoryHubDAO implements HubDAO {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void handleSummary(String topic, SubscriptionSummary summary) {
|
||||
ConcurrentHashMap<String, SubscriptionSummary> hostsToSummaries = this.summaries.get(topic);
|
||||
public void handleSummary(final String topic, final SubscriptionSummary summary) {
|
||||
ConcurrentHashMap<String, SubscriptionSummary> hostsToSummaries = summaries.get(topic);
|
||||
|
||||
if (hostsToSummaries == null) {
|
||||
synchronized (this) {
|
||||
hostsToSummaries = new ConcurrentHashMap<String, SubscriptionSummary>();
|
||||
this.summaries.put(topic, hostsToSummaries);
|
||||
summaries.put(topic, hostsToSummaries);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,14 +70,13 @@ public class InMemoryHubDAO implements HubDAO {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<?extends Subscriber> subscribersForTopic(String topic) {
|
||||
public List<? extends Subscriber> subscribersForTopic(final String topic) {
|
||||
if (subscribers.containsKey(topic)) {
|
||||
List<Subscriber> result = new LinkedList<Subscriber>();
|
||||
LinkedList<Subscriber> expired = new LinkedList<Subscriber>();
|
||||
final List<Subscriber> result = new LinkedList<Subscriber>();
|
||||
final LinkedList<Subscriber> expired = new LinkedList<Subscriber>();
|
||||
|
||||
for (Subscriber s : subscribers.get(topic)) {
|
||||
if ((s.getLeaseSeconds() > 0) &&
|
||||
(System.currentTimeMillis() >= (s.getCreationTime() + (s.getLeaseSeconds() * 1000L)))) {
|
||||
for (final Subscriber s : subscribers.get(topic)) {
|
||||
if (s.getLeaseSeconds() > 0 && System.currentTimeMillis() >= s.getCreationTime() + s.getLeaseSeconds() * 1000L) {
|
||||
expired.add(s);
|
||||
} else {
|
||||
result.add(s);
|
||||
|
@ -86,8 +84,7 @@ public class InMemoryHubDAO implements HubDAO {
|
|||
}
|
||||
|
||||
if (!expired.isEmpty()) {
|
||||
subscribers.get(topic)
|
||||
.removeAll(expired);
|
||||
subscribers.get(topic).removeAll(expired);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -97,41 +94,41 @@ public class InMemoryHubDAO implements HubDAO {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<?extends SubscriptionSummary> summariesForTopic(String topic) {
|
||||
LinkedList<SubscriptionSummary> result = new LinkedList<SubscriptionSummary>();
|
||||
public List<? extends SubscriptionSummary> summariesForTopic(final String topic) {
|
||||
final LinkedList<SubscriptionSummary> result = new LinkedList<SubscriptionSummary>();
|
||||
|
||||
if (this.summaries.containsKey(topic)) {
|
||||
result.addAll(this.summaries.get(topic).values());
|
||||
if (summaries.containsKey(topic)) {
|
||||
result.addAll(summaries.get(topic).values());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Subscriber findSubscriber(String topic, String callbackUrl) {
|
||||
public Subscriber findSubscriber(final String topic, final String callbackUrl) {
|
||||
|
||||
for (Subscriber s : this.subscribersForTopic(topic)) {
|
||||
for (final Subscriber s : subscribersForTopic(topic)) {
|
||||
if (callbackUrl.equals(s.getCallback())) {
|
||||
return s;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSubscriber(String topic, String callback) {
|
||||
List<Subscriber> subs = this.subscribers.get(topic);
|
||||
if(subs == null){
|
||||
public void removeSubscriber(final String topic, final String callback) {
|
||||
final List<Subscriber> subs = subscribers.get(topic);
|
||||
if (subs == null) {
|
||||
return;
|
||||
}
|
||||
Subscriber match = null;
|
||||
for(Subscriber s: subs){
|
||||
if(s.getCallback().equals(callback)){
|
||||
for (final Subscriber s : subs) {
|
||||
if (s.getCallback().equals(callback)) {
|
||||
match = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(match != null){
|
||||
if (match != null) {
|
||||
subs.remove(match);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,152 +16,140 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem.hub.notify.standard;
|
||||
|
||||
import com.sun.syndication.feed.synd.SyndFeed;
|
||||
import com.sun.syndication.io.FeedException;
|
||||
import com.sun.syndication.io.SyndFeedOutput;
|
||||
|
||||
import org.rometools.certiorem.hub.Notifier;
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.rometools.certiorem.sub.data.ram.InMemorySubDAO;
|
||||
|
||||
import org.rometools.certiorem.hub.Notifier;
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||
|
||||
import com.sun.syndication.feed.synd.SyndFeed;
|
||||
import com.sun.syndication.io.FeedException;
|
||||
import com.sun.syndication.io.SyndFeedOutput;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public abstract class AbstractNotifier implements Notifier {
|
||||
/**
|
||||
* This method will serialize the synd feed and build Notifications for the
|
||||
* implementation class to handle.
|
||||
* @see enqueueNotification
|
||||
*
|
||||
* This method will serialize the synd feed and build Notifications for the implementation class to handle.
|
||||
*
|
||||
* @see enqueueNotification
|
||||
*
|
||||
* @param subscribers List of subscribers to notify
|
||||
* @param value The SyndFeed object to send
|
||||
* @param callback A callback that will be invoked each time a subscriber is notified.
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void notifySubscribers(List<Subscriber> subscribers, SyndFeed value, SubscriptionSummaryCallback callback) {
|
||||
public void notifySubscribers(final List<Subscriber> subscribers, final SyndFeed value, final SubscriptionSummaryCallback callback) {
|
||||
String mimeType = null;
|
||||
|
||||
if (value.getFeedType()
|
||||
.startsWith("rss")) {
|
||||
if (value.getFeedType().startsWith("rss")) {
|
||||
mimeType = "application/rss+xml";
|
||||
} else {
|
||||
mimeType = "application/atom+xml";
|
||||
}
|
||||
|
||||
SyndFeedOutput output = new SyndFeedOutput();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
final SyndFeedOutput output = new SyndFeedOutput();
|
||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
try {
|
||||
output.output(value, new OutputStreamWriter(baos));
|
||||
baos.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(AbstractNotifier.class.getName())
|
||||
.log(Level.SEVERE, null, ex);
|
||||
} catch (final IOException ex) {
|
||||
Logger.getLogger(AbstractNotifier.class.getName()).log(Level.SEVERE, null, ex);
|
||||
throw new RuntimeException("Unable to output the feed.", ex);
|
||||
} catch (FeedException ex) {
|
||||
Logger.getLogger(AbstractNotifier.class.getName())
|
||||
.log(Level.SEVERE, null, ex);
|
||||
} catch (final FeedException ex) {
|
||||
Logger.getLogger(AbstractNotifier.class.getName()).log(Level.SEVERE, null, ex);
|
||||
throw new RuntimeException("Unable to output the feed.", ex);
|
||||
}
|
||||
|
||||
byte[] payload = baos.toByteArray();
|
||||
final byte[] payload = baos.toByteArray();
|
||||
|
||||
for (Subscriber s : subscribers) {
|
||||
Notification not = new Notification();
|
||||
for (final Subscriber s : subscribers) {
|
||||
final Notification not = new Notification();
|
||||
not.callback = callback;
|
||||
not.lastRun = 0;
|
||||
not.mimeType = mimeType;
|
||||
not.payload = payload;
|
||||
not.retryCount = 0;
|
||||
not.subscriber = s;
|
||||
this.enqueueNotification(not);
|
||||
enqueueNotification(not);
|
||||
}
|
||||
}
|
||||
/** Implementation method that queues/sends a notification
|
||||
*
|
||||
|
||||
/**
|
||||
* Implementation method that queues/sends a notification
|
||||
*
|
||||
* @param not notification to send.
|
||||
*/
|
||||
protected abstract void enqueueNotification(Notification not);
|
||||
|
||||
/**
|
||||
* POSTs the payload to the subscriber's callback and returns a
|
||||
* SubscriptionSummary with subscriber counts (where possible) and the
|
||||
* success state of the notification.
|
||||
* POSTs the payload to the subscriber's callback and returns a SubscriptionSummary with subscriber counts (where possible) and the success state of the
|
||||
* notification.
|
||||
*
|
||||
* @param subscriber subscriber data.
|
||||
* @param mimeType MIME type for the request
|
||||
* @param payload payload of the feed to send
|
||||
* @return SubscriptionSummary with the returned data.
|
||||
*/
|
||||
protected SubscriptionSummary postNotification(Subscriber subscriber, String mimeType, byte[] payload) {
|
||||
SubscriptionSummary result = new SubscriptionSummary();
|
||||
protected SubscriptionSummary postNotification(final Subscriber subscriber, final String mimeType, final byte[] payload) {
|
||||
final SubscriptionSummary result = new SubscriptionSummary();
|
||||
|
||||
try {
|
||||
URL target = new URL(subscriber.getCallback());
|
||||
final URL target = new URL(subscriber.getCallback());
|
||||
Logger.getLogger(AbstractNotifier.class.getName()).log(Level.INFO, "Posting notification to subscriber {0}", subscriber.getCallback());
|
||||
result.setHost(target.getHost());
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) target.openConnection();
|
||||
final HttpURLConnection connection = (HttpURLConnection) target.openConnection();
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setRequestProperty("Content-Type", mimeType);
|
||||
connection.setDoOutput(true);
|
||||
connection.connect();
|
||||
|
||||
OutputStream os = connection.getOutputStream();
|
||||
final OutputStream os = connection.getOutputStream();
|
||||
os.write(payload);
|
||||
os.close();
|
||||
|
||||
int responseCode = connection.getResponseCode();
|
||||
String subscribers = connection.getHeaderField("X-Hub-On-Behalf-Of");
|
||||
final int responseCode = connection.getResponseCode();
|
||||
final String subscribers = connection.getHeaderField("X-Hub-On-Behalf-Of");
|
||||
connection.disconnect();
|
||||
|
||||
|
||||
if (responseCode != 200) {
|
||||
Logger.getLogger(AbstractNotifier.class.getName())
|
||||
.log(Level.WARNING, "Got code " + responseCode + " from " + target);
|
||||
Logger.getLogger(AbstractNotifier.class.getName()).log(Level.WARNING, "Got code " + responseCode + " from " + target);
|
||||
result.setLastPublishSuccessful(false);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (subscribers != null) {
|
||||
try {
|
||||
result.setSubscribers(Integer.parseInt(subscribers));
|
||||
} catch (NumberFormatException nfe) {
|
||||
Logger.getLogger(AbstractNotifier.class.getName())
|
||||
.log(Level.WARNING, "Invalid subscriber value " + subscribers + " " + target, nfe);
|
||||
} catch (final NumberFormatException nfe) {
|
||||
Logger.getLogger(AbstractNotifier.class.getName()).log(Level.WARNING, "Invalid subscriber value " + subscribers + " " + target, nfe);
|
||||
result.setSubscribers(-1);
|
||||
}
|
||||
} else {
|
||||
result.setSubscribers(-1);
|
||||
}
|
||||
} catch (MalformedURLException ex) {
|
||||
Logger.getLogger(AbstractNotifier.class.getName())
|
||||
.log(Level.WARNING, null, ex);
|
||||
} catch (final MalformedURLException ex) {
|
||||
Logger.getLogger(AbstractNotifier.class.getName()).log(Level.WARNING, null, ex);
|
||||
result.setLastPublishSuccessful(false);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(AbstractNotifier.class.getName())
|
||||
.log(Level.SEVERE, null, ex);
|
||||
} catch (final IOException ex) {
|
||||
Logger.getLogger(AbstractNotifier.class.getName()).log(Level.SEVERE, null, ex);
|
||||
result.setLastPublishSuccessful(false);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,14 +16,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem.hub.notify.standard;
|
||||
|
||||
import org.rometools.certiorem.hub.Notifier.SubscriptionSummaryCallback;
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class Notification {
|
||||
|
|
|
@ -16,11 +16,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem.hub.notify.standard;
|
||||
|
||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
|
@ -28,11 +25,11 @@ import java.util.concurrent.LinkedBlockingQueue;
|
|||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||
|
||||
/**
|
||||
* A notifier implementation that uses a thread pool to deliver notifications to
|
||||
* subscribers
|
||||
*
|
||||
* A notifier implementation that uses a thread pool to deliver notifications to subscribers
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class ThreadPoolNotifier extends AbstractNotifier {
|
||||
|
@ -45,47 +42,47 @@ public class ThreadPoolNotifier extends AbstractNotifier {
|
|||
this(2, 5, 5);
|
||||
}
|
||||
|
||||
public ThreadPoolNotifier(int startPoolSize, int maxPoolSize, int queueSize) {
|
||||
this.exeuctor = new ThreadPoolExecutor(startPoolSize, maxPoolSize, 300, TimeUnit.SECONDS,
|
||||
new LinkedBlockingQueue<Runnable>(queueSize));
|
||||
public ThreadPoolNotifier(final int startPoolSize, final int maxPoolSize, final int queueSize) {
|
||||
exeuctor = new ThreadPoolExecutor(startPoolSize, maxPoolSize, 300, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(queueSize));
|
||||
}
|
||||
|
||||
protected ThreadPoolNotifier(final ThreadPoolExecutor executor) {
|
||||
this.exeuctor = executor;
|
||||
exeuctor = executor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues a notification to run. If the notification fails, it will be
|
||||
* retried every two minutes until 5 attempts are completed. Notifications
|
||||
* to the same callback should be delivered successfully in order.
|
||||
* Enqueues a notification to run. If the notification fails, it will be retried every two minutes until 5 attempts are completed. Notifications to the same
|
||||
* callback should be delivered successfully in order.
|
||||
*
|
||||
* @param not
|
||||
*/
|
||||
@Override
|
||||
protected void enqueueNotification(final Notification not) {
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
not.lastRun = System.currentTimeMillis();
|
||||
final Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
not.lastRun = System.currentTimeMillis();
|
||||
|
||||
SubscriptionSummary summary = postNotification(not.subscriber, not.mimeType, not.payload);
|
||||
final SubscriptionSummary summary = postNotification(not.subscriber, not.mimeType, not.payload);
|
||||
|
||||
if (!summary.isLastPublishSuccessful()) {
|
||||
not.retryCount++;
|
||||
if (!summary.isLastPublishSuccessful()) {
|
||||
not.retryCount++;
|
||||
|
||||
if (not.retryCount <= 5) {
|
||||
retry(not);
|
||||
}
|
||||
if (not.retryCount <= 5) {
|
||||
retry(not);
|
||||
}
|
||||
|
||||
not.callback.onSummaryInfo(summary);
|
||||
}
|
||||
};
|
||||
|
||||
this.exeuctor.execute(r);
|
||||
not.callback.onSummaryInfo(summary);
|
||||
}
|
||||
};
|
||||
|
||||
exeuctor.execute(r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a notification to retry in two minutes.
|
||||
*
|
||||
* @param not Notification to retry
|
||||
*/
|
||||
protected void retry(final Notification not) {
|
||||
|
@ -94,21 +91,21 @@ public class ThreadPoolNotifier extends AbstractNotifier {
|
|||
// will schedule the retry
|
||||
pendings.add(not.subscriber.getCallback());
|
||||
timer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
pendings.remove(not.subscriber.getCallback());
|
||||
enqueueNotification(not);
|
||||
}
|
||||
}, TWO_MINUTES);
|
||||
@Override
|
||||
public void run() {
|
||||
pendings.remove(not.subscriber.getCallback());
|
||||
enqueueNotification(not);
|
||||
}
|
||||
}, TWO_MINUTES);
|
||||
} else {
|
||||
// There is a retry in front of this one, so we will just schedule
|
||||
// it to retry again in a bit
|
||||
timer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
retry(not);
|
||||
}
|
||||
}, TWO_MINUTES);
|
||||
@Override
|
||||
public void run() {
|
||||
retry(not);
|
||||
}
|
||||
}, TWO_MINUTES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,32 +18,30 @@
|
|||
|
||||
package org.rometools.certiorem.hub.notify.standard;
|
||||
|
||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
|
||||
import org.rometools.certiorem.hub.data.SubscriptionSummary;
|
||||
|
||||
/**
|
||||
* A notifier that does not use threads. All calls are blocking and synchronous.
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class UnthreadedNotifier extends AbstractNotifier {
|
||||
private final ConcurrentSkipListSet<Notification> retries = new ConcurrentSkipListSet<Notification>();
|
||||
|
||||
/**
|
||||
* A blocking call that performs a notification.
|
||||
* If there are pending retries that are older than two minutes old, they will
|
||||
* be retried before the method returns.
|
||||
*
|
||||
* A blocking call that performs a notification. If there are pending retries that are older than two minutes old, they will be retried before the method
|
||||
* returns.
|
||||
*
|
||||
* @param not
|
||||
*/
|
||||
@Override
|
||||
protected void enqueueNotification(Notification not) {
|
||||
protected void enqueueNotification(final Notification not) {
|
||||
not.lastRun = System.currentTimeMillis();
|
||||
|
||||
SubscriptionSummary summary = postNotification(not.subscriber, not.mimeType, not.payload);
|
||||
|
||||
final SubscriptionSummary summary = postNotification(not.subscriber, not.mimeType, not.payload);
|
||||
|
||||
not.callback.onSummaryInfo(summary);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,91 +16,77 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem.hub.verify.standard;
|
||||
|
||||
import org.rometools.certiorem.hub.Verifier;
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.rometools.certiorem.hub.Verifier;
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
|
||||
/**
|
||||
* An abstract verifier based on the java.net HTTP classes. This implements only
|
||||
* synchronous operations, and expects a child class to do Async ops.
|
||||
* An abstract verifier based on the java.net HTTP classes. This implements only synchronous operations, and expects a child class to do Async ops.
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public abstract class AbstractVerifier implements Verifier {
|
||||
@Override
|
||||
public boolean verifySubcribeSyncronously(Subscriber subscriber) {
|
||||
public boolean verifySubcribeSyncronously(final Subscriber subscriber) {
|
||||
return doOp(Verifier.MODE_SUBSCRIBE, subscriber);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifyUnsubcribeSyncronously(Subscriber subscriber) {
|
||||
public boolean verifyUnsubcribeSyncronously(final Subscriber subscriber) {
|
||||
return doOp(Verifier.MODE_UNSUBSCRIBE, subscriber);
|
||||
}
|
||||
|
||||
private boolean doOp(String mode, Subscriber subscriber){
|
||||
private boolean doOp(final String mode, final Subscriber subscriber) {
|
||||
try {
|
||||
String challenge = UUID.randomUUID()
|
||||
.toString();
|
||||
StringBuilder queryString = new StringBuilder();
|
||||
queryString.append("hub.mode=")
|
||||
.append(mode)
|
||||
.append("&hub.topic=")
|
||||
.append(URLEncoder.encode(subscriber.getTopic(), "UTF-8"))
|
||||
.append("&hub.challenge=")
|
||||
.append(challenge);
|
||||
final String challenge = UUID.randomUUID().toString();
|
||||
final StringBuilder queryString = new StringBuilder();
|
||||
queryString.append("hub.mode=").append(mode).append("&hub.topic=").append(URLEncoder.encode(subscriber.getTopic(), "UTF-8"))
|
||||
.append("&hub.challenge=").append(challenge);
|
||||
|
||||
if (subscriber.getLeaseSeconds() != -1) {
|
||||
queryString.append("&hub.lease_seconds=")
|
||||
.append(subscriber.getLeaseSeconds());
|
||||
queryString.append("&hub.lease_seconds=").append(subscriber.getLeaseSeconds());
|
||||
}
|
||||
|
||||
if (subscriber.getVertifyToken() != null) {
|
||||
queryString.append("&hub.verify_token=")
|
||||
.append(URLEncoder.encode(subscriber.getVertifyToken(), "UTF-8"));
|
||||
queryString.append("&hub.verify_token=").append(URLEncoder.encode(subscriber.getVertifyToken(), "UTF-8"));
|
||||
}
|
||||
|
||||
URL url = new URL(subscriber.getCallback() + "?" + queryString.toString());
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
final URL url = new URL(subscriber.getCallback() + "?" + queryString.toString());
|
||||
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setDoInput(true);
|
||||
// connection.setRequestProperty("Host", url.getHost());
|
||||
// connection.setRequestProperty("Port", Integer.toString(url.getPort()));
|
||||
// connection.setRequestProperty("Host", url.getHost());
|
||||
// connection.setRequestProperty("Port", Integer.toString(url.getPort()));
|
||||
connection.setRequestProperty("User-Agent", "ROME-Certiorem");
|
||||
connection.connect();
|
||||
int rc = connection.getResponseCode();
|
||||
InputStream is = connection.getInputStream();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
||||
String result = reader.readLine();
|
||||
final int rc = connection.getResponseCode();
|
||||
final InputStream is = connection.getInputStream();
|
||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
||||
final String result = reader.readLine();
|
||||
reader.close();
|
||||
connection.disconnect();
|
||||
if ((rc != 200) || !challenge.equals(result.trim())) {
|
||||
if (rc != 200 || !challenge.equals(result.trim())) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
Logger.getLogger(AbstractVerifier.class.getName())
|
||||
.log(Level.SEVERE, null, ex);
|
||||
} catch (final UnsupportedEncodingException ex) {
|
||||
Logger.getLogger(AbstractVerifier.class.getName()).log(Level.SEVERE, null, ex);
|
||||
throw new RuntimeException("Should not happen. UTF-8 threw unsupported encoding", ex);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(AbstractVerifier.class.getName())
|
||||
.log(Level.SEVERE, null, ex);
|
||||
} catch (final IOException ex) {
|
||||
Logger.getLogger(AbstractVerifier.class.getName()).log(Level.SEVERE, null, ex);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -16,53 +16,51 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem.hub.verify.standard;
|
||||
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
|
||||
/**
|
||||
* Uses a ThreadPoolExecutor to do async verifications.
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class ThreadPoolVerifier extends AbstractVerifier {
|
||||
protected final ThreadPoolExecutor exeuctor;
|
||||
|
||||
protected ThreadPoolVerifier(final ThreadPoolExecutor executor){
|
||||
this.exeuctor = executor;
|
||||
protected ThreadPoolVerifier(final ThreadPoolExecutor executor) {
|
||||
exeuctor = executor;
|
||||
}
|
||||
|
||||
|
||||
public ThreadPoolVerifier() {
|
||||
this(2, 5, 5);
|
||||
}
|
||||
|
||||
public ThreadPoolVerifier(int startPoolSize, int maxPoolSize, int queueSize) {
|
||||
this.exeuctor = new ThreadPoolExecutor(startPoolSize, maxPoolSize, 300, TimeUnit.SECONDS,
|
||||
new LinkedBlockingQueue<Runnable>(queueSize));
|
||||
public ThreadPoolVerifier(final int startPoolSize, final int maxPoolSize, final int queueSize) {
|
||||
exeuctor = new ThreadPoolExecutor(startPoolSize, maxPoolSize, 300, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(queueSize));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verifySubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||
this.exeuctor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
callback.onVerify(verifySubcribeSyncronously(subscriber));
|
||||
}
|
||||
});
|
||||
exeuctor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
callback.onVerify(verifySubcribeSyncronously(subscriber));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verifyUnsubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||
this.exeuctor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
callback.onVerify(verifyUnsubcribeSyncronously(subscriber));
|
||||
}
|
||||
});
|
||||
exeuctor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
callback.onVerify(verifyUnsubcribeSyncronously(subscriber));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,12 +21,12 @@ package org.rometools.certiorem.hub.verify.standard;
|
|||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class ThreadpoolVerifierAdvanced extends ThreadPoolVerifier{
|
||||
public class ThreadpoolVerifierAdvanced extends ThreadPoolVerifier {
|
||||
|
||||
public ThreadpoolVerifierAdvanced(ThreadPoolExecutor executor){
|
||||
public ThreadpoolVerifierAdvanced(final ThreadPoolExecutor executor) {
|
||||
super(executor);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,25 +16,24 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package org.rometools.certiorem.hub.verify.standard;
|
||||
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
|
||||
/**
|
||||
* A verifier that does not use threads. Suitable for Google App Engine.
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class UnthreadedVerifier extends AbstractVerifier{
|
||||
public class UnthreadedVerifier extends AbstractVerifier {
|
||||
|
||||
@Override
|
||||
public void verifySubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback) {
|
||||
public void verifySubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||
callback.onVerify(verifySubcribeSyncronously(subscriber));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verifyUnsubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback) {
|
||||
public void verifyUnsubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||
callback.onVerify(verifyUnsubcribeSyncronously(subscriber));
|
||||
}
|
||||
|
||||
|
|
|
@ -16,20 +16,19 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem.pub;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class NotificationException extends Exception {
|
||||
|
||||
public NotificationException(String message){
|
||||
public NotificationException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public NotificationException(String message, Throwable cause){
|
||||
public NotificationException(final String message, final Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,28 +16,24 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem.pub;
|
||||
|
||||
import com.sun.syndication.feed.synd.SyndFeed;
|
||||
import com.sun.syndication.feed.synd.SyndLink;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sun.syndication.feed.synd.SyndFeed;
|
||||
import com.sun.syndication.feed.synd.SyndLink;
|
||||
|
||||
/**
|
||||
* A class for sending update notifications to a hub.
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class Publisher {
|
||||
|
@ -52,61 +48,57 @@ public class Publisher {
|
|||
/**
|
||||
* Constructs a new publisher with an optional ThreadPoolExector for sending updates.
|
||||
*/
|
||||
public Publisher(ThreadPoolExecutor executor) {
|
||||
public Publisher(final ThreadPoolExecutor executor) {
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the HUB url a notification of a change in topic
|
||||
*
|
||||
* @param hub URL of the hub to notify.
|
||||
* @param topic The Topic that has changed
|
||||
* @param topic The Topic that has changed
|
||||
* @throws NotificationException Any failure
|
||||
*/
|
||||
public void sendUpdateNotification(String hub, String topic)
|
||||
throws NotificationException {
|
||||
public void sendUpdateNotification(final String hub, final String topic) throws NotificationException {
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder("hub.mode=publish&hub.url=").append(URLEncoder.encode(topic, "UTF-8"));
|
||||
URL hubUrl = new URL(hub);
|
||||
HttpURLConnection connection = (HttpURLConnection) hubUrl.openConnection();
|
||||
// connection.setRequestProperty("Host", hubUrl.getHost());
|
||||
final StringBuilder sb = new StringBuilder("hub.mode=publish&hub.url=").append(URLEncoder.encode(topic, "UTF-8"));
|
||||
final URL hubUrl = new URL(hub);
|
||||
final HttpURLConnection connection = (HttpURLConnection) hubUrl.openConnection();
|
||||
// connection.setRequestProperty("Host", hubUrl.getHost());
|
||||
connection.setRequestProperty("User-Agent", "ROME-Certiorem");
|
||||
connection.setRequestProperty("ContentType", "application/x-www-form-urlencoded");
|
||||
connection.setDoOutput(true);
|
||||
connection.connect();
|
||||
|
||||
OutputStream os = connection.getOutputStream();
|
||||
final OutputStream os = connection.getOutputStream();
|
||||
os.write(sb.toString().getBytes("UTF-8"));
|
||||
os.close();
|
||||
|
||||
int rc = connection.getResponseCode();
|
||||
final int rc = connection.getResponseCode();
|
||||
connection.disconnect();
|
||||
|
||||
|
||||
if (rc != 204) {
|
||||
throw new NotificationException("Server returned an unexcepted response code: " + rc + " " +
|
||||
connection.getResponseMessage());
|
||||
throw new NotificationException("Server returned an unexcepted response code: " + rc + " " + connection.getResponseMessage());
|
||||
}
|
||||
|
||||
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
Logger.getLogger(Publisher.class.getName())
|
||||
.log(Level.SEVERE, null, ex);
|
||||
} catch (final UnsupportedEncodingException ex) {
|
||||
Logger.getLogger(Publisher.class.getName()).log(Level.SEVERE, null, ex);
|
||||
throw new NotificationException("Could not encode URL", ex);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(Publisher.class.getName())
|
||||
.log(Level.SEVERE, null, ex);
|
||||
} catch (final IOException ex) {
|
||||
Logger.getLogger(Publisher.class.getName()).log(Level.SEVERE, null, ex);
|
||||
throw new NotificationException("Unable to communicate with " + hub, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a notification for a feed located at "topic". The feed MUST contain rel="hub".
|
||||
*
|
||||
* @param topic URL for the feed
|
||||
* @param feed The feed itself
|
||||
* @throws NotificationException Any failure
|
||||
*/
|
||||
public void sendUpdateNotification(String topic, SyndFeed feed)
|
||||
throws NotificationException {
|
||||
for (SyndLink link : (List<SyndLink>) feed.getLinks()) {
|
||||
public void sendUpdateNotification(final String topic, final SyndFeed feed) throws NotificationException {
|
||||
for (final SyndLink link : feed.getLinks()) {
|
||||
if ("hub".equals(link.getRel())) {
|
||||
sendUpdateNotification(link.getRel(), topic);
|
||||
|
||||
|
@ -118,14 +110,15 @@ public class Publisher {
|
|||
|
||||
/**
|
||||
* Sends a notification for a feed. The feed MUST contain rel="hub" and rel="self" links.
|
||||
*
|
||||
* @param feed The feed to notify
|
||||
* @throws NotificationException Any failure
|
||||
*/
|
||||
public void sendUpdateNotification(SyndFeed feed) throws NotificationException {
|
||||
public void sendUpdateNotification(final SyndFeed feed) throws NotificationException {
|
||||
SyndLink hub = null;
|
||||
SyndLink self = null;
|
||||
|
||||
for (SyndLink link : (List<SyndLink>) feed.getLinks()) {
|
||||
for (final SyndLink link : feed.getLinks()) {
|
||||
if ("hub".equals(link.getRel())) {
|
||||
hub = link;
|
||||
}
|
||||
|
@ -134,7 +127,7 @@ public class Publisher {
|
|||
self = link;
|
||||
}
|
||||
|
||||
if ((hub != null) && (self != null)) {
|
||||
if (hub != null && self != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -152,27 +145,27 @@ public class Publisher {
|
|||
|
||||
/**
|
||||
* Sends the HUB url a notification of a change in topic asynchronously
|
||||
*
|
||||
* @param hub URL of the hub to notify.
|
||||
* @param topic The Topic that has changed
|
||||
* @param callback A callback invoked when the notification completes.
|
||||
* @param topic The Topic that has changed
|
||||
* @param callback A callback invoked when the notification completes.
|
||||
* @throws NotificationException Any failure
|
||||
*/
|
||||
public void sendUpdateNotificationAsyncronously(final String hub, final String topic,
|
||||
final AsyncNotificationCallback callback) {
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sendUpdateNotification(hub, topic);
|
||||
callback.onSuccess();
|
||||
} catch (Throwable t) {
|
||||
callback.onFailure(t);
|
||||
}
|
||||
public void sendUpdateNotificationAsyncronously(final String hub, final String topic, final AsyncNotificationCallback callback) {
|
||||
final Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sendUpdateNotification(hub, topic);
|
||||
callback.onSuccess();
|
||||
} catch (final Throwable t) {
|
||||
callback.onFailure(t);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
if (this.executor != null) {
|
||||
this.executor.execute(r);
|
||||
if (executor != null) {
|
||||
executor.execute(r);
|
||||
} else {
|
||||
new Thread(r).start();
|
||||
}
|
||||
|
@ -180,66 +173,70 @@ public class Publisher {
|
|||
|
||||
/**
|
||||
* Asynchronously sends a notification for a feed located at "topic". The feed MUST contain rel="hub".
|
||||
*
|
||||
* @param topic URL for the feed
|
||||
* @param feed The feed itself
|
||||
* @param callback A callback invoked when the notification completes.
|
||||
* @param callback A callback invoked when the notification completes.
|
||||
* @throws NotificationException Any failure
|
||||
*/
|
||||
public void sendUpdateNotificationAsyncronously(final String topic, final SyndFeed feed,
|
||||
final AsyncNotificationCallback callback) {
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sendUpdateNotification(topic, feed);
|
||||
callback.onSuccess();
|
||||
} catch (Throwable t) {
|
||||
callback.onFailure(t);
|
||||
}
|
||||
public void sendUpdateNotificationAsyncronously(final String topic, final SyndFeed feed, final AsyncNotificationCallback callback) {
|
||||
final Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sendUpdateNotification(topic, feed);
|
||||
callback.onSuccess();
|
||||
} catch (final Throwable t) {
|
||||
callback.onFailure(t);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
if (this.executor != null) {
|
||||
this.executor.execute(r);
|
||||
if (executor != null) {
|
||||
executor.execute(r);
|
||||
} else {
|
||||
new Thread(r).start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asyncronously sends a notification for a feed. The feed MUST contain rel="hub" and rel="self" links.
|
||||
* Asyncronously sends a notification for a feed. The feed MUST contain rel="hub" and rel="self" links.
|
||||
*
|
||||
* @param feed The feed to notify
|
||||
* @param callback A callback invoked when the notification completes.
|
||||
* @param callback A callback invoked when the notification completes.
|
||||
* @throws NotificationException Any failure
|
||||
*/
|
||||
public void sendUpdateNotificationAsyncronously(final SyndFeed feed, final AsyncNotificationCallback callback) {
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sendUpdateNotification(feed);
|
||||
callback.onSuccess();
|
||||
} catch (Throwable t) {
|
||||
callback.onFailure(t);
|
||||
}
|
||||
final Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sendUpdateNotification(feed);
|
||||
callback.onSuccess();
|
||||
} catch (final Throwable t) {
|
||||
callback.onFailure(t);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
if (this.executor != null) {
|
||||
this.executor.execute(r);
|
||||
if (executor != null) {
|
||||
executor.execute(r);
|
||||
} else {
|
||||
new Thread(r).start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A callback interface for asynchronous notifications.
|
||||
*/
|
||||
public static interface AsyncNotificationCallback {
|
||||
/**
|
||||
* Called when a notification fails
|
||||
*
|
||||
* @param thrown Whatever was thrown during the failure
|
||||
*/
|
||||
public void onFailure(Throwable thrown);
|
||||
|
||||
/**
|
||||
* Invoked with the asyncronous notification completes successfully.
|
||||
*/
|
||||
|
|
|
@ -20,17 +20,15 @@ package org.rometools.certiorem.sub;
|
|||
|
||||
import org.rometools.certiorem.sub.data.Subscription;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public interface Requester {
|
||||
public void sendSubscribeRequest(String hubUrl, Subscription subscription, String verifySync, long leaseSeconds,
|
||||
String secret, String callbackUrl, RequestCallback callback);
|
||||
public void sendSubscribeRequest(String hubUrl, Subscription subscription, String verifySync, long leaseSeconds, String secret, String callbackUrl,
|
||||
RequestCallback callback);
|
||||
|
||||
public void sendUnsubscribeRequest(String hubUrl, Subscription subscription, String verifySync, String secret,
|
||||
String callbackUrl, RequestCallback callback);
|
||||
public void sendUnsubscribeRequest(String hubUrl, Subscription subscription, String verifySync, String secret, String callbackUrl, RequestCallback callback);
|
||||
|
||||
public static interface RequestCallback {
|
||||
public void onFailure(Exception e);
|
||||
|
|
|
@ -18,104 +18,95 @@
|
|||
|
||||
package org.rometools.certiorem.sub;
|
||||
|
||||
import com.sun.syndication.feed.synd.SyndFeed;
|
||||
import com.sun.syndication.feed.synd.SyndLink;
|
||||
import com.sun.syndication.io.FeedException;
|
||||
import com.sun.syndication.io.SyndFeedInput;
|
||||
|
||||
import org.rometools.certiorem.HttpStatusCodeException;
|
||||
import org.rometools.certiorem.sub.Requester.RequestCallback;
|
||||
import org.rometools.certiorem.sub.data.SubDAO;
|
||||
import org.rometools.certiorem.sub.data.Subscription;
|
||||
|
||||
import org.rometools.fetcher.impl.FeedFetcherCache;
|
||||
import org.rometools.fetcher.impl.SyndFeedInfo;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.rometools.certiorem.sub.data.SubscriptionCallback;
|
||||
|
||||
import org.rometools.certiorem.HttpStatusCodeException;
|
||||
import org.rometools.certiorem.sub.Requester.RequestCallback;
|
||||
import org.rometools.certiorem.sub.data.SubDAO;
|
||||
import org.rometools.certiorem.sub.data.Subscription;
|
||||
import org.rometools.certiorem.sub.data.SubscriptionCallback;
|
||||
import org.rometools.fetcher.impl.FeedFetcherCache;
|
||||
import org.rometools.fetcher.impl.SyndFeedInfo;
|
||||
|
||||
import com.sun.syndication.feed.synd.SyndFeed;
|
||||
import com.sun.syndication.feed.synd.SyndLink;
|
||||
import com.sun.syndication.io.FeedException;
|
||||
import com.sun.syndication.io.SyndFeedInput;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class Subscriptions {
|
||||
//TODO unsubscribe.
|
||||
// TODO unsubscribe.
|
||||
private FeedFetcherCache cache;
|
||||
private Requester requester;
|
||||
private String callbackPrefix;
|
||||
private SubDAO dao;
|
||||
|
||||
public Subscriptions() {
|
||||
public Subscriptions() {
|
||||
}
|
||||
|
||||
public Subscriptions(final FeedFetcherCache cache, final Requester requester, final String callbackPrefix,
|
||||
final SubDAO dao) {
|
||||
|
||||
public Subscriptions(final FeedFetcherCache cache, final Requester requester, final String callbackPrefix, final SubDAO dao) {
|
||||
this.cache = cache;
|
||||
this.requester = requester;
|
||||
this.callbackPrefix = callbackPrefix;
|
||||
this.dao = dao;
|
||||
}
|
||||
|
||||
public void callback(String callbackPath, String feed) {
|
||||
public void callback(final String callbackPath, final String feed) {
|
||||
try {
|
||||
this.callback(callbackPath, feed.getBytes("UTF-8"));
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
Logger.getLogger(Subscriptions.class.getName())
|
||||
.log(Level.SEVERE, null, ex);
|
||||
} catch (final UnsupportedEncodingException ex) {
|
||||
Logger.getLogger(Subscriptions.class.getName()).log(Level.SEVERE, null, ex);
|
||||
throw new HttpStatusCodeException(400, "Unable to parse feed.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void callback(String callbackPath, InputStream feed) {
|
||||
SyndFeedInput input = new SyndFeedInput();
|
||||
public void callback(final String callbackPath, final InputStream feed) {
|
||||
final SyndFeedInput input = new SyndFeedInput();
|
||||
|
||||
try {
|
||||
this.callback(callbackPath, input.build(new InputStreamReader(feed)));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
Logger.getLogger(Subscriptions.class.getName())
|
||||
.log(Level.SEVERE, null, ex);
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
Logger.getLogger(Subscriptions.class.getName()).log(Level.SEVERE, null, ex);
|
||||
throw new HttpStatusCodeException(500, "Unable to parse feed.", ex);
|
||||
} catch (FeedException ex) {
|
||||
Logger.getLogger(Subscriptions.class.getName())
|
||||
.log(Level.SEVERE, null, ex);
|
||||
} catch (final FeedException ex) {
|
||||
Logger.getLogger(Subscriptions.class.getName()).log(Level.SEVERE, null, ex);
|
||||
throw new HttpStatusCodeException(400, "Unable to parse feed.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void callback(String callbackPath, byte[] feed) {
|
||||
public void callback(final String callbackPath, final byte[] feed) {
|
||||
this.callback(callbackPath, new ByteArrayInputStream(feed));
|
||||
}
|
||||
|
||||
public void callback(String callbackPath, SyndFeed feed) {
|
||||
public void callback(final String callbackPath, final SyndFeed feed) {
|
||||
|
||||
if (!callbackPath.startsWith(callbackPrefix)) {
|
||||
throw new HttpStatusCodeException(404, "Not a valid callback prefix.", new Exception(callbackPath+" doesnt start with "+callbackPrefix));
|
||||
throw new HttpStatusCodeException(404, "Not a valid callback prefix.", new Exception(callbackPath + " doesnt start with " + callbackPrefix));
|
||||
}
|
||||
|
||||
String id = callbackPath.substring(callbackPrefix.length());
|
||||
final String id = callbackPath.substring(callbackPrefix.length());
|
||||
Logger.getLogger(Subscriptions.class.getName()).log(Level.FINE, "Got callback for {0}", id);
|
||||
Subscription s = dao.findById(id);
|
||||
final Subscription s = dao.findById(id);
|
||||
|
||||
if (s == null) {
|
||||
throw new HttpStatusCodeException(404, "Not a valid callback.", null);
|
||||
}
|
||||
|
||||
this.validateLink(feed, s.getSourceUrl());
|
||||
validateLink(feed, s.getSourceUrl());
|
||||
|
||||
SyndFeedInfo info = null;
|
||||
URL url = null;
|
||||
|
@ -123,9 +114,8 @@ public class Subscriptions {
|
|||
try {
|
||||
url = new URL(s.getSourceUrl());
|
||||
info = cache.getFeedInfo(url);
|
||||
} catch (MalformedURLException ex) {
|
||||
Logger.getLogger(Subscriptions.class.getName())
|
||||
.log(Level.SEVERE, null, ex);
|
||||
} catch (final MalformedURLException ex) {
|
||||
Logger.getLogger(Subscriptions.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
if (info == null) {
|
||||
|
@ -141,58 +131,53 @@ public class Subscriptions {
|
|||
s.getCallback().onNotify(s, info);
|
||||
}
|
||||
|
||||
public void unsubscribe(final Subscription subscription, String hubUrl, boolean sync, String secret,
|
||||
final SubscriptionCallback callback) {
|
||||
public void unsubscribe(final Subscription subscription, final String hubUrl, final boolean sync, final String secret, final SubscriptionCallback callback) {
|
||||
|
||||
subscription.setUnsubscribed(true);
|
||||
this.requester.sendUnsubscribeRequest(hubUrl, subscription, (sync ? "sync" : "async"), secret,
|
||||
this.callbackPrefix + subscription.getId(),
|
||||
new RequestCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
callback.onUnsubscribe(subscription);
|
||||
}
|
||||
requester.sendUnsubscribeRequest(hubUrl, subscription, sync ? "sync" : "async", secret, callbackPrefix + subscription.getId(), new RequestCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
callback.onUnsubscribe(subscription);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
callback.onFailure(e);
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public void onFailure(final Exception e) {
|
||||
callback.onFailure(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void subscribe(String hubUrl, String topic, boolean sync, long leaseSeconds, String secret,
|
||||
final SubscriptionCallback callback) {
|
||||
Subscription s = new Subscription();
|
||||
|
||||
public void subscribe(final String hubUrl, final String topic, final boolean sync, final long leaseSeconds, final String secret,
|
||||
final SubscriptionCallback callback) {
|
||||
final Subscription s = new Subscription();
|
||||
s.setId(UUID.randomUUID().toString());
|
||||
s.setVerifyToken(UUID.randomUUID().toString());
|
||||
s.setSourceUrl(topic);
|
||||
s.setCallback(callback);
|
||||
if (leaseSeconds > 0) {
|
||||
s.setExpirationTime(System.currentTimeMillis() + (leaseSeconds * 1000));
|
||||
s.setExpirationTime(System.currentTimeMillis() + leaseSeconds * 1000);
|
||||
}
|
||||
|
||||
final Subscription stored = this.dao.addSubscription(s);
|
||||
final Subscription stored = dao.addSubscription(s);
|
||||
|
||||
this.requester.sendSubscribeRequest(hubUrl, stored, (sync ? "sync" : "async"), leaseSeconds, secret,
|
||||
this.callbackPrefix + stored.getId(),
|
||||
new RequestCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
callback.onSubscribe(stored);
|
||||
}
|
||||
requester.sendSubscribeRequest(hubUrl, stored, sync ? "sync" : "async", leaseSeconds, secret, callbackPrefix + stored.getId(), new RequestCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
callback.onSubscribe(stored);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
callback.onFailure(e);
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public void onFailure(final Exception e) {
|
||||
callback.onFailure(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void subscribe(String topic, boolean sync, long leaseSeconds, String secret,
|
||||
final SubscriptionCallback callback) throws IllegalArgumentException, IOException, FeedException {
|
||||
SyndFeedInput input = new SyndFeedInput();
|
||||
SyndFeed feed = input.build(new InputStreamReader(new URL(topic).openStream()));
|
||||
String hubUrl = this.findHubUrl(feed);
|
||||
public void subscribe(final String topic, final boolean sync, final long leaseSeconds, final String secret, final SubscriptionCallback callback)
|
||||
throws IllegalArgumentException, IOException, FeedException {
|
||||
final SyndFeedInput input = new SyndFeedInput();
|
||||
final SyndFeed feed = input.build(new InputStreamReader(new URL(topic).openStream()));
|
||||
final String hubUrl = findHubUrl(feed);
|
||||
|
||||
if (hubUrl == null) {
|
||||
throw new FeedException("No hub link");
|
||||
|
@ -201,20 +186,19 @@ public class Subscriptions {
|
|||
this.subscribe(hubUrl, topic, sync, leaseSeconds, secret, callback);
|
||||
}
|
||||
|
||||
public String validate(String callbackPath, String topic, String mode, String challenge, String leaseSeconds,
|
||||
String verifyToken) {
|
||||
public String validate(final String callbackPath, final String topic, final String mode, final String challenge, final String leaseSeconds,
|
||||
final String verifyToken) {
|
||||
if (!callbackPath.startsWith(callbackPrefix)) {
|
||||
throw new HttpStatusCodeException(404, "Not a valid callback prefix.", new Exception(callbackPath+" doesnt start with "+callbackPrefix));
|
||||
throw new HttpStatusCodeException(404, "Not a valid callback prefix.", new Exception(callbackPath + " doesnt start with " + callbackPrefix));
|
||||
}
|
||||
|
||||
String id = callbackPath.substring(callbackPrefix.length());
|
||||
final String id = callbackPath.substring(callbackPrefix.length());
|
||||
Logger.getLogger(Subscriptions.class.getName()).log(Level.FINE, "Handling validation request for id {0}", id);
|
||||
Subscription s = dao.findById(id);
|
||||
if(s == null){
|
||||
final Subscription s = dao.findById(id);
|
||||
if (s == null) {
|
||||
throw new HttpStatusCodeException(404, "Not a valid subscription id", null);
|
||||
}
|
||||
if (!s.getVerifyToken()
|
||||
.equals(verifyToken)) {
|
||||
if (!s.getVerifyToken().equals(verifyToken)) {
|
||||
throw new HttpStatusCodeException(403, "Verification Token Mismatch.", null);
|
||||
}
|
||||
|
||||
|
@ -238,8 +222,8 @@ public class Subscriptions {
|
|||
return challenge;
|
||||
}
|
||||
|
||||
private String findHubUrl(SyndFeed feed) {
|
||||
for (SyndLink l : (List<SyndLink>) feed.getLinks()) {
|
||||
private String findHubUrl(final SyndFeed feed) {
|
||||
for (final SyndLink l : feed.getLinks()) {
|
||||
if ("hub".equals(l.getRel())) {
|
||||
return l.getHref();
|
||||
}
|
||||
|
@ -248,21 +232,20 @@ public class Subscriptions {
|
|||
return null;
|
||||
}
|
||||
|
||||
private void validateLink(SyndFeed feed, String source) {
|
||||
for (SyndLink l : (List<SyndLink>) feed.getLinks()) {
|
||||
private void validateLink(final SyndFeed feed, final String source) {
|
||||
for (final SyndLink l : feed.getLinks()) {
|
||||
if ("self".equalsIgnoreCase(l.getRel())) {
|
||||
try {
|
||||
URI u = new URI(l.getHref());
|
||||
URI t = new URI(source);
|
||||
final URI u = new URI(l.getHref());
|
||||
final URI t = new URI(source);
|
||||
|
||||
if (!u.equals(t)) {
|
||||
throw new HttpStatusCodeException(400, "Feed self link does not match the subscribed URI.", null);
|
||||
}
|
||||
|
||||
break;
|
||||
} catch (URISyntaxException ex) {
|
||||
Logger.getLogger(Subscriptions.class.getName())
|
||||
.log(Level.SEVERE, null, ex);
|
||||
} catch (final URISyntaxException ex) {
|
||||
Logger.getLogger(Subscriptions.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -271,28 +254,28 @@ public class Subscriptions {
|
|||
/**
|
||||
* @param cache the cache to set
|
||||
*/
|
||||
public void setCache(FeedFetcherCache cache) {
|
||||
public void setCache(final FeedFetcherCache cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param requester the requester to set
|
||||
*/
|
||||
public void setRequester(Requester requester) {
|
||||
public void setRequester(final Requester requester) {
|
||||
this.requester = requester;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callbackPrefix the callbackPrefix to set
|
||||
*/
|
||||
public void setCallbackPrefix(String callbackPrefix) {
|
||||
public void setCallbackPrefix(final String callbackPrefix) {
|
||||
this.callbackPrefix = callbackPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dao the dao to set
|
||||
*/
|
||||
public void setDao(SubDAO dao) {
|
||||
public void setDao(final SubDAO dao) {
|
||||
this.dao = dao;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,11 +16,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem.sub.data;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public interface SubDAO {
|
||||
|
|
|
@ -20,9 +20,8 @@ package org.rometools.certiorem.sub.data;
|
|||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class Subscription implements Serializable {
|
||||
|
@ -36,110 +35,110 @@ public class Subscription implements Serializable {
|
|||
|
||||
/**
|
||||
* Set the value of expirationTime
|
||||
*
|
||||
*
|
||||
* @param newexpirationTime new value of expirationTime
|
||||
*/
|
||||
public void setExpirationTime(long newexpirationTime) {
|
||||
this.expirationTime = newexpirationTime;
|
||||
public void setExpirationTime(final long newexpirationTime) {
|
||||
expirationTime = newexpirationTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of expirationTime
|
||||
*
|
||||
*
|
||||
* @return the value of expirationTime
|
||||
*/
|
||||
public long getExpirationTime() {
|
||||
return this.expirationTime;
|
||||
return expirationTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of id
|
||||
*
|
||||
*
|
||||
* @param newid new value of id
|
||||
*/
|
||||
public void setId(String newid) {
|
||||
this.id = newid;
|
||||
public void setId(final String newid) {
|
||||
id = newid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of id
|
||||
*
|
||||
*
|
||||
* @return the value of id
|
||||
*/
|
||||
public String getId() {
|
||||
return this.id;
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of sourceUrl
|
||||
*
|
||||
*
|
||||
* @param newsourceUrl new value of sourceUrl
|
||||
*/
|
||||
public void setSourceUrl(String newsourceUrl) {
|
||||
this.sourceUrl = newsourceUrl;
|
||||
public void setSourceUrl(final String newsourceUrl) {
|
||||
sourceUrl = newsourceUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of sourceUrl
|
||||
*
|
||||
*
|
||||
* @return the value of sourceUrl
|
||||
*/
|
||||
public String getSourceUrl() {
|
||||
return this.sourceUrl;
|
||||
return sourceUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of unsubscribed
|
||||
*
|
||||
*
|
||||
* @param newunsubscribed new value of unsubscribed
|
||||
*/
|
||||
public void setUnsubscribed(boolean newunsubscribed) {
|
||||
this.unsubscribed = newunsubscribed;
|
||||
public void setUnsubscribed(final boolean newunsubscribed) {
|
||||
unsubscribed = newunsubscribed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of unsubscribed
|
||||
*
|
||||
*
|
||||
* @return the value of unsubscribed
|
||||
*/
|
||||
public boolean isUnsubscribed() {
|
||||
return this.unsubscribed;
|
||||
return unsubscribed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of validated
|
||||
*
|
||||
*
|
||||
* @param newvalidated new value of validated
|
||||
*/
|
||||
public void setValidated(boolean newvalidated) {
|
||||
this.validated = newvalidated;
|
||||
public void setValidated(final boolean newvalidated) {
|
||||
validated = newvalidated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of validated
|
||||
*
|
||||
*
|
||||
* @return the value of validated
|
||||
*/
|
||||
public boolean isValidated() {
|
||||
return this.validated;
|
||||
return validated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of verifyToken
|
||||
*
|
||||
*
|
||||
* @param newverifyToken new value of verifyToken
|
||||
*/
|
||||
public void setVerifyToken(String newverifyToken) {
|
||||
this.verifyToken = newverifyToken;
|
||||
public void setVerifyToken(final String newverifyToken) {
|
||||
verifyToken = newverifyToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of verifyToken
|
||||
*
|
||||
*
|
||||
* @return the value of verifyToken
|
||||
*/
|
||||
public String getVerifyToken() {
|
||||
return this.verifyToken;
|
||||
return verifyToken;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -152,7 +151,7 @@ public class Subscription implements Serializable {
|
|||
/**
|
||||
* @param callback the callback to set
|
||||
*/
|
||||
public void setCallback(SubscriptionCallback callback) {
|
||||
public void setCallback(final SubscriptionCallback callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ package org.rometools.certiorem.sub.data;
|
|||
import org.rometools.fetcher.impl.SyndFeedInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author najmi
|
||||
*/
|
||||
public interface SubscriptionCallback {
|
||||
|
@ -18,6 +18,6 @@ public interface SubscriptionCallback {
|
|||
void onFailure(Exception e);
|
||||
|
||||
void onSubscribe(Subscription subscribed);
|
||||
|
||||
|
||||
void onUnsubscribe(Subscription subscribed);
|
||||
}
|
||||
|
|
|
@ -27,25 +27,27 @@ import java.util.Date;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.rometools.certiorem.sub.data.SubDAO;
|
||||
import org.rometools.certiorem.sub.data.Subscription;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class InMemorySubDAO implements SubDAO {
|
||||
|
||||
private ConcurrentHashMap<String, Subscription> subscriptions = new ConcurrentHashMap<String, Subscription>();
|
||||
private final ConcurrentHashMap<String, Subscription> subscriptions = new ConcurrentHashMap<String, Subscription>();
|
||||
|
||||
@Override
|
||||
public Subscription findById(String id) {
|
||||
Subscription s = subscriptions.get(id);
|
||||
if(s == null){
|
||||
public Subscription findById(final String id) {
|
||||
final Subscription s = subscriptions.get(id);
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
if(s.getExpirationTime() > 0 && s.getExpirationTime() <= System.currentTimeMillis()){
|
||||
Logger.getLogger(InMemorySubDAO.class.getName()).log(Level.FINE, "Subscription {0} expired at {1}", new Object[]{s.getSourceUrl(), new Date(s.getExpirationTime())});
|
||||
if (s.getExpirationTime() > 0 && s.getExpirationTime() <= System.currentTimeMillis()) {
|
||||
Logger.getLogger(InMemorySubDAO.class.getName()).log(Level.FINE, "Subscription {0} expired at {1}",
|
||||
new Object[] { s.getSourceUrl(), new Date(s.getExpirationTime()) });
|
||||
subscriptions.remove(id);
|
||||
|
||||
return null;
|
||||
|
@ -54,20 +56,20 @@ public class InMemorySubDAO implements SubDAO {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Subscription addSubscription(Subscription s) {
|
||||
public Subscription addSubscription(final Subscription s) {
|
||||
subscriptions.put(s.getId(), s);
|
||||
Logger.getLogger(InMemorySubDAO.class.getName()).log(Level.FINE, "Stored subscription {0} {1}", new Object[]{s.getSourceUrl(), s.getId()});
|
||||
Logger.getLogger(InMemorySubDAO.class.getName()).log(Level.FINE, "Stored subscription {0} {1}", new Object[] { s.getSourceUrl(), s.getId() });
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Subscription updateSubscription(Subscription s) {
|
||||
public Subscription updateSubscription(final Subscription s) {
|
||||
subscriptions.put(s.getId(), s);
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSubscription(Subscription s) {
|
||||
public void removeSubscription(final Subscription s) {
|
||||
subscriptions.remove(s.getId());
|
||||
}
|
||||
|
||||
|
|
|
@ -16,64 +16,51 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem.sub.request;
|
||||
|
||||
import org.rometools.certiorem.sub.Requester;
|
||||
import org.rometools.certiorem.sub.data.Subscription;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import org.rometools.certiorem.sub.Requester;
|
||||
import org.rometools.certiorem.sub.data.Subscription;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public abstract class AbstractRequester implements Requester {
|
||||
|
||||
protected boolean sendRequest(String hubUrl, String mode, Subscription subscription, String verifySync,
|
||||
long leaseSeconds, String secret, String callbackUrl, RequestCallback callback)
|
||||
throws IOException {
|
||||
StringBuilder sb = new StringBuilder("hub.callback=").append(URLEncoder.encode(callbackUrl, "UTF-8"))
|
||||
.append("&hub.topic=")
|
||||
.append(URLEncoder.encode(subscription.getSourceUrl(),
|
||||
"UTF-8"))
|
||||
.append("&hub.verify=")
|
||||
.append(URLEncoder.encode(verifySync, "UTF-8"))
|
||||
.append("&hub.mode=")
|
||||
.append(URLEncoder.encode(mode, "UTF-8"));
|
||||
|
||||
protected boolean sendRequest(final String hubUrl, final String mode, final Subscription subscription, final String verifySync, final long leaseSeconds,
|
||||
final String secret, final String callbackUrl, final RequestCallback callback) throws IOException {
|
||||
final StringBuilder sb = new StringBuilder("hub.callback=").append(URLEncoder.encode(callbackUrl, "UTF-8")).append("&hub.topic=")
|
||||
.append(URLEncoder.encode(subscription.getSourceUrl(), "UTF-8")).append("&hub.verify=").append(URLEncoder.encode(verifySync, "UTF-8"))
|
||||
.append("&hub.mode=").append(URLEncoder.encode(mode, "UTF-8"));
|
||||
|
||||
if (leaseSeconds > 0) {
|
||||
sb.append("&hub.lease_seconds=")
|
||||
.append(Long.toString(leaseSeconds));
|
||||
sb.append("&hub.lease_seconds=").append(Long.toString(leaseSeconds));
|
||||
}
|
||||
|
||||
if (secret != null) {
|
||||
sb.append("&hub.secret=")
|
||||
.append(URLEncoder.encode(secret, "UTF-8"));
|
||||
sb.append("&hub.secret=").append(URLEncoder.encode(secret, "UTF-8"));
|
||||
}
|
||||
|
||||
if (subscription.getVerifyToken() != null) {
|
||||
sb.append("&hub.verify_token=")
|
||||
.append(URLEncoder.encode(subscription.getVerifyToken(), "UTF-8"));
|
||||
sb.append("&hub.verify_token=").append(URLEncoder.encode(subscription.getVerifyToken(), "UTF-8"));
|
||||
}
|
||||
|
||||
URL url = new URL(hubUrl);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
final URL url = new URL(hubUrl);
|
||||
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
||||
connection.setDoOutput(true);
|
||||
// connection.setRequestProperty("Host", url.getHost());
|
||||
// connection.setRequestProperty("Host", url.getHost());
|
||||
connection.setRequestProperty("User-Agent", "ROME-Certiorem");
|
||||
connection.connect();
|
||||
connection.getOutputStream()
|
||||
.write(sb.toString().getBytes("UTF-8"));
|
||||
connection.getOutputStream().write(sb.toString().getBytes("UTF-8"));
|
||||
|
||||
int rc = connection.getResponseCode();
|
||||
final int rc = connection.getResponseCode();
|
||||
connection.disconnect();
|
||||
|
||||
if (rc != 204) {
|
||||
|
|
|
@ -18,57 +18,53 @@
|
|||
|
||||
package org.rometools.certiorem.sub.request;
|
||||
|
||||
import org.rometools.certiorem.sub.data.Subscription;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.rometools.certiorem.sub.data.Subscription;
|
||||
|
||||
/**
|
||||
* A simple requester implementation that always makes requests as Async.
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class AsyncRequester extends AbstractRequester {
|
||||
@Override
|
||||
public void sendSubscribeRequest(final String hubUrl, final Subscription subscription, final String verifySync,
|
||||
final long leaseSeconds, final String secret, final String callbackUrl, final RequestCallback callback) {
|
||||
Logger.getLogger(AsyncRequester.class.getName()).log(Level.FINE, "Sending subscribe request to {0} for {1} to {2}", new Object[]{hubUrl, subscription.getSourceUrl(), callbackUrl});
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sendRequest(hubUrl, "subscribe", subscription, verifySync, leaseSeconds, secret, callbackUrl,
|
||||
callback);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(AsyncRequester.class.getName())
|
||||
.log(Level.SEVERE, null, ex);
|
||||
callback.onFailure(ex);
|
||||
}
|
||||
public void sendSubscribeRequest(final String hubUrl, final Subscription subscription, final String verifySync, final long leaseSeconds,
|
||||
final String secret, final String callbackUrl, final RequestCallback callback) {
|
||||
Logger.getLogger(AsyncRequester.class.getName()).log(Level.FINE, "Sending subscribe request to {0} for {1} to {2}",
|
||||
new Object[] { hubUrl, subscription.getSourceUrl(), callbackUrl });
|
||||
final Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sendRequest(hubUrl, "subscribe", subscription, verifySync, leaseSeconds, secret, callbackUrl, callback);
|
||||
} catch (final Exception ex) {
|
||||
Logger.getLogger(AsyncRequester.class.getName()).log(Level.SEVERE, null, ex);
|
||||
callback.onFailure(ex);
|
||||
}
|
||||
};
|
||||
new Thread(r).start();
|
||||
}
|
||||
};
|
||||
new Thread(r).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendUnsubscribeRequest(final String hubUrl, final Subscription subscription, final String verifySync,
|
||||
final String secret,
|
||||
final String callbackUrl, final RequestCallback callback) {
|
||||
Logger.getLogger(AsyncRequester.class.getName()).log(Level.FINE, "Sending unsubscribe request to {0} for {1} to {2}", new Object[]{hubUrl, subscription.getSourceUrl(), callbackUrl});
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sendRequest(hubUrl, "unsubscribe", subscription, verifySync, -1, secret, callbackUrl,
|
||||
callback);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(AsyncRequester.class.getName())
|
||||
.log(Level.SEVERE, null, ex);
|
||||
callback.onFailure(ex);
|
||||
}
|
||||
public void sendUnsubscribeRequest(final String hubUrl, final Subscription subscription, final String verifySync, final String secret,
|
||||
final String callbackUrl, final RequestCallback callback) {
|
||||
Logger.getLogger(AsyncRequester.class.getName()).log(Level.FINE, "Sending unsubscribe request to {0} for {1} to {2}",
|
||||
new Object[] { hubUrl, subscription.getSourceUrl(), callbackUrl });
|
||||
final Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sendRequest(hubUrl, "unsubscribe", subscription, verifySync, -1, secret, callbackUrl, callback);
|
||||
} catch (final IOException ex) {
|
||||
Logger.getLogger(AsyncRequester.class.getName()).log(Level.SEVERE, null, ex);
|
||||
callback.onFailure(ex);
|
||||
}
|
||||
};
|
||||
new Thread(r).start();
|
||||
}
|
||||
};
|
||||
new Thread(r).start();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,46 +22,42 @@
|
|||
*/
|
||||
package org.rometools.certiorem.sub.request;
|
||||
|
||||
import org.rometools.certiorem.sub.data.Subscription;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.rometools.certiorem.sub.data.Subscription;
|
||||
|
||||
/**
|
||||
* A simple requester implementation that always makes requests as Async.
|
||||
*
|
||||
* @author Farrukh Najmi
|
||||
*/
|
||||
public class SyncRequester extends AbstractRequester {
|
||||
@Override
|
||||
public void sendSubscribeRequest(final String hubUrl, final Subscription subscription, final String verifySync,
|
||||
final long leaseSeconds, final String secret, final String callbackUrl, final RequestCallback callback) {
|
||||
Logger.getLogger(SyncRequester.class.getName()).log(Level.INFO, "Sending subscribe request to {0} for {1} to {2}", new Object[]{hubUrl, subscription.getSourceUrl(), callbackUrl});
|
||||
public void sendSubscribeRequest(final String hubUrl, final Subscription subscription, final String verifySync, final long leaseSeconds,
|
||||
final String secret, final String callbackUrl, final RequestCallback callback) {
|
||||
Logger.getLogger(SyncRequester.class.getName()).log(Level.INFO, "Sending subscribe request to {0} for {1} to {2}",
|
||||
new Object[] { hubUrl, subscription.getSourceUrl(), callbackUrl });
|
||||
try {
|
||||
sendRequest(hubUrl, "subscribe", subscription, verifySync, leaseSeconds, secret, callbackUrl,
|
||||
callback);
|
||||
sendRequest(hubUrl, "subscribe", subscription, verifySync, leaseSeconds, secret, callbackUrl, callback);
|
||||
callback.onSuccess();
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(SyncRequester.class.getName())
|
||||
.log(Level.SEVERE, null, ex);
|
||||
} catch (final Exception ex) {
|
||||
Logger.getLogger(SyncRequester.class.getName()).log(Level.SEVERE, null, ex);
|
||||
callback.onFailure(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendUnsubscribeRequest(final String hubUrl, final Subscription subscription, final String verifySync,
|
||||
final String secret,
|
||||
final String callbackUrl, final RequestCallback callback) {
|
||||
Logger.getLogger(SyncRequester.class.getName()).log(Level.INFO, "Sending unsubscribe request to {0} for {1} to {2}", new Object[]{hubUrl, subscription.getSourceUrl(), callbackUrl});
|
||||
public void sendUnsubscribeRequest(final String hubUrl, final Subscription subscription, final String verifySync, final String secret,
|
||||
final String callbackUrl, final RequestCallback callback) {
|
||||
Logger.getLogger(SyncRequester.class.getName()).log(Level.INFO, "Sending unsubscribe request to {0} for {1} to {2}",
|
||||
new Object[] { hubUrl, subscription.getSourceUrl(), callbackUrl });
|
||||
try {
|
||||
sendRequest(hubUrl, "unsubscribe", subscription, verifySync, -1, secret, callbackUrl,
|
||||
callback);
|
||||
sendRequest(hubUrl, "unsubscribe", subscription, verifySync, -1, secret, callbackUrl, callback);
|
||||
callback.onSuccess();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SyncRequester.class.getName())
|
||||
.log(Level.SEVERE, null, ex);
|
||||
} catch (final IOException ex) {
|
||||
Logger.getLogger(SyncRequester.class.getName()).log(Level.SEVERE, null, ex);
|
||||
callback.onFailure(ex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,14 +16,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem.web;
|
||||
|
||||
import org.rometools.certiorem.HttpStatusCodeException;
|
||||
import org.rometools.certiorem.hub.Hub;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
|
@ -31,9 +26,11 @@ import javax.servlet.http.HttpServlet;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.rometools.certiorem.HttpStatusCodeException;
|
||||
import org.rometools.certiorem.hub.Hub;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public abstract class AbstractHubServlet extends HttpServlet {
|
||||
|
@ -46,37 +43,34 @@ public abstract class AbstractHubServlet extends HttpServlet {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
|
||||
try {
|
||||
if ("publish".equals(req.getParameter(HUBMODE))) {
|
||||
hub.sendNotification(req.getServerName(), req.getParameter("hub.url"));
|
||||
} else {
|
||||
String callback = req.getParameter("hub.callback");
|
||||
String topic = req.getParameter("hub.topic");
|
||||
String[] verifies = req.getParameterValues("hub.verify");
|
||||
String leaseString = req.getParameter("hub.lease_seconds");
|
||||
String secret = req.getParameter("hub.secret");
|
||||
String verifyToken = req.getParameter("hub.verify_token");
|
||||
String verifyMode = Arrays.asList(verifies)
|
||||
.contains("async") ? "async" : "sync";
|
||||
final String callback = req.getParameter("hub.callback");
|
||||
final String topic = req.getParameter("hub.topic");
|
||||
final String[] verifies = req.getParameterValues("hub.verify");
|
||||
final String leaseString = req.getParameter("hub.lease_seconds");
|
||||
final String secret = req.getParameter("hub.secret");
|
||||
final String verifyToken = req.getParameter("hub.verify_token");
|
||||
final String verifyMode = Arrays.asList(verifies).contains("async") ? "async" : "sync";
|
||||
Boolean result = null;
|
||||
|
||||
if ("subscribe".equals(req.getParameter(HUBMODE))) {
|
||||
long leaseSeconds = (leaseString != null) ? Long.parseLong(leaseString) : (-1);
|
||||
final long leaseSeconds = leaseString != null ? Long.parseLong(leaseString) : -1;
|
||||
result = hub.subscribe(callback, topic, verifyMode, leaseSeconds, secret, verifyToken);
|
||||
} else if ("unsubscribe".equals(req.getParameter(HUBMODE))) {
|
||||
result = hub.unsubscribe(callback, topic, verifyMode, secret, verifyToken);
|
||||
}
|
||||
|
||||
if ((result != null) && !result) {
|
||||
if (result != null && !result) {
|
||||
throw new HttpStatusCodeException(500, "Operation failed.", null);
|
||||
}
|
||||
}
|
||||
} catch (HttpStatusCodeException sc) {
|
||||
} catch (final HttpStatusCodeException sc) {
|
||||
resp.setStatus(sc.getStatus());
|
||||
resp.getWriter()
|
||||
.println(sc.getMessage());
|
||||
resp.getWriter().println(sc.getMessage());
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -16,45 +16,46 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem.web;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpUtils;
|
||||
|
||||
import org.rometools.certiorem.HttpStatusCodeException;
|
||||
import org.rometools.certiorem.sub.Subscriptions;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class AbstractSubServlet extends HttpServlet {
|
||||
|
||||
private final Subscriptions subscriptions;
|
||||
|
||||
protected AbstractSubServlet(final Subscriptions subscriptions){
|
||||
|
||||
protected AbstractSubServlet(final Subscriptions subscriptions) {
|
||||
super();
|
||||
this.subscriptions = subscriptions;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
String mode = req.getParameter("hub.mode");
|
||||
String topic = req.getParameter("hub.topic");
|
||||
String challenge = req.getParameter("hub.challenge");
|
||||
String leaseString = req.getParameter("hub.lease_seconds");
|
||||
String verifyToken = req.getParameter("hub.verify_token");
|
||||
try{
|
||||
String result = subscriptions.validate(HttpUtils.getRequestURL(req).toString(), topic, mode, challenge, leaseString, verifyToken);
|
||||
protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
|
||||
final String mode = req.getParameter("hub.mode");
|
||||
final String topic = req.getParameter("hub.topic");
|
||||
final String challenge = req.getParameter("hub.challenge");
|
||||
final String leaseString = req.getParameter("hub.lease_seconds");
|
||||
final String verifyToken = req.getParameter("hub.verify_token");
|
||||
try {
|
||||
final String result = subscriptions.validate(HttpUtils.getRequestURL(req).toString(), topic, mode, challenge, leaseString, verifyToken);
|
||||
resp.setStatus(200);
|
||||
resp.getWriter().print(result);
|
||||
return;
|
||||
} catch(HttpStatusCodeException e){
|
||||
} catch (final HttpStatusCodeException e) {
|
||||
e.printStackTrace();
|
||||
resp.setStatus(e.getStatus());
|
||||
resp.getWriter().print(e.getMessage());
|
||||
|
@ -63,17 +64,15 @@ public class AbstractSubServlet extends HttpServlet {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
try{
|
||||
this.subscriptions.callback(HttpUtils.getRequestURL(req).toString(), req.getInputStream());
|
||||
protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
|
||||
try {
|
||||
subscriptions.callback(HttpUtils.getRequestURL(req).toString(), req.getInputStream());
|
||||
return;
|
||||
} catch(HttpStatusCodeException e){
|
||||
} catch (final HttpStatusCodeException e) {
|
||||
e.printStackTrace();
|
||||
resp.setStatus(e.getStatus());
|
||||
resp.getWriter().println(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -16,34 +16,33 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem.hub;
|
||||
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class AlwaysVerifier implements Verifier {
|
||||
|
||||
@Override
|
||||
public void verifySubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback) {
|
||||
public void verifySubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||
callback.onVerify(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifySubcribeSyncronously(Subscriber subscriber) {
|
||||
public boolean verifySubcribeSyncronously(final Subscriber subscriber) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verifyUnsubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback) {
|
||||
public void verifyUnsubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||
callback.onVerify(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifyUnsubcribeSyncronously(Subscriber subscriber) {
|
||||
public boolean verifyUnsubcribeSyncronously(final Subscriber subscriber) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,25 +18,25 @@
|
|||
|
||||
package org.rometools.certiorem.hub;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.rometools.certiorem.HttpStatusCodeException;
|
||||
import org.rometools.certiorem.hub.data.HubDAO;
|
||||
import org.rometools.certiorem.hub.data.ram.InMemoryHubDAO;
|
||||
import org.rometools.fetcher.FeedFetcher;
|
||||
import org.rometools.fetcher.impl.HashMapFeedInfoCache;
|
||||
import org.rometools.fetcher.impl.HttpURLFeedFetcher;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.rometools.certiorem.hub.data.HubDAO;
|
||||
import org.rometools.certiorem.hub.data.ram.InMemoryHubDAO;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class ControllerTest {
|
||||
|
@ -66,14 +66,14 @@ public class ControllerTest {
|
|||
public void testSubscribe() {
|
||||
Logger.getLogger(ControllerTest.class.getName()).info("subscribe");
|
||||
|
||||
String callback = "http://localhost/doNothing";
|
||||
String topic = "http://feeds.feedburner.com/screaming-penguin";
|
||||
long lease_seconds = -1;
|
||||
String secret = null;
|
||||
String verify_token = "MyVoiceIsMyPassport";
|
||||
HubDAO dao = new InMemoryHubDAO();
|
||||
Notifier notifier = null;
|
||||
FeedFetcher fetcher = new HttpURLFeedFetcher(HashMapFeedInfoCache.getInstance());
|
||||
final String callback = "http://localhost/doNothing";
|
||||
final String topic = "http://feeds.feedburner.com/screaming-penguin";
|
||||
final long lease_seconds = -1;
|
||||
final String secret = null;
|
||||
final String verify_token = "MyVoiceIsMyPassport";
|
||||
final HubDAO dao = new InMemoryHubDAO();
|
||||
final Notifier notifier = null;
|
||||
final FeedFetcher fetcher = new HttpURLFeedFetcher(HashMapFeedInfoCache.getInstance());
|
||||
Hub instance = new Hub(dao, new AlwaysVerifier(), notifier, fetcher);
|
||||
|
||||
Boolean result = instance.subscribe(callback, topic, "sync", lease_seconds, secret, verify_token);
|
||||
|
@ -90,7 +90,7 @@ public class ControllerTest {
|
|||
try {
|
||||
instance.subscribe(null, topic, "async", lease_seconds, secret, verify_token);
|
||||
fail();
|
||||
} catch (HttpStatusCodeException e) {
|
||||
} catch (final HttpStatusCodeException e) {
|
||||
assertEquals(400, e.getStatus());
|
||||
Logger.getLogger(ControllerTest.class.getName()).info(e.getMessage());
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ public class ControllerTest {
|
|||
try {
|
||||
instance.subscribe(callback, null, "async", lease_seconds, secret, verify_token);
|
||||
fail();
|
||||
} catch (HttpStatusCodeException e) {
|
||||
} catch (final HttpStatusCodeException e) {
|
||||
assertEquals(400, e.getStatus());
|
||||
Logger.getLogger(ControllerTest.class.getName()).info(e.getMessage());
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ public class ControllerTest {
|
|||
try {
|
||||
instance.subscribe(callback, topic, "foo", lease_seconds, secret, verify_token);
|
||||
fail();
|
||||
} catch (HttpStatusCodeException e) {
|
||||
} catch (final HttpStatusCodeException e) {
|
||||
assertEquals(400, e.getStatus());
|
||||
Logger.getLogger(ControllerTest.class.getName()).info(e.getMessage());
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ public class ControllerTest {
|
|||
try {
|
||||
result = instance.subscribe(callback, topic, "sync", lease_seconds, secret, verify_token);
|
||||
fail();
|
||||
} catch (HttpStatusCodeException e) {
|
||||
} catch (final HttpStatusCodeException e) {
|
||||
assertEquals(500, e.getStatus());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,29 +5,32 @@
|
|||
package org.rometools.certiorem.hub;
|
||||
|
||||
import java.io.IOException;
|
||||
import com.sun.syndication.feed.synd.SyndEntry;
|
||||
import java.util.List;
|
||||
import junit.framework.Assert;
|
||||
import org.rometools.fetcher.impl.HashMapFeedInfoCache;
|
||||
import org.rometools.fetcher.impl.HttpURLFeedFetcher;
|
||||
import java.net.URL;
|
||||
import com.sun.syndication.feed.synd.SyndFeed;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.rometools.fetcher.impl.HashMapFeedInfoCache;
|
||||
import org.rometools.fetcher.impl.HttpURLFeedFetcher;
|
||||
|
||||
import com.sun.syndication.feed.synd.SyndEntry;
|
||||
import com.sun.syndication.feed.synd.SyndFeed;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author najmi
|
||||
*/
|
||||
public class DeltaSyndFeedInfoTest {
|
||||
|
||||
|
||||
DeltaFeedInfoCache feedInfoCache;
|
||||
HttpURLFeedFetcher feedFetcher;
|
||||
SyndFeed feed;
|
||||
|
||||
|
||||
public DeltaSyndFeedInfoTest() {
|
||||
}
|
||||
|
||||
|
@ -38,18 +41,16 @@ public class DeltaSyndFeedInfoTest {
|
|||
@AfterClass
|
||||
public static void tearDownClass() throws Exception {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
feedInfoCache = new DeltaFeedInfoCache(new HashMapFeedInfoCache());
|
||||
feedFetcher = new HttpURLFeedFetcher(feedInfoCache);
|
||||
}
|
||||
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
public void tearDown() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test of getSyndFeed method, of class DeltaSyndFeedInfo.
|
||||
|
@ -57,21 +58,21 @@ public class DeltaSyndFeedInfoTest {
|
|||
@Test
|
||||
public void testGetSyndFeed() throws Exception {
|
||||
System.out.println("getSyndFeed");
|
||||
|
||||
|
||||
feed = feedFetcher.retrieveFeed(getFeedUrl());
|
||||
List<SyndEntry> entries = feed.getEntries();
|
||||
Assert.assertTrue(!entries.isEmpty());
|
||||
|
||||
//Fetch again and this time the entries should be empty as none have changed.
|
||||
// Fetch again and this time the entries should be empty as none have changed.
|
||||
feed = feedFetcher.retrieveFeed(getFeedUrl());
|
||||
entries = feed.getEntries();
|
||||
Assert.assertTrue(entries.isEmpty());
|
||||
Assert.assertTrue(entries.isEmpty());
|
||||
}
|
||||
|
||||
private URL getFeedUrl() throws IOException {
|
||||
URL feedUrl = new URL("http://news.google.com/news?pz=1&cf=all&ned=us&hl=en&output=rss");
|
||||
// URL feedUrl = new URL("http://newsrss.bbc.co.uk/rss/newsonline_world_edition/front_page/rss.xml");
|
||||
|
||||
final URL feedUrl = new URL("http://news.google.com/news?pz=1&cf=all&ned=us&hl=en&output=rss");
|
||||
// URL feedUrl = new URL("http://newsrss.bbc.co.uk/rss/newsonline_world_edition/front_page/rss.xml");
|
||||
|
||||
return feedUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,34 +16,33 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem.hub;
|
||||
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class ExceptionVerifier implements Verifier{
|
||||
public class ExceptionVerifier implements Verifier {
|
||||
|
||||
@Override
|
||||
public void verifySubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback) {
|
||||
public void verifySubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifySubcribeSyncronously(Subscriber subscriber) {
|
||||
public boolean verifySubcribeSyncronously(final Subscriber subscriber) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verifyUnsubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback) {
|
||||
public void verifyUnsubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifyUnsubcribeSyncronously(Subscriber subscriber) {
|
||||
public boolean verifyUnsubcribeSyncronously(final Subscriber subscriber) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
|
|
|
@ -16,34 +16,33 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem.hub;
|
||||
|
||||
import org.rometools.certiorem.hub.data.Subscriber;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class NeverVerifier implements Verifier{
|
||||
public class NeverVerifier implements Verifier {
|
||||
|
||||
@Override
|
||||
public void verifySubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback) {
|
||||
public void verifySubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||
callback.onVerify(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifySubcribeSyncronously(Subscriber subscriber) {
|
||||
public boolean verifySubcribeSyncronously(final Subscriber subscriber) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verifyUnsubscribeAsyncronously(Subscriber subscriber, VerificationCallback callback) {
|
||||
public void verifyUnsubscribeAsyncronously(final Subscriber subscriber, final VerificationCallback callback) {
|
||||
callback.onVerify(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifyUnsubcribeSyncronously(Subscriber subscriber) {
|
||||
public boolean verifyUnsubcribeSyncronously(final Subscriber subscriber) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,10 +21,11 @@ package org.rometools.certiorem.hub.data;
|
|||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public abstract class AbstractDAOTest {
|
||||
|
@ -33,40 +34,40 @@ public abstract class AbstractDAOTest {
|
|||
|
||||
@Test
|
||||
public void testSubscribe() {
|
||||
HubDAO instance = get();
|
||||
final HubDAO instance = get();
|
||||
Logger.getLogger(AbstractDAOTest.class.getName()).log(Level.INFO, "{0} testSubscribe", instance.getClass().getName());
|
||||
Subscriber subscriber = new Subscriber();
|
||||
final Subscriber subscriber = new Subscriber();
|
||||
subscriber.setCallback("http://localhost:9797/noop");
|
||||
subscriber.setTopic("http://feeds.feedburner.com/screaming-penguin");
|
||||
subscriber.setLeaseSeconds(-1);
|
||||
subscriber.setVerify("VerifyMe");
|
||||
|
||||
Subscriber result = instance.addSubscriber(subscriber);
|
||||
final Subscriber result = instance.addSubscriber(subscriber);
|
||||
|
||||
assert result.equals(subscriber) : "Subscriber not equal.";
|
||||
|
||||
List<Subscriber> subscribers = (List<Subscriber>) instance.subscribersForTopic(subscriber.getTopic());
|
||||
final List<Subscriber> subscribers = (List<Subscriber>) instance.subscribersForTopic(subscriber.getTopic());
|
||||
|
||||
assert subscribers.contains(result) : "Subscriber not in result.";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLeaseExpire() throws InterruptedException {
|
||||
HubDAO instance = get();
|
||||
final HubDAO instance = get();
|
||||
Logger.getLogger(AbstractDAOTest.class.getName()).log(Level.INFO, "{0} testLeaseExpire", instance.getClass().getName());
|
||||
Subscriber subscriber = new Subscriber();
|
||||
final Subscriber subscriber = new Subscriber();
|
||||
subscriber.setCallback("http://localhost:9797/noop");
|
||||
subscriber.setTopic("http://feeds.feedburner.com/screaming-penguin");
|
||||
subscriber.setLeaseSeconds(1);
|
||||
subscriber.setVerify("VerifyMe");
|
||||
|
||||
Subscriber result = instance.addSubscriber(subscriber);
|
||||
final Subscriber result = instance.addSubscriber(subscriber);
|
||||
|
||||
assert subscriber.equals(result) : "Subscriber not equal.";
|
||||
//quick test for store.
|
||||
// quick test for store.
|
||||
List<Subscriber> subscribers = (List<Subscriber>) instance.subscribersForTopic(subscriber.getTopic());
|
||||
assert subscribers.contains(result) : "Subscriber not in result.";
|
||||
//sleep past expiration
|
||||
// sleep past expiration
|
||||
Thread.sleep(1100);
|
||||
subscribers = (List<Subscriber>) instance.subscribersForTopic(subscriber.getTopic());
|
||||
assert !subscribers.contains(result) : "Subscriber should have expired";
|
||||
|
@ -74,15 +75,15 @@ public abstract class AbstractDAOTest {
|
|||
|
||||
@Test
|
||||
public void testUnsubscribe() throws InterruptedException {
|
||||
HubDAO instance = get();
|
||||
final HubDAO instance = get();
|
||||
Logger.getLogger(AbstractDAOTest.class.getName()).log(Level.INFO, "{0} testUnsubscribe", instance.getClass().getName());
|
||||
Subscriber subscriber = new Subscriber();
|
||||
final Subscriber subscriber = new Subscriber();
|
||||
subscriber.setCallback("http://localhost:9797/noop");
|
||||
subscriber.setTopic("http://feeds.feedburner.com/screaming-penguin");
|
||||
subscriber.setLeaseSeconds(1);
|
||||
subscriber.setVerify("VerifyMe");
|
||||
|
||||
Subscriber result = instance.addSubscriber(subscriber);
|
||||
final Subscriber result = instance.addSubscriber(subscriber);
|
||||
// TODO
|
||||
|
||||
}
|
||||
|
|
|
@ -16,18 +16,17 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.rometools.certiorem.hub.data.ram;
|
||||
|
||||
import org.rometools.certiorem.hub.data.AbstractDAOTest;
|
||||
import org.rometools.certiorem.hub.data.HubDAO;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author robert.cooper
|
||||
*/
|
||||
public class InMemoryDAOTest extends AbstractDAOTest{
|
||||
private InMemoryHubDAO dao = new InMemoryHubDAO();
|
||||
public class InMemoryDAOTest extends AbstractDAOTest {
|
||||
private final InMemoryHubDAO dao = new InMemoryHubDAO();
|
||||
|
||||
public InMemoryDAOTest() {
|
||||
}
|
||||
|
@ -37,8 +36,4 @@ public class InMemoryDAOTest extends AbstractDAOTest{
|
|||
return dao;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
1
src/test/resources/.gitignore
vendored
Normal file
1
src/test/resources/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
# needed to commit empty folder
|
Loading…
Reference in a new issue