Formatted code

Added Eclipse formatter and cleaup configuration
This commit is contained in:
Patrick Gotthard 2013-10-12 00:10:09 +02:00
parent ad3c5de1c0
commit 8f475d9ae1
68 changed files with 3910 additions and 3577 deletions

56
cleanup.xml Normal file
View 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
View 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>

View file

@ -16,12 +16,11 @@
package org.rometools.propono.atom.client; package org.rometools.propono.atom.client;
import org.rometools.propono.utils.ProponoException; import org.rometools.propono.utils.ProponoException;
import com.sun.syndication.io.impl.Atom10Parser; import com.sun.syndication.io.impl.Atom10Parser;
/** /**
* Creates AtomService or ClientCollection based on username, password and * Creates AtomService or ClientCollection based on username, password and end-point URI of Atom protocol service.
* end-point URI of Atom protocol service.
*/ */
public class AtomClientFactory { public class AtomClientFactory {
@ -32,16 +31,14 @@ public class AtomClientFactory {
/** /**
* Create AtomService by reading service doc from Atom Server. * Create AtomService by reading service doc from Atom Server.
*/ */
public static ClientAtomService getAtomService( public static ClientAtomService getAtomService(final String uri, final AuthStrategy authStrategy) throws ProponoException {
String uri, AuthStrategy authStrategy) throws ProponoException {
return new ClientAtomService(uri, authStrategy); return new ClientAtomService(uri, authStrategy);
} }
/** /**
* Create ClientCollection bound to URI. * Create ClientCollection bound to URI.
*/ */
public static ClientCollection getCollection( public static ClientCollection getCollection(final String uri, final AuthStrategy authStrategy) throws ProponoException {
String uri, AuthStrategy authStrategy) throws ProponoException {
return new ClientCollection(uri, authStrategy); return new ClientCollection(uri, authStrategy);
} }
} }

View file

@ -15,16 +15,14 @@
*/ */
package org.rometools.propono.atom.client; package org.rometools.propono.atom.client;
import org.rometools.propono.utils.ProponoException;
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethodBase; import org.apache.commons.httpclient.HttpMethodBase;
import org.rometools.propono.utils.ProponoException;
public interface AuthStrategy { public interface AuthStrategy {
/** /**
* Add authentication credenticals, tokens, etc. to HTTP method * Add authentication credenticals, tokens, etc. to HTTP method
*/ */
void addAuthentication(HttpClient httpClient, HttpMethodBase method) void addAuthentication(HttpClient httpClient, HttpMethodBase method) throws ProponoException;
throws ProponoException;
} }

View file

@ -15,27 +15,28 @@
*/ */
package org.rometools.propono.atom.client; package org.rometools.propono.atom.client;
import com.sun.syndication.io.impl.Base64;
import org.rometools.propono.utils.ProponoException;
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethodBase; import org.apache.commons.httpclient.HttpMethodBase;
import org.rometools.propono.utils.ProponoException;
import com.sun.syndication.io.impl.Base64;
public class BasicAuthStrategy implements AuthStrategy { public class BasicAuthStrategy implements AuthStrategy {
private String credentials; private final String credentials;
public BasicAuthStrategy(String username, String password) { public BasicAuthStrategy(final String username, final String password) {
this.credentials = new Base64();
new String(new Base64().encode((username + ":" + password).getBytes())); credentials = new String(Base64.encode((username + ":" + password).getBytes()));
} }
public void init() throws ProponoException { public void init() throws ProponoException {
// op-op // op-op
} }
public void addAuthentication(HttpClient httpClient, HttpMethodBase method) throws ProponoException { @Override
public void addAuthentication(final HttpClient httpClient, final HttpMethodBase method) throws ProponoException {
httpClient.getParams().setAuthenticationPreemptive(true); httpClient.getParams().setAuthenticationPreemptive(true);
String header = "Basic " + credentials; final String header = "Basic " + credentials;
method.setRequestHeader("Authorization", header); method.setRequestHeader("Authorization", header);
} }
} }

View file

@ -15,13 +15,10 @@
*/ */
package org.rometools.propono.atom.client; package org.rometools.propono.atom.client;
import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.io.impl.Atom10Parser;
import org.rometools.propono.utils.ProponoException;
import org.rometools.propono.atom.common.AtomService;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethodBase; import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
@ -31,61 +28,60 @@ import org.apache.commons.logging.LogFactory;
import org.jdom2.Document; import org.jdom2.Document;
import org.jdom2.Element; import org.jdom2.Element;
import org.jdom2.input.SAXBuilder; import org.jdom2.input.SAXBuilder;
import org.rometools.propono.atom.common.AtomService;
import org.rometools.propono.utils.ProponoException;
import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.io.impl.Atom10Parser;
/** /**
* This class models an Atom Publising Protocol Service Document. * This class models an Atom Publising Protocol Service Document. It extends the common {@link com.sun.syndication.propono.atom.common.Collection} class to add
* It extends the common * a <code>getEntry()</code> method and to return {@link com.sun.syndication.propono.atom.client.ClientWorkspace} objects instead of common
* {@link com.sun.syndication.propono.atom.common.Collection}
* class to add a <code>getEntry()</code> method and to return
* {@link com.sun.syndication.propono.atom.client.ClientWorkspace}
* objects instead of common
* {@link com.sun.syndication.propono.atom.common.Workspace}s. * {@link com.sun.syndication.propono.atom.common.Workspace}s.
*/ */
public class ClientAtomService extends AtomService { public class ClientAtomService extends AtomService {
private static Log logger = LogFactory.getLog(ClientAtomService.class); private static Log logger = LogFactory.getLog(ClientAtomService.class);
private String uri = null; private String uri = null;
private HttpClient httpClient = null; private HttpClient httpClient = null;
private AuthStrategy authStrategy = null; private AuthStrategy authStrategy = null;
/** /**
* Create Atom blog service instance for specified URL and user account. * Create Atom blog service instance for specified URL and user account.
* @param url End-point URL of Atom service *
* @param url End-point URL of Atom service
*/ */
ClientAtomService(String uri, AuthStrategy authStrategy) ClientAtomService(final String uri, final AuthStrategy authStrategy) throws ProponoException {
throws ProponoException {
this.uri = uri; this.uri = uri;
this.authStrategy = authStrategy; this.authStrategy = authStrategy;
Document doc = getAtomServiceDocument(); final Document doc = getAtomServiceDocument();
parseAtomServiceDocument(doc); parseAtomServiceDocument(doc);
} }
/** /**
* Get full entry from service by entry edit URI. * Get full entry from service by entry edit URI.
*/ */
public ClientEntry getEntry(String uri) throws ProponoException { public ClientEntry getEntry(final String uri) throws ProponoException {
GetMethod method = new GetMethod(uri); final GetMethod method = new GetMethod(uri);
authStrategy.addAuthentication(httpClient, method); authStrategy.addAuthentication(httpClient, method);
try { try {
httpClient.executeMethod(method); httpClient.executeMethod(method);
if (method.getStatusCode() != 200) { if (method.getStatusCode() != 200) {
throw new ProponoException("ERROR HTTP status code=" + method.getStatusCode()); throw new ProponoException("ERROR HTTP status code=" + method.getStatusCode());
} }
Entry romeEntry = Atom10Parser.parseEntry( final Entry romeEntry = Atom10Parser.parseEntry(new InputStreamReader(method.getResponseBodyAsStream()), uri);
new InputStreamReader(method.getResponseBodyAsStream()), uri);
if (!romeEntry.isMediaEntry()) { if (!romeEntry.isMediaEntry()) {
return new ClientEntry(this, null, romeEntry, false); return new ClientEntry(this, null, romeEntry, false);
} else { } else {
return new ClientMediaEntry(this, null, romeEntry, false); return new ClientMediaEntry(this, null, romeEntry, false);
} }
} catch (Exception e) { } catch (final Exception e) {
throw new ProponoException("ERROR: getting or parsing entry/media", e); throw new ProponoException("ERROR: getting or parsing entry/media", e);
} finally { } finally {
method.releaseConnection(); method.releaseConnection();
} }
} }
void addAuthentication(HttpMethodBase method) throws ProponoException { void addAuthentication(final HttpMethodBase method) throws ProponoException {
authStrategy.addAuthentication(httpClient, method); authStrategy.addAuthentication(httpClient, method);
} }
@ -95,7 +91,7 @@ public class ClientAtomService extends AtomService {
private Document getAtomServiceDocument() throws ProponoException { private Document getAtomServiceDocument() throws ProponoException {
GetMethod method = null; GetMethod method = null;
int code = -1; final int code = -1;
try { try {
httpClient = new HttpClient(new MultiThreadedHttpConnectionManager()); httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());
// TODO: make connection timeout configurable // TODO: make connection timeout configurable
@ -105,25 +101,27 @@ public class ClientAtomService extends AtomService {
authStrategy.addAuthentication(httpClient, method); authStrategy.addAuthentication(httpClient, method);
httpClient.executeMethod(method); httpClient.executeMethod(method);
SAXBuilder builder = new SAXBuilder(); final SAXBuilder builder = new SAXBuilder();
return builder.build(method.getResponseBodyAsStream()); return builder.build(method.getResponseBodyAsStream());
} catch (Throwable t) { } catch (final Throwable t) {
String msg = "ERROR retrieving Atom Service Document, code: "+code; final String msg = "ERROR retrieving Atom Service Document, code: " + code;
logger.debug(msg, t); logger.debug(msg, t);
throw new ProponoException(msg, t); throw new ProponoException(msg, t);
} finally { } finally {
if (method != null) method.releaseConnection(); if (method != null) {
method.releaseConnection();
}
} }
} }
/** Deserialize an Atom service XML document into an object */ /** Deserialize an Atom service XML document into an object */
private void parseAtomServiceDocument(Document document) throws ProponoException { private void parseAtomServiceDocument(final Document document) throws ProponoException {
Element root = document.getRootElement(); final Element root = document.getRootElement();
List spaces = root.getChildren("workspace", AtomService.ATOM_PROTOCOL); final List spaces = root.getChildren("workspace", AtomService.ATOM_PROTOCOL);
Iterator iter = spaces.iterator(); final Iterator iter = spaces.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
Element e = (Element) iter.next(); final Element e = (Element) iter.next();
addWorkspace(new ClientWorkspace(e, this, uri)); addWorkspace(new ClientWorkspace(e, this, uri));
} }
} }
@ -135,4 +133,3 @@ public class ClientAtomService extends AtomService {
return httpClient; return httpClient;
} }
} }

View file

@ -1,70 +1,66 @@
/* /*
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. The ASF licenses this file to You * contributor license agreements. The ASF licenses this file to You
* under the Apache License, Version 2.0 (the "License"); you may not * under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. * use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. For additional information regarding * limitations under the License. For additional information regarding
* copyright in this work, please see the NOTICE file in the top level * copyright in this work, please see the NOTICE file in the top level
* directory of this distribution. * directory of this distribution.
*/ */
package org.rometools.propono.atom.client; package org.rometools.propono.atom.client;
import com.sun.syndication.feed.atom.Category;
import org.rometools.propono.atom.common.*;
import org.rometools.propono.utils.ProponoException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.GetMethod;
import org.jdom2.Document; import org.jdom2.Document;
import org.jdom2.Element; import org.jdom2.Element;
import org.jdom2.JDOMException; import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder; import org.jdom2.input.SAXBuilder;
import org.rometools.propono.atom.common.Categories;
import org.rometools.propono.utils.ProponoException;
/** /**
* Models an Atom protocol Categories element, which may contain ROME Atom * Models an Atom protocol Categories element, which may contain ROME Atom {@link com.sun.syndication.feed.atom.Category} elements.
* {@link com.sun.syndication.feed.atom.Category} elements.
*/ */
public class ClientCategories extends Categories { public class ClientCategories extends Categories {
private ClientCollection clientCollection = null; private ClientCollection clientCollection = null;
/** Load select from XML element */ /** Load select from XML element */
public ClientCategories(Element e, ClientCollection clientCollection) throws ProponoException { public ClientCategories(final Element e, final ClientCollection clientCollection) throws ProponoException {
this.clientCollection = clientCollection; this.clientCollection = clientCollection;
parseCategoriesElement(e); parseCategoriesElement(e);
if (getHref() != null) fetchContents(); if (getHref() != null) {
fetchContents();
}
} }
public void fetchContents() throws ProponoException { public void fetchContents() throws ProponoException {
GetMethod method = new GetMethod(getHrefResolved()); final GetMethod method = new GetMethod(getHrefResolved());
clientCollection.addAuthentication(method); clientCollection.addAuthentication(method);
try { try {
clientCollection.getHttpClient().executeMethod(method); clientCollection.getHttpClient().executeMethod(method);
if (method.getStatusCode() != 200) { if (method.getStatusCode() != 200) {
throw new ProponoException("ERROR HTTP status code=" + method.getStatusCode()); throw new ProponoException("ERROR HTTP status code=" + method.getStatusCode());
} }
SAXBuilder builder = new SAXBuilder(); final SAXBuilder builder = new SAXBuilder();
Document catsDoc = builder.build( final Document catsDoc = builder.build(new InputStreamReader(method.getResponseBodyAsStream()));
new InputStreamReader(method.getResponseBodyAsStream()));
parseCategoriesElement(catsDoc.getRootElement()); parseCategoriesElement(catsDoc.getRootElement());
} catch (IOException ioe) { } catch (final IOException ioe) {
throw new ProponoException( throw new ProponoException("ERROR: reading out-of-line categories", ioe);
"ERROR: reading out-of-line categories", ioe); } catch (final JDOMException jde) {
} catch (JDOMException jde) { throw new ProponoException("ERROR: parsing out-of-line categories", jde);
throw new ProponoException(
"ERROR: parsing out-of-line categories", jde);
} finally { } finally {
method.releaseConnection(); method.releaseConnection();
} }
} }
} }

View file

@ -16,62 +16,63 @@
package org.rometools.propono.atom.client; package org.rometools.propono.atom.client;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.io.InputStreamReader;
import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.io.impl.Atom10Parser;
import org.rometools.propono.atom.common.AtomService;
import org.rometools.propono.atom.common.Categories;
import org.rometools.propono.utils.ProponoException;
import org.rometools.propono.atom.common.Collection;
import org.rometools.propono.atom.common.Workspace;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethodBase; import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom2.Element; import org.jdom2.Element;
import org.rometools.propono.atom.common.AtomService;
import org.rometools.propono.atom.common.Categories;
import org.rometools.propono.atom.common.Collection;
import org.rometools.propono.atom.common.Workspace;
import org.rometools.propono.utils.ProponoException;
import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.io.impl.Atom10Parser;
/** /**
* Models an Atom collection, extends Collection and adds methods for adding, * Models an Atom collection, extends Collection and adds methods for adding, retrieving, updateing and deleting entries.
* retrieving, updateing and deleting entries.
*/ */
public class ClientCollection extends Collection { public class ClientCollection extends Collection {
static final Log logger = LogFactory.getLog(ClientCollection.class); static final Log logger = LogFactory.getLog(ClientCollection.class);
private List categories = new ArrayList(); private final List categories = new ArrayList();
private HttpClient httpClient = null; private HttpClient httpClient = null;
private AuthStrategy authStrategy = null; private AuthStrategy authStrategy = null;
private boolean writable = true; private final boolean writable = true;
private ClientWorkspace workspace = null; private ClientWorkspace workspace = null;
private ClientAtomService service = null; private ClientAtomService service = null;
ClientCollection(Element e, ClientWorkspace workspace, String baseURI) throws ProponoException { ClientCollection(final Element e, final ClientWorkspace workspace, final String baseURI) throws ProponoException {
super(e, baseURI); super(e, baseURI);
this.workspace = workspace; this.workspace = workspace;
this.service = workspace.getAtomService(); service = workspace.getAtomService();
this.httpClient = workspace.getAtomService().getHttpClient(); httpClient = workspace.getAtomService().getHttpClient();
this.authStrategy = workspace.getAtomService().getAuthStrategy(); authStrategy = workspace.getAtomService().getAuthStrategy();
parseCollectionElement(e); parseCollectionElement(e);
} }
ClientCollection(String href, AuthStrategy authStrategy) throws ProponoException { ClientCollection(final String href, final AuthStrategy authStrategy) throws ProponoException {
super("Standalone connection", "text", href); super("Standalone connection", "text", href);
this.authStrategy = authStrategy; this.authStrategy = authStrategy;
try { try {
httpClient = new HttpClient(new MultiThreadedHttpConnectionManager()); httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());
// TODO: make connection timeout configurable // TODO: make connection timeout configurable
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(30000); httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(30000);
} catch (Throwable t) { } catch (final Throwable t) {
throw new ProponoException("ERROR creating HTTPClient", t); throw new ProponoException("ERROR creating HTTPClient", t);
} }
} }
void addAuthentication(HttpMethodBase method) throws ProponoException { void addAuthentication(final HttpMethodBase method) throws ProponoException {
authStrategy.addAuthentication(httpClient, method); authStrategy.addAuthentication(httpClient, method);
} }
@ -83,34 +84,32 @@ public class ClientCollection extends Collection {
} }
/** /**
* Get iterator over entries in this collection. Entries returned are * Get iterator over entries in this collection. Entries returned are considered to be partial entries cannot be saved/updated.
* considered to be partial entries cannot be saved/updated.
*/ */
public Iterator getEntries() throws ProponoException { public Iterator getEntries() throws ProponoException {
return new EntryIterator(this); return new EntryIterator(this);
} }
/** /**
* Get full entry specified by entry edit URI. * Get full entry specified by entry edit URI. Note that entry may or may not be associated with this collection.
* Note that entry may or may not be associated with this collection. *
* @return ClientEntry or ClientMediaEntry specified by URI. * @return ClientEntry or ClientMediaEntry specified by URI.
*/ */
public ClientEntry getEntry(String uri) throws ProponoException { public ClientEntry getEntry(final String uri) throws ProponoException {
GetMethod method = new GetMethod(uri); final GetMethod method = new GetMethod(uri);
authStrategy.addAuthentication(httpClient, method); authStrategy.addAuthentication(httpClient, method);
try { try {
httpClient.executeMethod(method); httpClient.executeMethod(method);
if (method.getStatusCode() != 200) { if (method.getStatusCode() != 200) {
throw new ProponoException("ERROR HTTP status code=" + method.getStatusCode()); throw new ProponoException("ERROR HTTP status code=" + method.getStatusCode());
} }
Entry romeEntry = Atom10Parser.parseEntry( final Entry romeEntry = Atom10Parser.parseEntry(new InputStreamReader(method.getResponseBodyAsStream()), uri);
new InputStreamReader(method.getResponseBodyAsStream()), uri);
if (!romeEntry.isMediaEntry()) { if (!romeEntry.isMediaEntry()) {
return new ClientEntry(service, this, romeEntry, false); return new ClientEntry(service, this, romeEntry, false);
} else { } else {
return new ClientMediaEntry(service, this, romeEntry, false); return new ClientMediaEntry(service, this, romeEntry, false);
} }
} catch (Exception e) { } catch (final Exception e) {
throw new ProponoException("ERROR: getting or parsing entry/media, HTTP code: ", e); throw new ProponoException("ERROR: getting or parsing entry/media, HTTP code: ", e);
} finally { } finally {
method.releaseConnection(); method.releaseConnection();
@ -133,64 +132,72 @@ public class ClientCollection extends Collection {
/** /**
* Create new entry associated with collection, but do not save to server. * Create new entry associated with collection, but do not save to server.
*
* @throws ProponoException if collecton is not writable. * @throws ProponoException if collecton is not writable.
*/ */
public ClientEntry createEntry() throws ProponoException { public ClientEntry createEntry() throws ProponoException {
if (!isWritable()) throw new ProponoException("Collection is not writable"); if (!isWritable()) {
throw new ProponoException("Collection is not writable");
}
return new ClientEntry(service, this); return new ClientEntry(service, this);
} }
/** /**
* Create new media entry assocaited with collection, but do not save. * Create new media entry assocaited with collection, but do not save. server. Depending on the Atom server, you may or may not be able to persist the
* server. Depending on the Atom server, you may or may not be able to * properties of the entry that is returned.
* persist the properties of the entry that is returned. *
* @param title Title to used for uploaded file. * @param title Title to used for uploaded file.
* @param slug String to be used in file-name of stored file * @param slug String to be used in file-name of stored file
* @param contentType MIME content-type of file. * @param contentType MIME content-type of file.
* @param bytes Data to be uploaded as byte array. * @param bytes Data to be uploaded as byte array.
* @throws ProponoException if collecton is not writable * @throws ProponoException if collecton is not writable
*/ */
public ClientMediaEntry createMediaEntry( public ClientMediaEntry createMediaEntry(final String title, final String slug, final String contentType, final byte[] bytes) throws ProponoException {
String title, String slug, String contentType, byte[] bytes) if (!isWritable()) {
throws ProponoException { throw new ProponoException("Collection is not writable");
if (!isWritable()) throw new ProponoException("Collection is not writable"); }
return new ClientMediaEntry(service, this, title, slug, contentType, bytes); return new ClientMediaEntry(service, this, title, slug, contentType, bytes);
} }
/** /**
* Create new media entry assocaited with collection, but do not save. * Create new media entry assocaited with collection, but do not save. server. Depending on the Atom server, you may or may not be able to. persist the
* server. Depending on the Atom server, you may or may not be able to. * properties of the entry that is returned.
* persist the properties of the entry that is returned. *
* @param title Title to used for uploaded file. * @param title Title to used for uploaded file.
* @param slug String to be used in file-name of stored file * @param slug String to be used in file-name of stored file
* @param contentType MIME content-type of file. * @param contentType MIME content-type of file.
* @param is Data to be uploaded as InputStream. * @param is Data to be uploaded as InputStream.
* @throws ProponoException if collecton is not writable * @throws ProponoException if collecton is not writable
*/ */
public ClientMediaEntry createMediaEntry( public ClientMediaEntry createMediaEntry(final String title, final String slug, final String contentType, final InputStream is) throws ProponoException {
String title, String slug, String contentType, InputStream is) if (!isWritable()) {
throws ProponoException { throw new ProponoException("Collection is not writable");
if (!isWritable()) throw new ProponoException("Collection is not writable"); }
return new ClientMediaEntry(service, this, title, slug, contentType, is); return new ClientMediaEntry(service, this, title, slug, contentType, is);
} }
/** /**
* Save to collection a new entry that was created by a createEntry() * Save to collection a new entry that was created by a createEntry() or createMediaEntry() and save it to the server.
* or createMediaEntry() and save it to the server. *
* @param entry Entry to be saved. * @param entry Entry to be saved.
* @throws ProponoException on error, if collection is not writable or if entry is partial. * @throws ProponoException on error, if collection is not writable or if entry is partial.
*/ */
public void addEntry(ClientEntry entry) throws ProponoException { public void addEntry(final ClientEntry entry) throws ProponoException {
if (!isWritable()) throw new ProponoException("Collection is not writable"); if (!isWritable()) {
throw new ProponoException("Collection is not writable");
}
entry.addToCollection(this); entry.addToCollection(this);
} }
protected void parseCollectionElement(Element element) throws ProponoException { @Override
if (workspace == null) return; protected void parseCollectionElement(final Element element) throws ProponoException {
if (workspace == null) {
return;
}
setHref(element.getAttribute("href").getValue()); setHref(element.getAttribute("href").getValue());
Element titleElem = element.getChild("title", AtomService.ATOM_FORMAT); final Element titleElem = element.getChild("title", AtomService.ATOM_FORMAT);
if (titleElem != null) { if (titleElem != null) {
setTitle(titleElem.getText()); setTitle(titleElem.getText());
if (titleElem.getAttribute("type", AtomService.ATOM_FORMAT) != null) { if (titleElem.getAttribute("type", AtomService.ATOM_FORMAT) != null) {
@ -198,19 +205,19 @@ public class ClientCollection extends Collection {
} }
} }
List acceptElems = element.getChildren("accept", AtomService.ATOM_PROTOCOL); final List acceptElems = element.getChildren("accept", AtomService.ATOM_PROTOCOL);
if (acceptElems != null && acceptElems.size() > 0) { if (acceptElems != null && acceptElems.size() > 0) {
for (Iterator it = acceptElems.iterator(); it.hasNext();) { for (final Iterator it = acceptElems.iterator(); it.hasNext();) {
Element acceptElem = (Element)it.next(); final Element acceptElem = (Element) it.next();
addAccept(acceptElem.getTextTrim()); addAccept(acceptElem.getTextTrim());
} }
} }
// Loop to parse <app:categories> element to Categories objects // Loop to parse <app:categories> element to Categories objects
List catsElems = element.getChildren("categories", AtomService.ATOM_PROTOCOL); final List catsElems = element.getChildren("categories", AtomService.ATOM_PROTOCOL);
for (Iterator catsIter = catsElems.iterator(); catsIter.hasNext();) { for (final Iterator catsIter = catsElems.iterator(); catsIter.hasNext();) {
Element catsElem = (Element) catsIter.next(); final Element catsElem = (Element) catsIter.next();
Categories cats = new ClientCategories(catsElem, this); final Categories cats = new ClientCategories(catsElem, this);
addCategories(cats); addCategories(cats);
} }
} }

View file

@ -15,94 +15,92 @@
*/ */
package org.rometools.propono.atom.client; package org.rometools.propono.atom.client;
import com.sun.syndication.feed.atom.Content;
import com.sun.syndication.feed.atom.Link;
import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.io.impl.Atom10Generator;
import com.sun.syndication.io.impl.Atom10Parser;
import org.rometools.propono.utils.ProponoException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.StringWriter; import java.io.StringWriter;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rometools.propono.utils.Utilities;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethodBase; import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rometools.propono.utils.ProponoException;
import org.rometools.propono.utils.Utilities;
import com.sun.syndication.feed.atom.Content;
import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.feed.atom.Link;
import com.sun.syndication.io.impl.Atom10Generator;
import com.sun.syndication.io.impl.Atom10Parser;
/** /**
* Client implementation of Atom entry, extends ROME Entry to add methods for * Client implementation of Atom entry, extends ROME Entry to add methods for easily getting/setting content, updating and removing the entry from the server.
* easily getting/setting content, updating and removing the entry from the server.
*/ */
public class ClientEntry extends Entry { public class ClientEntry extends Entry {
private static final Log logger = LogFactory.getLog(ClientEntry.class); private static final Log logger = LogFactory.getLog(ClientEntry.class);
boolean partial = false; boolean partial = false;
private ClientAtomService service = null; private ClientAtomService service = null;
private ClientCollection collection = null; private ClientCollection collection = null;
public ClientEntry(ClientAtomService service, ClientCollection collection) { public ClientEntry(final ClientAtomService service, final ClientCollection collection) {
super(); super();
this.service = service; this.service = service;
this.collection = collection; this.collection = collection;
} }
public ClientEntry(ClientAtomService service, ClientCollection collection, public ClientEntry(final ClientAtomService service, final ClientCollection collection, final Entry entry, final boolean partial) throws ProponoException {
Entry entry, boolean partial) throws ProponoException {
super(); super();
this.service = service; this.service = service;
this.collection = collection; this.collection = collection;
this.partial = partial; this.partial = partial;
try { try {
BeanUtils.copyProperties(this, entry); BeanUtils.copyProperties(this, entry);
} catch (Exception e) { } catch (final Exception e) {
throw new ProponoException("ERROR: copying fields from ROME entry", e); throw new ProponoException("ERROR: copying fields from ROME entry", e);
} }
} }
/** /**
* Set content of entry. * Set content of entry.
*
* @param contentString content string. * @param contentString content string.
* @param type Must be "text" for plain text, "html" for escaped HTML, * @param type Must be "text" for plain text, "html" for escaped HTML, "xhtml" for XHTML or a valid MIME content-type.
* "xhtml" for XHTML or a valid MIME content-type.
*/ */
public void setContent(String contentString, String type) { public void setContent(final String contentString, final String type) {
Content newContent = new Content(); final Content newContent = new Content();
newContent.setType(type == null ? Content.HTML : type); newContent.setType(type == null ? Content.HTML : type);
newContent.setValue(contentString); newContent.setValue(contentString);
ArrayList contents = new ArrayList(); final ArrayList contents = new ArrayList();
contents.add(newContent); contents.add(newContent);
setContents(contents); setContents(contents);
} }
/** /**
* Convenience method to set first content object in content collection. * Convenience method to set first content object in content collection. Atom 1.0 allows only one content element per entry.
* Atom 1.0 allows only one content element per entry.
*/ */
public void setContent(Content c) { public void setContent(final Content c) {
ArrayList contents = new ArrayList(); final ArrayList contents = new ArrayList();
contents.add(c); contents.add(c);
setContents(contents); setContents(contents);
} }
/** /**
* Convenience method to get first content object in content collection. * Convenience method to get first content object in content collection. Atom 1.0 allows only one content element per entry.
* Atom 1.0 allows only one content element per entry.
*/ */
public Content getContent() { public Content getContent() {
if (getContents() != null && getContents().size() > 0) { if (getContents() != null && getContents().size() > 0) {
Content c = (Content)getContents().get(0); final Content c = getContents().get(0);
return c; return c;
} }
return null; return null;
@ -111,9 +109,10 @@ public class ClientEntry extends Entry {
/** /**
* Determines if entries are equal based on edit URI. * Determines if entries are equal based on edit URI.
*/ */
public boolean equals(Object o) { @Override
public boolean equals(final Object o) {
if (o instanceof ClientEntry) { if (o instanceof ClientEntry) {
ClientEntry other = (ClientEntry)o; final ClientEntry other = (ClientEntry) o;
if (other.getEditURI() != null && getEditURI() != null) { if (other.getEditURI() != null && getEditURI() != null) {
return other.getEditURI().equals(getEditURI()); return other.getEditURI().equals(getEditURI());
} }
@ -122,35 +121,32 @@ public class ClientEntry extends Entry {
} }
/** /**
* Update entry by posting new representation of entry to server. * Update entry by posting new representation of entry to server. Note that you should not attempt to update entries that you get from iterating over a
* Note that you should not attempt to update entries that you get from * collection they may be "partial" entries. If you want to update an entry, you must get it via one of the <code>getEntry()</code> methods in
* iterating over a collection they may be "partial" entries. If you want * {@link com.sun.syndication.propono.atom.common.Collection} or {@link com.sun.syndication.propono.atom.common.AtomService}.
* to update an entry, you must get it via one of the <code>getEntry()</code> *
* methods in
* {@link com.sun.syndication.propono.atom.common.Collection} or
* {@link com.sun.syndication.propono.atom.common.AtomService}.
* @throws ProponoException If entry is a "partial" entry. * @throws ProponoException If entry is a "partial" entry.
*/ */
public void update() throws ProponoException { public void update() throws ProponoException {
if (partial) throw new ProponoException("ERROR: attempt to update partial entry"); if (partial) {
EntityEnclosingMethod method = new PutMethod(getEditURI()); throw new ProponoException("ERROR: attempt to update partial entry");
}
final EntityEnclosingMethod method = new PutMethod(getEditURI());
addAuthentication(method); addAuthentication(method);
StringWriter sw = new StringWriter(); final StringWriter sw = new StringWriter();
int code = -1; final int code = -1;
try { try {
Atom10Generator.serializeEntry(this, sw); Atom10Generator.serializeEntry(this, sw);
method.setRequestEntity(new StringRequestEntity(sw.toString())); method.setRequestEntity(new StringRequestEntity(sw.toString()));
method.setRequestHeader( method.setRequestHeader("Content-type", "application/atom+xml; charset=utf-8");
"Content-type", "application/atom+xml; charset=utf-8");
getHttpClient().executeMethod(method); getHttpClient().executeMethod(method);
InputStream is = method.getResponseBodyAsStream(); final InputStream is = method.getResponseBodyAsStream();
if (method.getStatusCode() != 200 && method.getStatusCode() != 201) { if (method.getStatusCode() != 200 && method.getStatusCode() != 201) {
throw new ProponoException( throw new ProponoException("ERROR HTTP status=" + method.getStatusCode() + " : " + Utilities.streamToString(is));
"ERROR HTTP status=" + method.getStatusCode() + " : " + Utilities.streamToString(is));
} }
} catch (Exception e) { } catch (final Exception e) {
String msg = "ERROR: updating entry, HTTP code: " + code; final String msg = "ERROR: updating entry, HTTP code: " + code;
logger.debug(msg, e); logger.debug(msg, e);
throw new ProponoException(msg, e); throw new ProponoException(msg, e);
} finally { } finally {
@ -165,18 +161,18 @@ public class ClientEntry extends Entry {
if (getEditURI() == null) { if (getEditURI() == null) {
throw new ProponoException("ERROR: cannot delete unsaved entry"); throw new ProponoException("ERROR: cannot delete unsaved entry");
} }
DeleteMethod method = new DeleteMethod(getEditURI()); final DeleteMethod method = new DeleteMethod(getEditURI());
addAuthentication(method); addAuthentication(method);
try { try {
getHttpClient().executeMethod(method); getHttpClient().executeMethod(method);
} catch (IOException ex) { } catch (final IOException ex) {
throw new ProponoException("ERROR: removing entry, HTTP code", ex); throw new ProponoException("ERROR: removing entry, HTTP code", ex);
} finally { } finally {
method.releaseConnection(); method.releaseConnection();
} }
} }
void setCollection(ClientCollection collection) { void setCollection(final ClientCollection collection) {
this.collection = collection; this.collection = collection;
} }
@ -188,8 +184,8 @@ public class ClientEntry extends Entry {
* Get the URI that can be used to edit the entry via HTTP PUT or DELETE. * Get the URI that can be used to edit the entry via HTTP PUT or DELETE.
*/ */
public String getEditURI() { public String getEditURI() {
for (int i=0; i<getOtherLinks().size(); i++) { for (int i = 0; i < getOtherLinks().size(); i++) {
Link link = (Link)getOtherLinks().get(i); final Link link = getOtherLinks().get(i);
if (link.getRel() != null && link.getRel().equals("edit")) { if (link.getRel() != null && link.getRel().equals("edit")) {
return link.getHrefResolved(); return link.getHrefResolved();
} }
@ -197,41 +193,38 @@ public class ClientEntry extends Entry {
return null; return null;
} }
void addToCollection(ClientCollection col) throws ProponoException { void addToCollection(final ClientCollection col) throws ProponoException {
setCollection(col); setCollection(col);
EntityEnclosingMethod method = new PostMethod(getCollection().getHrefResolved()); final EntityEnclosingMethod method = new PostMethod(getCollection().getHrefResolved());
addAuthentication(method); addAuthentication(method);
StringWriter sw = new StringWriter(); final StringWriter sw = new StringWriter();
int code = -1; int code = -1;
try { try {
Atom10Generator.serializeEntry(this, sw); Atom10Generator.serializeEntry(this, sw);
method.setRequestEntity(new StringRequestEntity(sw.toString())); method.setRequestEntity(new StringRequestEntity(sw.toString()));
method.setRequestHeader( method.setRequestHeader("Content-type", "application/atom+xml; charset=utf-8");
"Content-type", "application/atom+xml; charset=utf-8");
getHttpClient().executeMethod(method); getHttpClient().executeMethod(method);
InputStream is = method.getResponseBodyAsStream(); final InputStream is = method.getResponseBodyAsStream();
code = method.getStatusCode(); code = method.getStatusCode();
if (code != 200 && code != 201) { if (code != 200 && code != 201) {
throw new ProponoException( throw new ProponoException("ERROR HTTP status=" + code + " : " + Utilities.streamToString(is));
"ERROR HTTP status=" + code + " : " + Utilities.streamToString(is));
} }
Entry romeEntry = Atom10Parser.parseEntry( final Entry romeEntry = Atom10Parser.parseEntry(new InputStreamReader(is), getCollection().getHrefResolved());
new InputStreamReader(is), getCollection().getHrefResolved());
BeanUtils.copyProperties(this, romeEntry); BeanUtils.copyProperties(this, romeEntry);
} catch (Exception e) { } catch (final Exception e) {
String msg = "ERROR: saving entry, HTTP code: " + code; final String msg = "ERROR: saving entry, HTTP code: " + code;
logger.debug(msg, e); logger.debug(msg, e);
throw new ProponoException(msg, e); throw new ProponoException(msg, e);
} finally { } finally {
method.releaseConnection(); method.releaseConnection();
} }
Header locationHeader = method.getResponseHeader("Location"); final Header locationHeader = method.getResponseHeader("Location");
if (locationHeader == null) { if (locationHeader == null) {
logger.warn("WARNING added entry, but no location header returned"); logger.warn("WARNING added entry, but no location header returned");
} else if (getEditURI() == null) { } else if (getEditURI() == null) {
List links = getOtherLinks(); final List links = getOtherLinks();
Link link = new Link(); final Link link = new Link();
link.setHref(locationHeader.getValue()); link.setHref(locationHeader.getValue());
link.setRel("edit"); link.setRel("edit");
links.add(link); links.add(link);
@ -239,7 +232,7 @@ public class ClientEntry extends Entry {
} }
} }
void addAuthentication(HttpMethodBase method) throws ProponoException { void addAuthentication(final HttpMethodBase method) throws ProponoException {
if (service != null) { if (service != null) {
service.addAuthentication(method); service.addAuthentication(method);
} else if (collection != null) { } else if (collection != null) {

View file

@ -15,40 +15,41 @@
*/ */
package org.rometools.propono.atom.client; package org.rometools.propono.atom.client;
import com.sun.syndication.feed.atom.Content;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom2.JDOMException;
import org.rometools.propono.utils.ProponoException;
import org.rometools.propono.utils.Utilities;
import com.sun.syndication.feed.atom.Content;
import com.sun.syndication.feed.atom.Entry; import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.feed.atom.Link; import com.sun.syndication.feed.atom.Link;
import com.sun.syndication.io.FeedException; import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.impl.Atom10Generator; import com.sun.syndication.io.impl.Atom10Generator;
import com.sun.syndication.io.impl.Atom10Parser; import com.sun.syndication.io.impl.Atom10Parser;
import org.rometools.propono.utils.ProponoException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringWriter;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.rometools.propono.utils.Utilities;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom2.JDOMException;
/** /**
* Client implementation of Atom media-link entry, an Atom entry that provides * Client implementation of Atom media-link entry, an Atom entry that provides meta-data for a media file (e.g. uploaded image or audio file).
* meta-data for a media file (e.g. uploaded image or audio file).
*/ */
public class ClientMediaEntry extends ClientEntry { public class ClientMediaEntry extends ClientEntry {
private static final Log logger = LogFactory.getLog(ClientMediaEntry.class); private static final Log logger = LogFactory.getLog(ClientMediaEntry.class);
private String slug = null; private String slug = null;
private byte[] bytes; private byte[] bytes;
@ -57,43 +58,44 @@ public class ClientMediaEntry extends ClientEntry {
/** /**
* Create ClientMedieEntry for service and collection. * Create ClientMedieEntry for service and collection.
*/ */
public ClientMediaEntry(ClientAtomService service, ClientCollection collection) { public ClientMediaEntry(final ClientAtomService service, final ClientCollection collection) {
super(service, collection); super(service, collection);
} }
public ClientMediaEntry(ClientAtomService service, ClientCollection collection, public ClientMediaEntry(final ClientAtomService service, final ClientCollection collection, final Entry entry, final boolean partial)
Entry entry, boolean partial) throws ProponoException { throws ProponoException {
super(service, collection, entry, partial); super(service, collection, entry, partial);
} }
public ClientMediaEntry(ClientAtomService service, ClientCollection collection, public ClientMediaEntry(final ClientAtomService service, final ClientCollection collection, final String title, final String slug,
String title, String slug, String contentType, InputStream is) { final String contentType, final InputStream is) {
this(service, collection); this(service, collection);
this.inputStream = is; inputStream = is;
setTitle(title); setTitle(title);
setSlug(slug); setSlug(slug);
Content content = new Content(); final Content content = new Content();
content.setType(contentType); content.setType(contentType);
List contents = new ArrayList(); final List contents = new ArrayList();
contents.add(content); contents.add(content);
setContents(contents); setContents(contents);
} }
public ClientMediaEntry(ClientAtomService service, ClientCollection collection, public ClientMediaEntry(final ClientAtomService service, final ClientCollection collection, final String title, final String slug,
String title, String slug, String contentType, byte[] bytes) { final String contentType, final byte[] bytes) {
this(service, collection); this(service, collection);
this.bytes = bytes; this.bytes = bytes;
setTitle(title); setTitle(title);
setSlug(slug); setSlug(slug);
Content content = new Content(); final Content content = new Content();
content.setType(contentType); content.setType(contentType);
List contents = new ArrayList(); final List contents = new ArrayList();
contents.add(content); contents.add(content);
setContents(contents); setContents(contents);
} }
/** /**
* Get bytes of media resource associated with entry. * Get bytes of media resource associated with entry.
*
* @return Bytes or null if none available or if entry uses an InputStream instead. * @return Bytes or null if none available or if entry uses an InputStream instead.
*/ */
public byte[] getBytes() { public byte[] getBytes() {
@ -101,10 +103,9 @@ public class ClientMediaEntry extends ClientEntry {
} }
/** /**
* Set media resource data as a byte array, don't try this if you have already * Set media resource data as a byte array, don't try this if you have already set the data as an InputStream.
* set the data as an InputStream.
*/ */
public void setBytes(byte[] bytes) { public void setBytes(final byte[] bytes) {
if (inputStream != null) { if (inputStream != null) {
throw new IllegalStateException("ERROR: already has inputStream, cannot set both inputStream and bytes"); throw new IllegalStateException("ERROR: already has inputStream, cannot set both inputStream and bytes");
} }
@ -113,6 +114,7 @@ public class ClientMediaEntry extends ClientEntry {
/** /**
* Get input stream for media resource associated with this entry. * Get input stream for media resource associated with this entry.
*
* @return InputStream or null if none available or if entry uses bytes instead. * @return InputStream or null if none available or if entry uses bytes instead.
*/ */
public InputStream getInputStream() { public InputStream getInputStream() {
@ -120,10 +122,9 @@ public class ClientMediaEntry extends ClientEntry {
} }
/** /**
* Set media resource data as an input stream, don't try this if you have already * Set media resource data as an input stream, don't try this if you have already set the data as a byte array.
* set the data as a byte array.
*/ */
public void setInputStream(InputStream inputStream) { public void setInputStream(final InputStream inputStream) {
if (bytes != null) { if (bytes != null) {
throw new IllegalStateException("ERROR: already has bytes, cannot set both bytes and inputStream"); throw new IllegalStateException("ERROR: already has bytes, cannot set both bytes and inputStream");
} }
@ -131,12 +132,11 @@ public class ClientMediaEntry extends ClientEntry {
} }
/** /**
* Get media link URI for editing the media resource associated with this * Get media link URI for editing the media resource associated with this entry via HTTP PUT or DELETE.
* entry via HTTP PUT or DELETE.
*/ */
public String getMediaLinkURI() { public String getMediaLinkURI() {
for (int i=0; i<getOtherLinks().size(); i++) { for (int i = 0; i < getOtherLinks().size(); i++) {
Link link = (Link)getOtherLinks().get(i); final Link link = getOtherLinks().get(i);
if (link.getRel() != null && link.getRel().equals("edit-media")) { if (link.getRel() != null && link.getRel().equals("edit-media")) {
return link.getHrefResolved(); return link.getHrefResolved();
} }
@ -145,12 +145,11 @@ public class ClientMediaEntry extends ClientEntry {
} }
/** /**
* Get media resource as an InputStream, should work regardless of whether * Get media resource as an InputStream, should work regardless of whether you set the media resource data as an InputStream or as a byte array.
* you set the media resource data as an InputStream or as a byte array.
*/ */
public InputStream getAsStream() throws ProponoException { public InputStream getAsStream() throws ProponoException {
if (getContents() != null && getContents().size() > 0) { if (getContents() != null && getContents().size() > 0) {
Content c = (Content)getContents().get(0); final Content c = getContents().get(0);
if (c.getSrc() != null) { if (c.getSrc() != null) {
return getResourceAsStream(); return getResourceAsStream();
} else if (inputStream != null) { } else if (inputStream != null) {
@ -160,8 +159,7 @@ public class ClientMediaEntry extends ClientEntry {
} else { } else {
throw new ProponoException("ERROR: no src URI or binary data to return"); throw new ProponoException("ERROR: no src URI or binary data to return");
} }
} } else {
else {
throw new ProponoException("ERROR: no content found in entry"); throw new ProponoException("ERROR: no content found in entry");
} }
} }
@ -170,14 +168,14 @@ public class ClientMediaEntry extends ClientEntry {
if (getEditURI() == null) { if (getEditURI() == null) {
throw new ProponoException("ERROR: not yet saved to server"); throw new ProponoException("ERROR: not yet saved to server");
} }
GetMethod method = new GetMethod(((Content)getContents()).getSrc()); final GetMethod method = new GetMethod(((Content) getContents()).getSrc());
try { try {
getCollection().getHttpClient().executeMethod(method); getCollection().getHttpClient().executeMethod(method);
if (method.getStatusCode() != 200) { if (method.getStatusCode() != 200) {
throw new ProponoException("ERROR HTTP status=" + method.getStatusCode()); throw new ProponoException("ERROR HTTP status=" + method.getStatusCode());
} }
return method.getResponseBodyAsStream(); return method.getResponseBodyAsStream();
} catch (IOException e) { } catch (final IOException e) {
throw new ProponoException("ERROR: getting media entry", e); throw new ProponoException("ERROR: getting media entry", e);
} }
} }
@ -185,10 +183,13 @@ public class ClientMediaEntry extends ClientEntry {
/** /**
* Update entry on server. * Update entry on server.
*/ */
@Override
public void update() throws ProponoException { public void update() throws ProponoException {
if (partial) throw new ProponoException("ERROR: attempt to update partial entry"); if (partial) {
throw new ProponoException("ERROR: attempt to update partial entry");
}
EntityEnclosingMethod method = null; EntityEnclosingMethod method = null;
Content updateContent = (Content)getContents().get(0); final Content updateContent = getContents().get(0);
try { try {
if (getMediaLinkURI() != null && getBytes() != null) { if (getMediaLinkURI() != null && getBytes() != null) {
// existing media entry and new file, so PUT file to edit-media URI // existing media entry and new file, so PUT file to edit-media URI
@ -200,29 +201,28 @@ public class ClientMediaEntry extends ClientEntry {
} }
method.setRequestHeader("Content-type", updateContent.getType()); method.setRequestHeader("Content-type", updateContent.getType());
} } else if (getEditURI() != null) {
else if (getEditURI() != null) {
// existing media entry and NO new file, so PUT entry to edit URI // existing media entry and NO new file, so PUT entry to edit URI
method = new PutMethod(getEditURI()); method = new PutMethod(getEditURI());
StringWriter sw = new StringWriter(); final StringWriter sw = new StringWriter();
Atom10Generator.serializeEntry(this, sw); Atom10Generator.serializeEntry(this, sw);
method.setRequestEntity(new StringRequestEntity(sw.toString())); method.setRequestEntity(new StringRequestEntity(sw.toString()));
method.setRequestHeader( method.setRequestHeader("Content-type", "application/atom+xml; charset=utf8");
"Content-type", "application/atom+xml; charset=utf8");
} else { } else {
throw new ProponoException("ERROR: media entry has no edit URI or media-link URI"); throw new ProponoException("ERROR: media entry has no edit URI or media-link URI");
} }
this.getCollection().addAuthentication(method); getCollection().addAuthentication(method);
method.addRequestHeader("Title", getTitle()); method.addRequestHeader("Title", getTitle());
getCollection().getHttpClient().executeMethod(method); getCollection().getHttpClient().executeMethod(method);
if (inputStream != null) inputStream.close(); if (inputStream != null) {
InputStream is = method.getResponseBodyAsStream(); inputStream.close();
}
final InputStream is = method.getResponseBodyAsStream();
if (method.getStatusCode() != 200 && method.getStatusCode() != 201) { if (method.getStatusCode() != 200 && method.getStatusCode() != 201) {
throw new ProponoException( throw new ProponoException("ERROR HTTP status=" + method.getStatusCode() + " : " + Utilities.streamToString(is));
"ERROR HTTP status=" + method.getStatusCode() + " : " + Utilities.streamToString(is));
} }
} catch (Exception e) { } catch (final Exception e) {
throw new ProponoException("ERROR: saving media entry"); throw new ProponoException("ERROR: saving media entry");
} }
if (method.getStatusCode() != 201) { if (method.getStatusCode() != 201) {
@ -231,14 +231,15 @@ public class ClientMediaEntry extends ClientEntry {
} }
/** Package access, to be called by DefaultClientCollection */ /** Package access, to be called by DefaultClientCollection */
void addToCollection(ClientCollection col) throws ProponoException { @Override
void addToCollection(final ClientCollection col) throws ProponoException {
setCollection(col); setCollection(col);
EntityEnclosingMethod method = new PostMethod(col.getHrefResolved()); final EntityEnclosingMethod method = new PostMethod(col.getHrefResolved());
getCollection().addAuthentication(method); getCollection().addAuthentication(method);
StringWriter sw = new StringWriter(); final StringWriter sw = new StringWriter();
boolean error = false; final boolean error = false;
try { try {
Content c = (Content)getContents().get(0); final Content c = getContents().get(0);
if (inputStream != null) { if (inputStream != null) {
method.setRequestEntity(new InputStreamRequestEntity(inputStream)); method.setRequestEntity(new InputStreamRequestEntity(inputStream));
} else { } else {
@ -248,35 +249,34 @@ public class ClientMediaEntry extends ClientEntry {
method.setRequestHeader("Title", getTitle()); method.setRequestHeader("Title", getTitle());
method.setRequestHeader("Slug", getSlug()); method.setRequestHeader("Slug", getSlug());
getCollection().getHttpClient().executeMethod(method); getCollection().getHttpClient().executeMethod(method);
if (inputStream != null) inputStream.close(); if (inputStream != null) {
InputStream is = method.getResponseBodyAsStream(); inputStream.close();
}
final InputStream is = method.getResponseBodyAsStream();
if (method.getStatusCode() == 200 || method.getStatusCode() == 201) { if (method.getStatusCode() == 200 || method.getStatusCode() == 201) {
Entry romeEntry = Atom10Parser.parseEntry( final Entry romeEntry = Atom10Parser.parseEntry(new InputStreamReader(is), col.getHrefResolved());
new InputStreamReader(is), col.getHrefResolved());
BeanUtils.copyProperties(this, romeEntry); BeanUtils.copyProperties(this, romeEntry);
} else { } else {
throw new ProponoException( throw new ProponoException("ERROR HTTP status-code=" + method.getStatusCode() + " status-line: " + method.getStatusLine());
"ERROR HTTP status-code=" + method.getStatusCode()
+ " status-line: " + method.getStatusLine());
} }
} catch (IOException ie) { } catch (final IOException ie) {
throw new ProponoException("ERROR: saving media entry", ie); throw new ProponoException("ERROR: saving media entry", ie);
} catch (JDOMException je) { } catch (final JDOMException je) {
throw new ProponoException("ERROR: saving media entry", je); throw new ProponoException("ERROR: saving media entry", je);
} catch (FeedException fe) { } catch (final FeedException fe) {
throw new ProponoException("ERROR: saving media entry", fe); throw new ProponoException("ERROR: saving media entry", fe);
} catch (IllegalAccessException ae) { } catch (final IllegalAccessException ae) {
throw new ProponoException("ERROR: saving media entry", ae); throw new ProponoException("ERROR: saving media entry", ae);
} catch (InvocationTargetException te) { } catch (final InvocationTargetException te) {
throw new ProponoException("ERROR: saving media entry", te); throw new ProponoException("ERROR: saving media entry", te);
} }
Header locationHeader = method.getResponseHeader("Location"); final Header locationHeader = method.getResponseHeader("Location");
if (locationHeader == null) { if (locationHeader == null) {
logger.warn("WARNING added entry, but no location header returned"); logger.warn("WARNING added entry, but no location header returned");
} else if (getEditURI() == null) { } else if (getEditURI() == null) {
List links = getOtherLinks(); final List links = getOtherLinks();
Link link = new Link(); final Link link = new Link();
link.setHref(locationHeader.getValue()); link.setHref(locationHeader.getValue());
link.setRel("edit"); link.setRel("edit");
links.add(link); links.add(link);
@ -290,33 +290,8 @@ public class ClientMediaEntry extends ClientEntry {
} }
/** Get string to be used in file name of new media resource on server. */ /** Get string to be used in file name of new media resource on server. */
public void setSlug(String slug) { public void setSlug(final String slug) {
this.slug = slug; this.slug = slug;
} }
} }

View file

@ -15,28 +15,22 @@
*/ */
package org.rometools.propono.atom.client; package org.rometools.propono.atom.client;
import org.rometools.propono.atom.common.AtomService;
import org.rometools.propono.atom.common.Workspace;
import org.rometools.propono.atom.common.Workspace;
import org.rometools.propono.utils.ProponoException;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.jdom2.Element;
import org.jdom2.Element;
import org.rometools.propono.atom.common.AtomService;
import org.rometools.propono.atom.common.Workspace;
import org.rometools.propono.utils.ProponoException;
/** /**
* Represents Atom protocol workspace on client-side. * Represents Atom protocol workspace on client-side. It extends the common {@link com.sun.syndication.propono.atom.common.Workspace} to return
* It extends the common * {@link com.sun.syndication.propono.atom.client.ClientCollection} objects instead of common {@link com.sun.syndication.propono.atom.common.Collection}s.
* {@link com.sun.syndication.propono.atom.common.Workspace}
* to return
* {@link com.sun.syndication.propono.atom.client.ClientCollection}
* objects instead of common
* {@link com.sun.syndication.propono.atom.common.Collection}s.
*/ */
public class ClientWorkspace extends Workspace { public class ClientWorkspace extends Workspace {
private ClientAtomService atomService = null; private ClientAtomService atomService = null;
ClientWorkspace(Element e, ClientAtomService atomService, String baseURI) throws ProponoException { ClientWorkspace(final Element e, final ClientAtomService atomService, final String baseURI) throws ProponoException {
super("dummy", "dummy"); super("dummy", "dummy");
this.atomService = atomService; this.atomService = atomService;
parseWorkspaceElement(e, baseURI); parseWorkspaceElement(e, baseURI);
@ -50,16 +44,16 @@ public class ClientWorkspace extends Workspace {
} }
/** Deserialize a Atom workspace XML element into an object */ /** Deserialize a Atom workspace XML element into an object */
protected void parseWorkspaceElement(Element element, String baseURI) throws ProponoException { protected void parseWorkspaceElement(final Element element, final String baseURI) throws ProponoException {
Element titleElem = element.getChild("title", AtomService.ATOM_FORMAT); final Element titleElem = element.getChild("title", AtomService.ATOM_FORMAT);
setTitle(titleElem.getText()); setTitle(titleElem.getText());
if (titleElem.getAttribute("type", AtomService.ATOM_FORMAT) != null) { if (titleElem.getAttribute("type", AtomService.ATOM_FORMAT) != null) {
setTitleType(titleElem.getAttribute("type", AtomService.ATOM_FORMAT).getValue()); setTitleType(titleElem.getAttribute("type", AtomService.ATOM_FORMAT).getValue());
} }
List collections = element.getChildren("collection", AtomService.ATOM_PROTOCOL); final List collections = element.getChildren("collection", AtomService.ATOM_PROTOCOL);
Iterator iter = collections.iterator(); final Iterator iter = collections.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
Element e = (Element) iter.next(); final Element e = (Element) iter.next();
addCollection(new ClientCollection(e, this, baseURI)); addCollection(new ClientCollection(e, this, baseURI));
} }
} }

View file

@ -15,20 +15,21 @@
*/ */
package org.rometools.propono.atom.client; package org.rometools.propono.atom.client;
import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.feed.atom.Feed;
import com.sun.syndication.feed.atom.Link;
import com.sun.syndication.io.WireFeedInput;
import org.rometools.propono.utils.ProponoException;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.jdom2.Document; import org.jdom2.Document;
import org.jdom2.input.SAXBuilder; import org.jdom2.input.SAXBuilder;
import org.rometools.propono.utils.ProponoException;
import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.feed.atom.Feed;
import com.sun.syndication.feed.atom.Link;
import com.sun.syndication.io.WireFeedInput;
/** /**
* Enables iteration over entries in Atom protocol collection. * Enables iteration over entries in Atom protocol collection.
@ -37,14 +38,14 @@ public class EntryIterator implements Iterator {
static final Log logger = LogFactory.getLog(EntryIterator.class); static final Log logger = LogFactory.getLog(EntryIterator.class);
private final ClientCollection collection; private final ClientCollection collection;
int maxEntries = 20; int maxEntries = 20;
int offset = 0; int offset = 0;
Iterator members = null; Iterator members = null;
Feed col = null; Feed col = null;
String collectionURI; String collectionURI;
String nextURI; String nextURI;
EntryIterator(ClientCollection collection) throws ProponoException { EntryIterator(final ClientCollection collection) throws ProponoException {
this.collection = collection; this.collection = collection;
collectionURI = collection.getHrefResolved(); collectionURI = collection.getHrefResolved();
nextURI = collectionURI; nextURI = collectionURI;
@ -54,11 +55,12 @@ public class EntryIterator implements Iterator {
/** /**
* Returns true if more entries are available. * Returns true if more entries are available.
*/ */
@Override
public boolean hasNext() { public boolean hasNext() {
if (!members.hasNext()) { if (!members.hasNext()) {
try { try {
getNextEntries(); getNextEntries();
} catch (Exception ignored) { } catch (final Exception ignored) {
logger.error("ERROR getting next entries", ignored); logger.error("ERROR getting next entries", ignored);
} }
} }
@ -68,16 +70,17 @@ public class EntryIterator implements Iterator {
/** /**
* Get next entry in collection. * Get next entry in collection.
*/ */
@Override
public Object next() { public Object next() {
if (hasNext()) { if (hasNext()) {
Entry romeEntry = (Entry)members.next(); final Entry romeEntry = (Entry) members.next();
try { try {
if (!romeEntry.isMediaEntry()) { if (!romeEntry.isMediaEntry()) {
return new ClientEntry(null, collection, romeEntry, true); return new ClientEntry(null, collection, romeEntry, true);
} else { } else {
return new ClientMediaEntry(null, collection, romeEntry, true); return new ClientMediaEntry(null, collection, romeEntry, true);
} }
} catch (ProponoException e) { } catch (final ProponoException e) {
throw new RuntimeException("Unexpected exception creating ClientEntry or ClientMedia", e); throw new RuntimeException("Unexpected exception creating ClientEntry or ClientMedia", e);
} }
} }
@ -87,21 +90,24 @@ public class EntryIterator implements Iterator {
/** /**
* Remove entry is not implemented. * Remove entry is not implemented.
*/ */
@Override
public void remove() { public void remove() {
// optional method, not implemented // optional method, not implemented
} }
private void getNextEntries() throws ProponoException { private void getNextEntries() throws ProponoException {
if (nextURI == null) return; if (nextURI == null) {
GetMethod colGet = new GetMethod( collection.getHrefResolved(nextURI) ); return;
}
final GetMethod colGet = new GetMethod(collection.getHrefResolved(nextURI));
collection.addAuthentication(colGet); collection.addAuthentication(colGet);
try { try {
collection.getHttpClient().executeMethod(colGet); collection.getHttpClient().executeMethod(colGet);
SAXBuilder builder = new SAXBuilder(); final SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(colGet.getResponseBodyAsStream()); final Document doc = builder.build(colGet.getResponseBodyAsStream());
WireFeedInput feedInput = new WireFeedInput(); final WireFeedInput feedInput = new WireFeedInput();
col = (Feed) feedInput.build(doc); col = (Feed) feedInput.build(doc);
} catch (Exception e) { } catch (final Exception e) {
throw new ProponoException("ERROR: fetching or parsing next entries, HTTP code: " + (colGet != null ? colGet.getStatusCode() : -1), e); throw new ProponoException("ERROR: fetching or parsing next entries, HTTP code: " + (colGet != null ? colGet.getStatusCode() : -1), e);
} finally { } finally {
colGet.releaseConnection(); colGet.releaseConnection();
@ -110,11 +116,11 @@ public class EntryIterator implements Iterator {
offset += col.getEntries().size(); offset += col.getEntries().size();
nextURI = null; nextURI = null;
List altLinks = col.getOtherLinks(); final List altLinks = col.getOtherLinks();
if (altLinks != null) { if (altLinks != null) {
Iterator iter = altLinks.iterator(); final Iterator iter = altLinks.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
Link link = (Link)iter.next(); final Link link = (Link) iter.next();
if ("next".equals(link.getRel())) { if ("next".equals(link.getRel())) {
nextURI = link.getHref(); nextURI = link.getHref();
} }

View file

@ -15,20 +15,19 @@
*/ */
package org.rometools.propono.atom.client; package org.rometools.propono.atom.client;
import org.rometools.propono.utils.ProponoException;
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethodBase; import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.PostMethod;
import org.rometools.propono.utils.ProponoException;
public class GDataAuthStrategy implements AuthStrategy { public class GDataAuthStrategy implements AuthStrategy {
private String email; private final String email;
private String password; private final String password;
private String service; private final String service;
private String authToken; private String authToken;
public GDataAuthStrategy(String email, String password, String service) throws ProponoException { public GDataAuthStrategy(final String email, final String password, final String service) throws ProponoException {
this.email = email; this.email = email;
this.password = password; this.password = password;
this.service = service; this.service = service;
@ -37,30 +36,27 @@ public class GDataAuthStrategy implements AuthStrategy {
private void init() throws ProponoException { private void init() throws ProponoException {
try { try {
HttpClient httpClient = new HttpClient(); final HttpClient httpClient = new HttpClient();
PostMethod method = new PostMethod("https://www.google.com/accounts/ClientLogin"); final PostMethod method = new PostMethod("https://www.google.com/accounts/ClientLogin");
NameValuePair[] data = { final NameValuePair[] data = { new NameValuePair("Email", email), new NameValuePair("Passwd", password),
new NameValuePair("Email", email), new NameValuePair("accountType", "GOOGLE"), new NameValuePair("service", service),
new NameValuePair("Passwd", password), new NameValuePair("source", "ROME Propono Atompub Client") };
new NameValuePair("accountType", "GOOGLE"),
new NameValuePair("service", service),
new NameValuePair("source", "ROME Propono Atompub Client")
};
method.setRequestBody(data); method.setRequestBody(data);
httpClient.executeMethod(method); httpClient.executeMethod(method);
String responseBody = method.getResponseBodyAsString(); final String responseBody = method.getResponseBodyAsString();
int authIndex = responseBody.indexOf("Auth="); final int authIndex = responseBody.indexOf("Auth=");
authToken = "GoogleLogin auth=" + responseBody.trim().substring(authIndex + 5); authToken = "GoogleLogin auth=" + responseBody.trim().substring(authIndex + 5);
} catch (Throwable t) { } catch (final Throwable t) {
t.printStackTrace(); t.printStackTrace();
throw new ProponoException("ERROR obtaining Google authentication string", t); throw new ProponoException("ERROR obtaining Google authentication string", t);
} }
} }
public void addAuthentication(HttpClient httpClient, HttpMethodBase method) throws ProponoException { @Override
public void addAuthentication(final HttpClient httpClient, final HttpMethodBase method) throws ProponoException {
httpClient.getParams().setAuthenticationPreemptive(true); httpClient.getParams().setAuthenticationPreemptive(true);
method.setRequestHeader("Authorization", authToken); method.setRequestHeader("Authorization", authToken);
} }

View file

@ -15,16 +15,17 @@
*/ */
package org.rometools.propono.atom.client; package org.rometools.propono.atom.client;
import org.rometools.propono.utils.ProponoException;
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethodBase; import org.apache.commons.httpclient.HttpMethodBase;
import org.rometools.propono.utils.ProponoException;
/** /**
* No authentication * No authentication
*/ */
public class NoAuthStrategy implements AuthStrategy { public class NoAuthStrategy implements AuthStrategy {
public void addAuthentication(HttpClient httpClient, HttpMethodBase method) throws ProponoException { @Override
public void addAuthentication(final HttpClient httpClient, final HttpMethodBase method) throws ProponoException {
// no-op // no-op
} }

View file

@ -15,7 +15,6 @@
*/ */
package org.rometools.propono.atom.client; package org.rometools.propono.atom.client;
import org.rometools.propono.utils.ProponoException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
@ -23,18 +22,20 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import net.oauth.OAuth; import net.oauth.OAuth;
import net.oauth.OAuthAccessor; import net.oauth.OAuthAccessor;
import net.oauth.OAuthConsumer; import net.oauth.OAuthConsumer;
import net.oauth.OAuthMessage; import net.oauth.OAuthMessage;
import net.oauth.OAuthServiceProvider; import net.oauth.OAuthServiceProvider;
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethodBase; import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.util.ParameterParser; import org.apache.commons.httpclient.util.ParameterParser;
import org.rometools.propono.utils.ProponoException;
/** /**
* Strategy for using OAuth. * Strategy for using OAuth.
@ -44,55 +45,53 @@ public class OAuthStrategy implements AuthStrategy {
private State state = State.UNAUTHORIZED; private State state = State.UNAUTHORIZED;
private enum State { private enum State {
UNAUTHORIZED, // have not sent any requests UNAUTHORIZED, // have not sent any requests
REQUEST_TOKEN, // have a request token REQUEST_TOKEN, // have a request token
AUTHORIZED, // are authorized AUTHORIZED, // are authorized
ACCESS_TOKEN // have access token, ready to make calls ACCESS_TOKEN // have access token, ready to make calls
} }
private String username; private final String username;
private String consumerKey; private final String consumerKey;
private String consumerSecret; private final String consumerSecret;
private String keyType; private final String keyType;
private String reqUrl; private final String reqUrl;
private String authzUrl; private final String authzUrl;
private String accessUrl; private final String accessUrl;
private String nonce; private final String nonce;
private long timestamp; private final long timestamp;
private String requestToken = null; private String requestToken = null;
private String accessToken = null; private String accessToken = null;
private String tokenSecret = null; private String tokenSecret = null;
/** /**
* Create OAuth authentcation strategy and negotiate with services to * Create OAuth authentcation strategy and negotiate with services to obtain access token to be used in subsequent calls.
* obtain access token to be used in subsequent calls.
* *
* @param username Username to be used in authentication * @param username Username to be used in authentication
* @param key Consumer key * @param key Consumer key
* @param secret Consumer secret * @param secret Consumer secret
* @param keyType Key type (e.g. "HMAC-SHA1") * @param keyType Key type (e.g. "HMAC-SHA1")
* @param reqUrl URL of request token service * @param reqUrl URL of request token service
* @param authzUrl URL of authorize service * @param authzUrl URL of authorize service
* @param accessUrl URL of acess token service * @param accessUrl URL of acess token service
* @throws ProponoException on any sort of initialization error * @throws ProponoException on any sort of initialization error
*/ */
public OAuthStrategy( public OAuthStrategy(final String username, final String key, final String secret, final String keyType, final String reqUrl, final String authzUrl,
String username, String key, String secret, String keyType, final String accessUrl) throws ProponoException {
String reqUrl, String authzUrl, String accessUrl) throws ProponoException {
this.username = username; this.username = username;
this.reqUrl = reqUrl; this.reqUrl = reqUrl;
this.authzUrl = authzUrl; this.authzUrl = authzUrl;
this.accessUrl = accessUrl; this.accessUrl = accessUrl;
this.consumerKey = key; consumerKey = key;
this.consumerSecret = secret; consumerSecret = secret;
this.keyType = keyType; this.keyType = keyType;
this.nonce = UUID.randomUUID().toString(); nonce = UUID.randomUUID().toString();
this.timestamp = (long)(new Date().getTime()/1000L); timestamp = new Date().getTime() / 1000L;
init(); init();
} }
@ -103,7 +102,8 @@ public class OAuthStrategy implements AuthStrategy {
callOAuthUri(accessUrl); callOAuthUri(accessUrl);
} }
public void addAuthentication(HttpClient httpClient, HttpMethodBase method) throws ProponoException { @Override
public void addAuthentication(final HttpClient httpClient, final HttpMethodBase method) throws ProponoException {
if (state != State.ACCESS_TOKEN) { if (state != State.ACCESS_TOKEN) {
throw new ProponoException("ERROR: authentication strategy failed init"); throw new ProponoException("ERROR: authentication strategy failed init");
@ -122,9 +122,9 @@ public class OAuthStrategy implements AuthStrategy {
} }
// put query string into hashmap form to please OAuth.net classes // put query string into hashmap form to please OAuth.net classes
Map params = new HashMap(); final Map params = new HashMap();
for (Iterator it = originalqlist.iterator(); it.hasNext();) { for (final Iterator it = originalqlist.iterator(); it.hasNext();) {
NameValuePair pair = (NameValuePair)it.next(); final NameValuePair pair = (NameValuePair) it.next();
params.put(pair.getName(), pair.getValue()); params.put(pair.getName(), pair.getValue());
} }
@ -139,21 +139,18 @@ public class OAuthStrategy implements AuthStrategy {
// sign complete URI // sign complete URI
String finalUri = null; String finalUri = null;
OAuthServiceProvider provider = final OAuthServiceProvider provider = new OAuthServiceProvider(reqUrl, authzUrl, accessUrl);
new OAuthServiceProvider(reqUrl, authzUrl, accessUrl); final OAuthConsumer consumer = new OAuthConsumer(null, consumerKey, consumerSecret, provider);
OAuthConsumer consumer = final OAuthAccessor accessor = new OAuthAccessor(consumer);
new OAuthConsumer(null, consumerKey, consumerSecret, provider);
OAuthAccessor accessor = new OAuthAccessor(consumer);
accessor.tokenSecret = tokenSecret; accessor.tokenSecret = tokenSecret;
OAuthMessage message; OAuthMessage message;
try { try {
message = new OAuthMessage( message = new OAuthMessage(method.getName(), method.getURI().toString(), params.entrySet());
method.getName(), method.getURI().toString(), params.entrySet());
message.sign(accessor); message.sign(accessor);
finalUri = OAuth.addParameters(message.URL, message.getParameters()); finalUri = OAuth.addParameters(message.URL, message.getParameters());
} catch (Exception ex) { } catch (final Exception ex) {
throw new ProponoException("ERROR: OAuth signing request", ex); throw new ProponoException("ERROR: OAuth signing request", ex);
} }
@ -161,8 +158,7 @@ public class OAuthStrategy implements AuthStrategy {
method.setQueryString(finalUri.substring(finalUri.lastIndexOf("?"))); method.setQueryString(finalUri.substring(finalUri.lastIndexOf("?")));
} }
private void callOAuthUri(final String uri) throws ProponoException {
private void callOAuthUri(String uri) throws ProponoException {
final HttpClient httpClient = new HttpClient(); final HttpClient httpClient = new HttpClient();
@ -183,24 +179,22 @@ public class OAuthStrategy implements AuthStrategy {
params.put("oauth_nonce", nonce); params.put("oauth_nonce", nonce);
params.put("oauth_callback", "none"); params.put("oauth_callback", "none");
OAuthServiceProvider provider = final OAuthServiceProvider provider = new OAuthServiceProvider(reqUrl, authzUrl, accessUrl);
new OAuthServiceProvider(reqUrl, authzUrl, accessUrl); final OAuthConsumer consumer = new OAuthConsumer(null, consumerKey, consumerSecret, provider);
OAuthConsumer consumer = final OAuthAccessor accessor = new OAuthAccessor(consumer);
new OAuthConsumer(null, consumerKey, consumerSecret, provider);
OAuthAccessor accessor = new OAuthAccessor(consumer);
if (state == State.UNAUTHORIZED) { if (state == State.UNAUTHORIZED) {
try { try {
OAuthMessage message = new OAuthMessage("GET", uri, params.entrySet()); final OAuthMessage message = new OAuthMessage("GET", uri, params.entrySet());
message.sign(accessor); message.sign(accessor);
String finalUri = OAuth.addParameters(message.URL, message.getParameters()); final String finalUri = OAuth.addParameters(message.URL, message.getParameters());
method = new GetMethod(finalUri); method = new GetMethod(finalUri);
httpClient.executeMethod(method); httpClient.executeMethod(method);
content = method.getResponseBodyAsString(); content = method.getResponseBodyAsString();
} catch (Exception e) { } catch (final Exception e) {
throw new ProponoException("ERROR fetching request token", e); throw new ProponoException("ERROR fetching request token", e);
} }
@ -211,15 +205,15 @@ public class OAuthStrategy implements AuthStrategy {
params.put("oauth_token_secret", tokenSecret); params.put("oauth_token_secret", tokenSecret);
accessor.tokenSecret = tokenSecret; accessor.tokenSecret = tokenSecret;
OAuthMessage message = new OAuthMessage("POST", uri, params.entrySet()); final OAuthMessage message = new OAuthMessage("POST", uri, params.entrySet());
message.sign(accessor); message.sign(accessor);
String finalUri = OAuth.addParameters(message.URL, message.getParameters()); final String finalUri = OAuth.addParameters(message.URL, message.getParameters());
method = new PostMethod(finalUri); method = new PostMethod(finalUri);
httpClient.executeMethod(method); httpClient.executeMethod(method);
content = method.getResponseBodyAsString(); content = method.getResponseBodyAsString();
} catch (Exception e) { } catch (final Exception e) {
throw new ProponoException("ERROR fetching request token", e); throw new ProponoException("ERROR fetching request token", e);
} }
@ -230,15 +224,15 @@ public class OAuthStrategy implements AuthStrategy {
params.put("oauth_token_secret", tokenSecret); params.put("oauth_token_secret", tokenSecret);
accessor.tokenSecret = tokenSecret; accessor.tokenSecret = tokenSecret;
OAuthMessage message = new OAuthMessage("GET", uri, params.entrySet()); final OAuthMessage message = new OAuthMessage("GET", uri, params.entrySet());
message.sign(accessor); message.sign(accessor);
String finalUri = OAuth.addParameters(message.URL, message.getParameters()); final String finalUri = OAuth.addParameters(message.URL, message.getParameters());
method = new GetMethod(finalUri); method = new GetMethod(finalUri);
httpClient.executeMethod(method); httpClient.executeMethod(method);
content = method.getResponseBodyAsString(); content = method.getResponseBodyAsString();
} catch (Exception e) { } catch (final Exception e) {
throw new ProponoException("ERROR fetching request token", e); throw new ProponoException("ERROR fetching request token", e);
} }
@ -248,14 +242,13 @@ public class OAuthStrategy implements AuthStrategy {
return; return;
} }
String token = null; String token = null;
String secret = null; String secret = null;
if (content != null) { if (content != null) {
String[] settings = content.split("&"); final String[] settings = content.split("&");
for (int i=0; i<settings.length; i++) { for (final String setting2 : settings) {
String[] setting = settings[i].split("="); final String[] setting = setting2.split("=");
if (setting.length > 1) { if (setting.length > 1) {
if ("oauth_token".equals(setting[0])) { if ("oauth_token".equals(setting[0])) {
token = setting[1]; token = setting[1];
@ -268,35 +261,33 @@ public class OAuthStrategy implements AuthStrategy {
switch (state) { switch (state) {
case UNAUTHORIZED: case UNAUTHORIZED:
if (token != null && secret != null) { if (token != null && secret != null) {
requestToken = token; requestToken = token;
tokenSecret = secret; tokenSecret = secret;
state = State.REQUEST_TOKEN; state = State.REQUEST_TOKEN;
} else { } else {
throw new ProponoException("ERROR: requestToken or tokenSecret is null"); throw new ProponoException("ERROR: requestToken or tokenSecret is null");
} }
break; break;
case REQUEST_TOKEN: case REQUEST_TOKEN:
if (method.getStatusCode() == 200) { if (method.getStatusCode() == 200) {
state = State.AUTHORIZED; state = State.AUTHORIZED;
} else { } else {
throw new ProponoException("ERROR: authorization returned code: " + method.getStatusCode()); throw new ProponoException("ERROR: authorization returned code: " + method.getStatusCode());
} }
break; break;
case AUTHORIZED: case AUTHORIZED:
if (token != null && secret != null) { if (token != null && secret != null) {
accessToken = token; accessToken = token;
tokenSecret = secret; tokenSecret = secret;
state = State.ACCESS_TOKEN; state = State.ACCESS_TOKEN;
} else { } else {
throw new ProponoException("ERROR: accessToken or tokenSecret is null"); throw new ProponoException("ERROR: accessToken or tokenSecret is null");
} }
break; break;
} }
} }
} }

View file

@ -1,24 +1,22 @@
/* /*
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. The ASF licenses this file to You * contributor license agreements. The ASF licenses this file to You
* under the Apache License, Version 2.0 (the "License"); you may not * under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. * use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. For additional information regarding * limitations under the License. For additional information regarding
* copyright in this work, please see the NOTICE file in the top level * copyright in this work, please see the NOTICE file in the top level
* directory of this distribution. * directory of this distribution.
*/ */
package org.rometools.propono.atom.common; package org.rometools.propono.atom.common;
import org.rometools.propono.utils.ProponoException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -26,23 +24,21 @@ import java.util.List;
import org.jdom2.Document; import org.jdom2.Document;
import org.jdom2.Element; import org.jdom2.Element;
import org.jdom2.Namespace; import org.jdom2.Namespace;
import org.rometools.propono.utils.ProponoException;
/** /**
* Models an Atom Publishing Protocol Service Document. * Models an Atom Publishing Protocol Service Document. Is able to read a Service document from a JDOM Document and to write Service document out as a JDOM
* Is able to read a Service document from a JDOM Document * Document.
* and to write Service document out as a JDOM Document.
*/ */
public class AtomService { public class AtomService {
private List workspaces = new ArrayList(); private List workspaces = new ArrayList();
/** Namespace for Atom Syndication Format */ /** Namespace for Atom Syndication Format */
public static Namespace ATOM_FORMAT = public static Namespace ATOM_FORMAT = Namespace.getNamespace("atom", "http://www.w3.org/2005/Atom");
Namespace.getNamespace("atom","http://www.w3.org/2005/Atom");
/** Namespace for Atom Publishing Protocol */ /** Namespace for Atom Publishing Protocol */
public static Namespace ATOM_PROTOCOL = public static Namespace ATOM_PROTOCOL = Namespace.getNamespace("app", "http://www.w3.org/2007/app");
Namespace.getNamespace("app","http://www.w3.org/2007/app");
/** /**
* Create new and empty Atom service * Create new and empty Atom service
@ -53,7 +49,7 @@ public class AtomService {
/** /**
* Add Workspace to service. * Add Workspace to service.
*/ */
public void addWorkspace(Workspace workspace) { public void addWorkspace(final Workspace workspace) {
workspaces.add(workspace); workspaces.add(workspace);
} }
@ -67,18 +63,19 @@ public class AtomService {
/** /**
* Set Workspaces of service. * Set Workspaces of service.
*/ */
public void setWorkspaces(List workspaces) { public void setWorkspaces(final List workspaces) {
this.workspaces = workspaces; this.workspaces = workspaces;
} }
/** /**
* Find workspace by title. * Find workspace by title.
*
* @param title Match this title * @param title Match this title
* @return Matching Workspace or null if none found. * @return Matching Workspace or null if none found.
*/ */
public Workspace findWorkspace(String title) { public Workspace findWorkspace(final String title) {
for (Iterator it = workspaces.iterator(); it.hasNext();) { for (final Iterator it = workspaces.iterator(); it.hasNext();) {
Workspace ws = (Workspace) it.next(); final Workspace ws = (Workspace) it.next();
if (title.equals(ws.getTitle())) { if (title.equals(ws.getTitle())) {
return ws; return ws;
} }
@ -89,13 +86,13 @@ public class AtomService {
/** /**
* Deserialize an Atom service XML document into an object * Deserialize an Atom service XML document into an object
*/ */
public static AtomService documentToService(Document document) throws ProponoException { public static AtomService documentToService(final Document document) throws ProponoException {
AtomService service = new AtomService(); final AtomService service = new AtomService();
Element root = document.getRootElement(); final Element root = document.getRootElement();
List spaces = root.getChildren("workspace", ATOM_PROTOCOL); final List spaces = root.getChildren("workspace", ATOM_PROTOCOL);
Iterator iter = spaces.iterator(); final Iterator iter = spaces.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
Element e = (Element) iter.next(); final Element e = (Element) iter.next();
service.addWorkspace(Workspace.elementToWorkspace(e)); service.addWorkspace(Workspace.elementToWorkspace(e));
} }
return service; return service;
@ -105,18 +102,17 @@ public class AtomService {
* Serialize an AtomService object into an XML document * Serialize an AtomService object into an XML document
*/ */
public Document serviceToDocument() { public Document serviceToDocument() {
AtomService service = this; final AtomService service = this;
Document doc = new Document(); final Document doc = new Document();
Element root = new Element("service", ATOM_PROTOCOL); final Element root = new Element("service", ATOM_PROTOCOL);
doc.setRootElement(root); doc.setRootElement(root);
Iterator iter = service.getWorkspaces().iterator(); final Iterator iter = service.getWorkspaces().iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
Workspace space = (Workspace) iter.next(); final Workspace space = (Workspace) iter.next();
root.addContent(space.workspaceToElement()); root.addContent(space.workspaceToElement());
} }
return doc; return doc;
} }
} }

View file

@ -1,36 +1,36 @@
/* /*
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. The ASF licenses this file to You * contributor license agreements. The ASF licenses this file to You
* under the Apache License, Version 2.0 (the "License"); you may not * under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. * use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. For additional information regarding * limitations under the License. For additional information regarding
* copyright in this work, please see the NOTICE file in the top level * copyright in this work, please see the NOTICE file in the top level
* directory of this distribution. * directory of this distribution.
*/ */
package org.rometools.propono.atom.common; package org.rometools.propono.atom.common;
import com.sun.syndication.feed.atom.Category;
import com.sun.syndication.io.impl.Atom10Parser;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.jdom2.Element; import org.jdom2.Element;
import com.sun.syndication.feed.atom.Category;
import com.sun.syndication.io.impl.Atom10Parser;
/** /**
* Models an Atom protocol Categories element, which may contain ROME Atom * Models an Atom protocol Categories element, which may contain ROME Atom {@link com.sun.syndication.feed.atom.Category} elements.
* {@link com.sun.syndication.feed.atom.Category} elements.
*/ */
public class Categories { public class Categories {
private List categories = new ArrayList(); // of Category objects private final List categories = new ArrayList(); // of Category objects
private String baseURI = null; private String baseURI = null;
private Element categoriesElement = null; private Element categoriesElement = null;
private String href = null; private String href = null;
@ -41,19 +41,20 @@ public class Categories {
} }
/** Load select from XML element */ /** Load select from XML element */
public Categories(Element e, String baseURI) { public Categories(final Element e, final String baseURI) {
this.categoriesElement = e; categoriesElement = e;
this.baseURI = baseURI; this.baseURI = baseURI;
parseCategoriesElement(e); parseCategoriesElement(e);
} }
/** Add category list of those specified */ /** Add category list of those specified */
public void addCategory(Category cat) { public void addCategory(final Category cat) {
categories.add(cat); categories.add(cat);
} }
/** /**
* Iterate over Category objects * Iterate over Category objects
*
* @return List of ROME Atom {@link com.sun.syndication.feed.atom.Category} * @return List of ROME Atom {@link com.sun.syndication.feed.atom.Category}
*/ */
public List getCategories() { public List getCategories() {
@ -66,7 +67,7 @@ public class Categories {
} }
/** True if clients MUST use one of the categories specified */ /** True if clients MUST use one of the categories specified */
public void setFixed(boolean fixed) { public void setFixed(final boolean fixed) {
this.fixed = fixed; this.fixed = fixed;
} }
@ -76,7 +77,7 @@ public class Categories {
} }
/** Category URI scheme to use for Categories without a scheme */ /** Category URI scheme to use for Categories without a scheme */
public void setScheme(String scheme) { public void setScheme(final String scheme) {
this.scheme = scheme; this.scheme = scheme;
} }
@ -86,7 +87,7 @@ public class Categories {
} }
/** URI of out-of-line categories */ /** URI of out-of-line categories */
public void setHref(String href) { public void setHref(final String href) {
this.href = href; this.href = href;
} }
@ -95,15 +96,14 @@ public class Categories {
if (Atom10Parser.isAbsoluteURI(href)) { if (Atom10Parser.isAbsoluteURI(href)) {
return href; return href;
} else if (baseURI != null && categoriesElement != null) { } else if (baseURI != null && categoriesElement != null) {
return Atom10Parser.resolveURI( return Atom10Parser.resolveURI(baseURI, categoriesElement, href);
baseURI, categoriesElement, href);
} }
return null; return null;
} }
public Element categoriesToElement() { public Element categoriesToElement() {
Categories cats = this; final Categories cats = this;
Element catsElem = new Element("categories", AtomService.ATOM_PROTOCOL); final Element catsElem = new Element("categories", AtomService.ATOM_PROTOCOL);
catsElem.setAttribute("fixed", cats.isFixed() ? "yes" : "no", AtomService.ATOM_PROTOCOL); catsElem.setAttribute("fixed", cats.isFixed() ? "yes" : "no", AtomService.ATOM_PROTOCOL);
if (cats.getScheme() != null) { if (cats.getScheme() != null) {
catsElem.setAttribute("scheme", cats.getScheme(), AtomService.ATOM_PROTOCOL); catsElem.setAttribute("scheme", cats.getScheme(), AtomService.ATOM_PROTOCOL);
@ -112,9 +112,9 @@ public class Categories {
catsElem.setAttribute("href", cats.getHref(), AtomService.ATOM_PROTOCOL); catsElem.setAttribute("href", cats.getHref(), AtomService.ATOM_PROTOCOL);
} else { } else {
// Loop to create <atom:category> elements // Loop to create <atom:category> elements
for (Iterator catIter = cats.getCategories().iterator(); catIter.hasNext();) { for (final Iterator catIter = cats.getCategories().iterator(); catIter.hasNext();) {
Category cat = (Category) catIter.next(); final Category cat = (Category) catIter.next();
Element catElem = new Element("category", AtomService.ATOM_FORMAT); final Element catElem = new Element("category", AtomService.ATOM_FORMAT);
catElem.setAttribute("term", cat.getTerm(), AtomService.ATOM_FORMAT); catElem.setAttribute("term", cat.getTerm(), AtomService.ATOM_FORMAT);
if (cat.getScheme() != null) { // optional if (cat.getScheme() != null) { // optional
catElem.setAttribute("scheme", cat.getScheme(), AtomService.ATOM_FORMAT); catElem.setAttribute("scheme", cat.getScheme(), AtomService.ATOM_FORMAT);
@ -128,23 +128,23 @@ public class Categories {
return catsElem; return catsElem;
} }
protected void parseCategoriesElement(Element catsElem) { protected void parseCategoriesElement(final Element catsElem) {
if (catsElem.getAttribute("href", AtomService.ATOM_PROTOCOL) != null) { if (catsElem.getAttribute("href", AtomService.ATOM_PROTOCOL) != null) {
setHref(catsElem.getAttribute("href", AtomService.ATOM_PROTOCOL).getValue()); setHref(catsElem.getAttribute("href", AtomService.ATOM_PROTOCOL).getValue());
} }
if (catsElem.getAttribute("fixed", AtomService.ATOM_PROTOCOL) != null) { if (catsElem.getAttribute("fixed", AtomService.ATOM_PROTOCOL) != null) {
if ("yes".equals(catsElem.getAttribute("fixed", AtomService.ATOM_PROTOCOL).getValue())) { if ("yes".equals(catsElem.getAttribute("fixed", AtomService.ATOM_PROTOCOL).getValue())) {
setFixed(true); setFixed(true);
} }
} }
if (catsElem.getAttribute("scheme", AtomService.ATOM_PROTOCOL) != null) { if (catsElem.getAttribute("scheme", AtomService.ATOM_PROTOCOL) != null) {
setScheme(catsElem.getAttribute("scheme", AtomService.ATOM_PROTOCOL).getValue()); setScheme(catsElem.getAttribute("scheme", AtomService.ATOM_PROTOCOL).getValue());
} }
// Loop to parse <atom:category> elemenents to Category objects // Loop to parse <atom:category> elemenents to Category objects
List catElems = catsElem.getChildren("category", AtomService.ATOM_FORMAT); final List catElems = catsElem.getChildren("category", AtomService.ATOM_FORMAT);
for (Iterator catIter = catElems.iterator(); catIter.hasNext();) { for (final Iterator catIter = catElems.iterator(); catIter.hasNext();) {
Element catElem = (Element) catIter.next(); final Element catElem = (Element) catIter.next();
Category cat = new Category(); final Category cat = new Category();
cat.setTerm(catElem.getAttributeValue("term", AtomService.ATOM_FORMAT)); cat.setTerm(catElem.getAttributeValue("term", AtomService.ATOM_FORMAT));
cat.setLabel(catElem.getAttributeValue("label", AtomService.ATOM_FORMAT)); cat.setLabel(catElem.getAttributeValue("label", AtomService.ATOM_FORMAT));
cat.setScheme(catElem.getAttributeValue("scheme", AtomService.ATOM_FORMAT)); cat.setScheme(catElem.getAttributeValue("scheme", AtomService.ATOM_FORMAT));
@ -152,4 +152,3 @@ public class Categories {
} }
} }
} }

View file

@ -1,29 +1,30 @@
/* /*
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. The ASF licenses this file to You * contributor license agreements. The ASF licenses this file to You
* under the Apache License, Version 2.0 (the "License"); you may not * under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. * use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. For additional information regarding * limitations under the License. For additional information regarding
* copyright in this work, please see the NOTICE file in the top level * copyright in this work, please see the NOTICE file in the top level
* directory of this distribution. * directory of this distribution.
*/ */
package org.rometools.propono.atom.common; package org.rometools.propono.atom.common;
import com.sun.syndication.io.impl.Atom10Parser;
import org.rometools.propono.utils.ProponoException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.jdom2.Element;
import org.jdom2.Element;
import org.rometools.propono.utils.ProponoException;
import com.sun.syndication.io.impl.Atom10Parser;
/** /**
* Models an Atom workspace collection. * Models an Atom workspace collection.
@ -37,33 +38,34 @@ public class Collection {
private String title = null; private String title = null;
private String titleType = null; // may be TEXT, HTML, XHTML private String titleType = null; // may be TEXT, HTML, XHTML
private List accepts = new ArrayList(); // of Strings private List accepts = new ArrayList(); // of Strings
private String listTemplate = null; private final String listTemplate = null;
private String href = null; private String href = null;
private List categories = new ArrayList(); // of Categories objects private final List categories = new ArrayList(); // of Categories objects
/** /**
* Collection MUST have title and href. * Collection MUST have title and href.
* @param title Title for collection *
* @param title Title for collection
* @param titleType Content type of title (null for plain text) * @param titleType Content type of title (null for plain text)
* @param href Collection URI. * @param href Collection URI.
*/ */
public Collection(String title, String titleType, String href) { public Collection(final String title, final String titleType, final String href) {
this.title = title; this.title = title;
this.titleType = titleType; this.titleType = titleType;
this.href = href; this.href = href;
} }
/** Load self from XML element */ /** Load self from XML element */
public Collection(Element e) throws ProponoException { public Collection(final Element e) throws ProponoException {
this.collectionElement = e; collectionElement = e;
this.parseCollectionElement(e); parseCollectionElement(e);
} }
/** Load self from XML element and base URI for resolving relative URIs */ /** Load self from XML element and base URI for resolving relative URIs */
public Collection(Element e, String baseURI) throws ProponoException { public Collection(final Element e, final String baseURI) throws ProponoException {
this.collectionElement = e; collectionElement = e;
this.baseURI = baseURI; this.baseURI = baseURI;
this.parseCollectionElement(e); parseCollectionElement(e);
} }
/** /**
@ -73,11 +75,11 @@ public class Collection {
return accepts; return accepts;
} }
public void addAccept(String accept) { public void addAccept(final String accept) {
this.accepts.add(accept); accepts.add(accept);
} }
public void setAccepts(List accepts) { public void setAccepts(final List accepts) {
this.accepts = accepts; this.accepts = accepts;
} }
@ -89,7 +91,7 @@ public class Collection {
/** /**
* Set URI of collection * Set URI of collection
*/ */
public void setHref(String href) { public void setHref(final String href) {
this.href = href; this.href = href;
} }
@ -98,18 +100,18 @@ public class Collection {
if (Atom10Parser.isAbsoluteURI(href)) { if (Atom10Parser.isAbsoluteURI(href)) {
return href; return href;
} else if (baseURI != null && collectionElement != null) { } else if (baseURI != null && collectionElement != null) {
int lastslash = baseURI.lastIndexOf("/"); final int lastslash = baseURI.lastIndexOf("/");
return Atom10Parser.resolveURI(baseURI.substring(0, lastslash), collectionElement, href); return Atom10Parser.resolveURI(baseURI.substring(0, lastslash), collectionElement, href);
} }
return null; return null;
} }
/** Get resolved URI using collection's baseURI, or null if impossible to determine */ /** Get resolved URI using collection's baseURI, or null if impossible to determine */
public String getHrefResolved(String relativeUri) { public String getHrefResolved(final String relativeUri) {
if (Atom10Parser.isAbsoluteURI(relativeUri)) { if (Atom10Parser.isAbsoluteURI(relativeUri)) {
return relativeUri; return relativeUri;
} else if (baseURI != null && collectionElement != null) { } else if (baseURI != null && collectionElement != null) {
int lastslash = baseURI.lastIndexOf("/"); final int lastslash = baseURI.lastIndexOf("/");
return Atom10Parser.resolveURI(baseURI.substring(0, lastslash), collectionElement, relativeUri); return Atom10Parser.resolveURI(baseURI.substring(0, lastslash), collectionElement, relativeUri);
} }
return null; return null;
@ -123,7 +125,7 @@ public class Collection {
/** /**
* Set title of collection. * Set title of collection.
*/ */
public void setTitle(String title) { public void setTitle(final String title) {
this.title = title; this.title = title;
} }
@ -137,17 +139,18 @@ public class Collection {
/** /**
* Type of title ("text", "html" or "xhtml") * Type of title ("text", "html" or "xhtml")
*/ */
public void setTitleType(String titleType) { public void setTitleType(final String titleType) {
this.titleType = titleType; this.titleType = titleType;
} }
/** Workspace can have multiple Categories objects */ /** Workspace can have multiple Categories objects */
public void addCategories(Categories cats) { public void addCategories(final Categories cats) {
categories.add(cats); categories.add(cats);
} }
/** /**
* Get categories allowed by collection. * Get categories allowed by collection.
*
* @return Collection of {@link com.sun.syndication.propono.atom.common.Categories} objects. * @return Collection of {@link com.sun.syndication.propono.atom.common.Categories} objects.
*/ */
public List getCategories() { public List getCategories() {
@ -157,12 +160,14 @@ public class Collection {
/** /**
* Returns true if contentType is accepted by collection. * Returns true if contentType is accepted by collection.
*/ */
public boolean accepts(String ct) { public boolean accepts(final String ct) {
for (Iterator it = accepts.iterator(); it.hasNext();) { for (final Iterator it = accepts.iterator(); it.hasNext();) {
String accept = (String)it.next(); final String accept = (String) it.next();
if (accept != null && accept.trim().equals("*/*")) return true; if (accept != null && accept.trim().equals("*/*")) {
String entryType = "application/atom+xml"; return true;
boolean entry = entryType.equals(ct); }
final String entryType = "application/atom+xml";
final boolean entry = entryType.equals(ct);
if (entry && null == accept) { if (entry && null == accept) {
return true; return true;
} else if (entry && "entry".equals(accept)) { } else if (entry && "entry".equals(accept)) {
@ -170,14 +175,18 @@ public class Collection {
} else if (entry && entryType.equals(accept)) { } else if (entry && entryType.equals(accept)) {
return true; return true;
} else { } else {
String[] rules = (String[])accepts.toArray(new String[accepts.size()]); final String[] rules = (String[]) accepts.toArray(new String[accepts.size()]);
for (int i=0; i<rules.length; i++) { for (final String rule2 : rules) {
String rule = rules[i].trim(); String rule = rule2.trim();
if (rule.equals(ct)) return true; if (rule.equals(ct)) {
int slashstar = rule.indexOf("/*"); return true;
}
final int slashstar = rule.indexOf("/*");
if (slashstar > 0) { if (slashstar > 0) {
rule = rule.substring(0, slashstar + 1); rule = rule.substring(0, slashstar + 1);
if (ct.startsWith(rule)) return true; if (ct.startsWith(rule)) {
return true;
}
} }
} }
} }
@ -189,11 +198,11 @@ public class Collection {
* Serialize an AtomService.Collection into an XML element * Serialize an AtomService.Collection into an XML element
*/ */
public Element collectionToElement() { public Element collectionToElement() {
Collection collection = this; final Collection collection = this;
Element element = new Element("collection", AtomService.ATOM_PROTOCOL); final Element element = new Element("collection", AtomService.ATOM_PROTOCOL);
element.setAttribute("href", collection.getHref()); element.setAttribute("href", collection.getHref());
Element titleElem = new Element("title", AtomService.ATOM_FORMAT); final Element titleElem = new Element("title", AtomService.ATOM_FORMAT);
titleElem.setText(collection.getTitle()); titleElem.setText(collection.getTitle());
if (collection.getTitleType() != null && !collection.getTitleType().equals("TEXT")) { if (collection.getTitleType() != null && !collection.getTitleType().equals("TEXT")) {
titleElem.setAttribute("type", collection.getTitleType(), AtomService.ATOM_FORMAT); titleElem.setAttribute("type", collection.getTitleType(), AtomService.ATOM_FORMAT);
@ -201,14 +210,14 @@ public class Collection {
element.addContent(titleElem); element.addContent(titleElem);
// Loop to create <app:categories> elements // Loop to create <app:categories> elements
for (Iterator it = collection.getCategories().iterator(); it.hasNext();) { for (final Iterator it = collection.getCategories().iterator(); it.hasNext();) {
Categories cats = (Categories)it.next(); final Categories cats = (Categories) it.next();
element.addContent(cats.categoriesToElement()); element.addContent(cats.categoriesToElement());
} }
for (Iterator it = collection.getAccepts().iterator(); it.hasNext();) { for (final Iterator it = collection.getAccepts().iterator(); it.hasNext();) {
String range = (String)it.next(); final String range = (String) it.next();
Element acceptElem = new Element("accept", AtomService.ATOM_PROTOCOL); final Element acceptElem = new Element("accept", AtomService.ATOM_PROTOCOL);
acceptElem.setText(range); acceptElem.setText(range);
element.addContent(acceptElem); element.addContent(acceptElem);
} }
@ -217,14 +226,14 @@ public class Collection {
} }
/** Deserialize an Atom service collection XML element into an object */ /** Deserialize an Atom service collection XML element into an object */
public Collection elementToCollection(Element element) throws ProponoException { public Collection elementToCollection(final Element element) throws ProponoException {
return new Collection(element); return new Collection(element);
} }
protected void parseCollectionElement(Element element) throws ProponoException { protected void parseCollectionElement(final Element element) throws ProponoException {
setHref(element.getAttribute("href").getValue()); setHref(element.getAttribute("href").getValue());
Element titleElem = element.getChild("title", AtomService.ATOM_FORMAT); final Element titleElem = element.getChild("title", AtomService.ATOM_FORMAT);
if (titleElem != null) { if (titleElem != null) {
setTitle(titleElem.getText()); setTitle(titleElem.getText());
if (titleElem.getAttribute("type", AtomService.ATOM_FORMAT) != null) { if (titleElem.getAttribute("type", AtomService.ATOM_FORMAT) != null) {
@ -232,21 +241,20 @@ public class Collection {
} }
} }
List acceptElems = element.getChildren("accept", AtomService.ATOM_PROTOCOL); final List acceptElems = element.getChildren("accept", AtomService.ATOM_PROTOCOL);
if (acceptElems != null && acceptElems.size() > 0) { if (acceptElems != null && acceptElems.size() > 0) {
for (Iterator it = acceptElems.iterator(); it.hasNext();) { for (final Iterator it = acceptElems.iterator(); it.hasNext();) {
Element acceptElem = (Element)it.next(); final Element acceptElem = (Element) it.next();
addAccept(acceptElem.getTextTrim()); addAccept(acceptElem.getTextTrim());
} }
} }
// Loop to parse <app:categories> element to Categories objects // Loop to parse <app:categories> element to Categories objects
List catsElems = element.getChildren("categories", AtomService.ATOM_PROTOCOL); final List catsElems = element.getChildren("categories", AtomService.ATOM_PROTOCOL);
for (Iterator catsIter = catsElems.iterator(); catsIter.hasNext();) { for (final Iterator catsIter = catsElems.iterator(); catsIter.hasNext();) {
Element catsElem = (Element) catsIter.next(); final Element catsElem = (Element) catsIter.next();
Categories cats = new Categories(catsElem, baseURI); final Categories cats = new Categories(catsElem, baseURI);
addCategories(cats); addCategories(cats);
} }
} }
} }

View file

@ -1,28 +1,28 @@
/* /*
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. The ASF licenses this file to You * contributor license agreements. The ASF licenses this file to You
* under the Apache License, Version 2.0 (the "License"); you may not * under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. * use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. For additional information regarding * limitations under the License. For additional information regarding
* copyright in this work, please see the NOTICE file in the top level * copyright in this work, please see the NOTICE file in the top level
* directory of this distribution. * directory of this distribution.
*/ */
package org.rometools.propono.atom.common; package org.rometools.propono.atom.common;
import org.rometools.propono.utils.ProponoException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.jdom2.Element;
import org.jdom2.Element;
import org.rometools.propono.utils.ProponoException;
/** /**
* Models an Atom workspace. * Models an Atom workspace.
@ -30,19 +30,20 @@ import org.jdom2.Element;
public class Workspace { public class Workspace {
private String title = null; private String title = null;
private String titleType = null; // may be TEXT, HTML, XHTML private String titleType = null; // may be TEXT, HTML, XHTML
private List collections = new ArrayList(); private final List collections = new ArrayList();
/** /**
* Collection MUST have title. * Collection MUST have title.
* @param title Title for collection *
* @param title Title for collection
* @param titleType Content type of title (null for plain text) * @param titleType Content type of title (null for plain text)
*/ */
public Workspace(String title, String titleType) { public Workspace(final String title, final String titleType) {
this.title = title; this.title = title;
this.titleType = titleType; this.titleType = titleType;
} }
public Workspace(Element elem) throws ProponoException { public Workspace(final Element elem) throws ProponoException {
parseWorkspaceElement(elem); parseWorkspaceElement(elem);
} }
@ -52,7 +53,7 @@ public class Workspace {
} }
/** Add new collection to workspace */ /** Add new collection to workspace */
public void addCollection(Collection col) { public void addCollection(final Collection col) {
collections.add(col); collections.add(col);
} }
@ -66,7 +67,7 @@ public class Workspace {
/** /**
* Set title of workspace. * Set title of workspace.
*/ */
public void setTitle(String title) { public void setTitle(final String title) {
this.title = title; this.title = title;
} }
@ -80,19 +81,20 @@ public class Workspace {
/** /**
* Set title type ("text", "html", "xhtml" or MIME content-type) * Set title type ("text", "html", "xhtml" or MIME content-type)
*/ */
public void setTitleType(String titleType) { public void setTitleType(final String titleType) {
this.titleType = titleType; this.titleType = titleType;
} }
/** /**
* Find collection by title and/or content-type. * Find collection by title and/or content-type.
*
* @param title Title or null to match all titles. * @param title Title or null to match all titles.
* @param contentType Content-type or null to match all content-types. * @param contentType Content-type or null to match all content-types.
* @return First Collection that matches title and/or content-type. * @return First Collection that matches title and/or content-type.
*/ */
public Collection findCollection(String title, String contentType) { public Collection findCollection(final String title, final String contentType) {
for (Iterator it = collections.iterator(); it.hasNext();) { for (final Iterator it = collections.iterator(); it.hasNext();) {
Collection col = (Collection) it.next(); final Collection col = (Collection) it.next();
if (title != null && col.accepts(contentType)) { if (title != null && col.accepts(contentType)) {
return col; return col;
} else if (col.accepts(contentType)) { } else if (col.accepts(contentType)) {
@ -103,7 +105,7 @@ public class Workspace {
} }
/** Deserialize a Atom workspace XML element into an object */ /** Deserialize a Atom workspace XML element into an object */
public static Workspace elementToWorkspace(Element element) throws ProponoException { public static Workspace elementToWorkspace(final Element element) throws ProponoException {
return new Workspace(element); return new Workspace(element);
} }
@ -111,36 +113,36 @@ public class Workspace {
* Serialize an AtomService.DefaultWorkspace object into an XML element * Serialize an AtomService.DefaultWorkspace object into an XML element
*/ */
public Element workspaceToElement() { public Element workspaceToElement() {
Workspace space = this; final Workspace space = this;
Element element = new Element("workspace", AtomService.ATOM_PROTOCOL); final Element element = new Element("workspace", AtomService.ATOM_PROTOCOL);
Element titleElem = new Element("title", AtomService.ATOM_FORMAT); final Element titleElem = new Element("title", AtomService.ATOM_FORMAT);
titleElem.setText(space.getTitle()); titleElem.setText(space.getTitle());
if (space.getTitleType() != null && !space.getTitleType().equals("TEXT")) { if (space.getTitleType() != null && !space.getTitleType().equals("TEXT")) {
titleElem.setAttribute("type", space.getTitleType(), AtomService.ATOM_FORMAT); titleElem.setAttribute("type", space.getTitleType(), AtomService.ATOM_FORMAT);
} }
element.addContent(titleElem); element.addContent(titleElem);
Iterator iter = space.getCollections().iterator(); final Iterator iter = space.getCollections().iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
Collection col = (Collection) iter.next(); final Collection col = (Collection) iter.next();
element.addContent(col.collectionToElement()); element.addContent(col.collectionToElement());
} }
return element; return element;
} }
/** Deserialize a Atom workspace XML element into an object */ /** Deserialize a Atom workspace XML element into an object */
protected void parseWorkspaceElement(Element element) throws ProponoException { protected void parseWorkspaceElement(final Element element) throws ProponoException {
Element titleElem = element.getChild("title", AtomService.ATOM_FORMAT); final Element titleElem = element.getChild("title", AtomService.ATOM_FORMAT);
setTitle(titleElem.getText()); setTitle(titleElem.getText());
if (titleElem.getAttribute("type", AtomService.ATOM_FORMAT) != null) { if (titleElem.getAttribute("type", AtomService.ATOM_FORMAT) != null) {
setTitleType(titleElem.getAttribute("type", AtomService.ATOM_FORMAT).getValue()); setTitleType(titleElem.getAttribute("type", AtomService.ATOM_FORMAT).getValue());
} }
List collections = element.getChildren("collection", AtomService.ATOM_PROTOCOL); final List collections = element.getChildren("collection", AtomService.ATOM_PROTOCOL);
Iterator iter = collections.iterator(); final Iterator iter = collections.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
Element e = (Element) iter.next(); final Element e = (Element) iter.next();
addCollection(new Collection(e)); addCollection(new Collection(e));
} }
} }

View file

@ -19,9 +19,10 @@
*/ */
package org.rometools.propono.atom.common.rome; package org.rometools.propono.atom.common.rome;
import com.sun.syndication.feed.module.Module;
import java.util.Date; import java.util.Date;
import com.sun.syndication.feed.module.Module;
/** /**
* ROME Extension Module to Atom protocol extensions to Atom format. * ROME Extension Module to Atom protocol extensions to Atom format.
*/ */

View file

@ -19,27 +19,26 @@
*/ */
package org.rometools.propono.atom.common.rome; package org.rometools.propono.atom.common.rome;
import com.sun.syndication.io.impl.DateParser; import java.text.SimpleDateFormat;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Locale;
import java.util.Set; import java.util.Set;
import java.util.TimeZone;
import org.jdom2.Element; import org.jdom2.Element;
import org.jdom2.Namespace; import org.jdom2.Namespace;
import com.sun.syndication.feed.module.Module; import com.sun.syndication.feed.module.Module;
import com.sun.syndication.io.ModuleGenerator; import com.sun.syndication.io.ModuleGenerator;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.TimeZone;
/** /**
* Creates JDOM representation for APP Extension Module. * Creates JDOM representation for APP Extension Module.
*/ */
public class AppModuleGenerator implements ModuleGenerator { public class AppModuleGenerator implements ModuleGenerator {
private static final Namespace APP_NS = private static final Namespace APP_NS = Namespace.getNamespace("app", AppModule.URI);
Namespace.getNamespace("app", AppModule.URI);
@Override
public String getNamespaceUri() { public String getNamespaceUri() {
return AppModule.URI; return AppModule.URI;
} }
@ -47,38 +46,40 @@ public class AppModuleGenerator implements ModuleGenerator {
private static final Set NAMESPACES; private static final Set NAMESPACES;
static { static {
Set nss = new HashSet(); final Set nss = new HashSet();
nss.add(APP_NS); nss.add(APP_NS);
NAMESPACES = Collections.unmodifiableSet(nss); NAMESPACES = Collections.unmodifiableSet(nss);
} }
/** Get namespaces associated with this module */ /** Get namespaces associated with this module */
@Override
public Set getNamespaces() { public Set getNamespaces() {
return NAMESPACES; return NAMESPACES;
} }
/** Generate JDOM element for module and add it to parent element */ /** Generate JDOM element for module and add it to parent element */
public void generate(Module module, Element parent) { @Override
AppModule m = (AppModule)module; public void generate(final Module module, final Element parent) {
final AppModule m = (AppModule) module;
if (m.getDraft() != null) { if (m.getDraft() != null) {
String draft = m.getDraft().booleanValue() ? "yes" : "no"; final String draft = m.getDraft().booleanValue() ? "yes" : "no";
Element control = new Element("control", APP_NS); final Element control = new Element("control", APP_NS);
control.addContent(generateSimpleElement("draft", draft)); control.addContent(generateSimpleElement("draft", draft));
parent.addContent(control); parent.addContent(control);
} }
if (m.getEdited() != null) { if (m.getEdited() != null) {
Element edited = new Element("edited", APP_NS); final Element edited = new Element("edited", APP_NS);
// Inclulde millis in date/time // Inclulde millis in date/time
SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); final SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
dateFormater.setTimeZone(TimeZone.getTimeZone("GMT")); dateFormater.setTimeZone(TimeZone.getTimeZone("GMT"));
edited.addContent(dateFormater.format(m.getEdited())); edited.addContent(dateFormater.format(m.getEdited()));
parent.addContent(edited); parent.addContent(edited);
} }
} }
private Element generateSimpleElement(String name, String value) { private Element generateSimpleElement(final String name, final String value) {
Element element = new Element(name, APP_NS); final Element element = new Element(name, APP_NS);
element.addContent(value); element.addContent(value);
return element; return element;
} }

View file

@ -20,9 +20,10 @@
*/ */
package org.rometools.propono.atom.common.rome; package org.rometools.propono.atom.common.rome;
import java.util.Date;
import com.sun.syndication.feed.CopyFrom; import com.sun.syndication.feed.CopyFrom;
import com.sun.syndication.feed.module.ModuleImpl; import com.sun.syndication.feed.module.ModuleImpl;
import java.util.Date;
/** /**
* Bean representation of APP module. * Bean representation of APP module.
@ -36,33 +37,39 @@ public class AppModuleImpl extends ModuleImpl implements AppModule {
} }
/** True if entry is draft */ /** True if entry is draft */
@Override
public Boolean getDraft() { public Boolean getDraft() {
return draft ? Boolean.TRUE : Boolean.FALSE; return draft ? Boolean.TRUE : Boolean.FALSE;
} }
/** Set to true if entry is draft */ /** Set to true if entry is draft */
public void setDraft(Boolean draft) { @Override
public void setDraft(final Boolean draft) {
this.draft = draft.booleanValue(); this.draft = draft.booleanValue();
} }
/** Time of last edit */ /** Time of last edit */
@Override
public Date getEdited() { public Date getEdited() {
return edited; return edited;
} }
/** Set time of last edit */ /** Set time of last edit */
public void setEdited(Date edited) { @Override
public void setEdited(final Date edited) {
this.edited = edited; this.edited = edited;
} }
/** Get interface class of module */ /** Get interface class of module */
@Override
public Class getInterface() { public Class getInterface() {
return AppModule.class; return AppModule.class;
} }
/** Copy from other module */ /** Copy from other module */
public void copyFrom(CopyFrom obj) { @Override
AppModule m = (AppModule)obj; public void copyFrom(final CopyFrom obj) {
final AppModule m = (AppModule) obj;
setDraft(m.getDraft()); setDraft(m.getDraft());
setEdited(m.getEdited()); setEdited(m.getEdited());
} }

View file

@ -19,20 +19,20 @@
*/ */
package org.rometools.propono.atom.common.rome; package org.rometools.propono.atom.common.rome;
import com.sun.syndication.io.impl.DateParser;
import org.jdom2.Element; import org.jdom2.Element;
import org.jdom2.Namespace; import org.jdom2.Namespace;
import com.sun.syndication.feed.module.Module; import com.sun.syndication.feed.module.Module;
import com.sun.syndication.io.ModuleParser; import com.sun.syndication.io.ModuleParser;
import com.sun.syndication.io.impl.DateParser;
/** /**
* Parses APP module information from a JDOM element and into * Parses APP module information from a JDOM element and into <code>AppModule</code> form.
* <code>AppModule</code> form.
*/ */
public class AppModuleParser implements ModuleParser { public class AppModuleParser implements ModuleParser {
/** Get URI of module namespace */ /** Get URI of module namespace */
@Override
public String getNamespaceUri() { public String getNamespaceUri() {
return AppModule.URI; return AppModule.URI;
} }
@ -43,24 +43,29 @@ public class AppModuleParser implements ModuleParser {
} }
/** Parse JDOM element into module */ /** Parse JDOM element into module */
public Module parse(Element elem) { @Override
boolean foundSomething = false; public Module parse(final Element elem) {
AppModule m = new AppModuleImpl(); final boolean foundSomething = false;
Element control = elem.getChild("control", getContentNamespace()); final AppModule m = new AppModuleImpl();
final Element control = elem.getChild("control", getContentNamespace());
if (control != null) { if (control != null) {
Element draftElem = control.getChild("draft", getContentNamespace()); final Element draftElem = control.getChild("draft", getContentNamespace());
if (draftElem != null) { if (draftElem != null) {
if ("yes".equals(draftElem.getText())) m.setDraft(Boolean.TRUE); if ("yes".equals(draftElem.getText())) {
if ("no".equals(draftElem.getText())) m.setDraft(Boolean.FALSE); m.setDraft(Boolean.TRUE);
}
if ("no".equals(draftElem.getText())) {
m.setDraft(Boolean.FALSE);
}
} }
} }
Element edited = elem.getChild("edited", getContentNamespace()); final Element edited = elem.getChild("edited", getContentNamespace());
if (edited != null) { if (edited != null) {
try { try {
m.setEdited(DateParser.parseW3CDateTime(edited.getTextTrim())); m.setEdited(DateParser.parseW3CDateTime(edited.getTextTrim()));
} catch (Exception ignored) {} } catch (final Exception ignored) {
}
} }
return m; return m;
} }
} }

View file

@ -21,28 +21,30 @@ package org.rometools.propono.atom.server;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
/** /**
* Exception thrown by {@link com.sun.syndication.propono.atom.server.AtomHandler} * Exception thrown by {@link com.sun.syndication.propono.atom.server.AtomHandler} and extended by other Propono Atom exception classes.
* and extended by other Propono Atom exception classes.
*/ */
public class AtomException extends Exception { public class AtomException extends Exception {
/** Construct new exception */ /** Construct new exception */
public AtomException() { public AtomException() {
super(); super();
} }
/** Construct new exception with message */ /** Construct new exception with message */
public AtomException(String msg) { public AtomException(final String msg) {
super(msg); super(msg);
} }
/** Contruct new exception with message and wrapping existing exception */ /** Contruct new exception with message and wrapping existing exception */
public AtomException(String msg, Throwable t) { public AtomException(final String msg, final Throwable t) {
super(msg, t); super(msg, t);
} }
/** Construct new exception to wrap existing one. */ /** Construct new exception to wrap existing one. */
public AtomException(Throwable t) { public AtomException(final Throwable t) {
super(t); super(t);
} }
/* Get HTTP status code associated with exception (HTTP 500 server error) */ /* Get HTTP status code associated with exception (HTTP 500 server error) */
/** /**
* Get HTTP status associated with exception. * Get HTTP status associated with exception.

View file

@ -19,34 +19,29 @@
*/ */
package org.rometools.propono.atom.server; package org.rometools.propono.atom.server;
import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.feed.atom.Feed;
import org.rometools.propono.atom.common.AtomService; import org.rometools.propono.atom.common.AtomService;
import org.rometools.propono.atom.common.Categories; import org.rometools.propono.atom.common.Categories;
import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.feed.atom.Feed;
/** /**
* Interface for handling single Atom protocol requests. * Interface for handling single Atom protocol requests.
* *
* <p>To create your own Atom protocol implementation you must implement this * <p>
* interface and create a concrete sub-class of * To create your own Atom protocol implementation you must implement this interface and create a concrete sub-class of
* {@link com.sun.syndication.propono.atom.server.AtomHandlerFactory} * {@link com.sun.syndication.propono.atom.server.AtomHandlerFactory} which is capable of instantiating it.
* which is capable of instantiating it.</p> * </p>
*/ */
public interface AtomHandler public interface AtomHandler {
{
/** /**
* Get username of authenticated user. Return the username of the * Get username of authenticated user. Return the username of the authenticated user
* authenticated user
*/ */
public String getAuthenticatedUsername(); public String getAuthenticatedUsername();
/** /**
* Return * Return {@link com.sun.syndication.propono.atom.common.AtomService} object that contains the {@link com.sun.syndication.propono.atom.common.Workspace}
* {@link com.sun.syndication.propono.atom.common.AtomService} * objects available to the currently authenticated user and within those the {@link com.sun.syndication.propono.atom.common.Collection} avalaible.
* object that contains the
* {@link com.sun.syndication.propono.atom.common.Workspace} objects
* available to the currently authenticated user and within those the
* {@link com.sun.syndication.propono.atom.common.Collection} avalaible.
*/ */
public AtomService getAtomService(AtomRequest req) throws AtomException; public AtomService getAtomService(AtomRequest req) throws AtomException;
@ -57,13 +52,14 @@ public interface AtomHandler
/** /**
* Return collection or portion of collection specified by request. * Return collection or portion of collection specified by request.
*
* @param req Details of HTTP request * @param req Details of HTTP request
*/ */
public Feed getCollection(AtomRequest req) throws AtomException; public Feed getCollection(AtomRequest req) throws AtomException;
/** /**
* Store new entry in collection specified by request and return * Store new entry in collection specified by request and return representation of entry as it is stored on server.
* representation of entry as it is stored on server. *
* @param req Details of HTTP request * @param req Details of HTTP request
* @return Location URL of new entry * @return Location URL of new entry
*/ */
@ -71,74 +67,81 @@ public interface AtomHandler
/** /**
* Get entry specified by request. * Get entry specified by request.
*
* @param req Details of HTTP request * @param req Details of HTTP request
*/ */
public Entry getEntry(AtomRequest req) throws AtomException; public Entry getEntry(AtomRequest req) throws AtomException;
/** /**
* Get media resource specified by request. * Get media resource specified by request.
*
* @param req Details of HTTP request * @param req Details of HTTP request
*/ */
public AtomMediaResource getMediaResource(AtomRequest req) throws AtomException; public AtomMediaResource getMediaResource(AtomRequest req) throws AtomException;
/** /**
* Update entry specified by request and return new entry as represented * Update entry specified by request and return new entry as represented on the server.
* on the server. *
* @param req Details of HTTP request * @param req Details of HTTP request
*/ */
public void putEntry(AtomRequest req, Entry entry) throws AtomException; public void putEntry(AtomRequest req, Entry entry) throws AtomException;
/** /**
* Delete entry specified by request. * Delete entry specified by request.
*
* @param req Details of HTTP request * @param req Details of HTTP request
*/ */
public void deleteEntry(AtomRequest req) throws AtomException; public void deleteEntry(AtomRequest req) throws AtomException;
/** /**
* Store media data in collection specified by request, create an Atom * Store media data in collection specified by request, create an Atom media-link entry to store metadata for the new media file and return that entry to
* media-link entry to store metadata for the new media file and return * the caller.
* that entry to the caller. *
* @param req Details of HTTP request * @param req Details of HTTP request
* @param entry New entry initialzied with only title and content type * @param entry New entry initialzied with only title and content type
* @return Location URL of new media entry * @return Location URL of new media entry
*/ */
public Entry postMedia(AtomRequest req, Entry entry) throws AtomException; public Entry postMedia(AtomRequest req, Entry entry) throws AtomException;
/** /**
* Update the media file part of a media-link entry. * Update the media file part of a media-link entry.
*
* @param req Details of HTTP request * @param req Details of HTTP request
*/ */
public void putMedia(AtomRequest req) throws AtomException; public void putMedia(AtomRequest req) throws AtomException;
/** /**
* Return true if specified request represents URI of a Service Document. * Return true if specified request represents URI of a Service Document.
*
* @param req Details of HTTP request * @param req Details of HTTP request
*/ */
public boolean isAtomServiceURI(AtomRequest req); public boolean isAtomServiceURI(AtomRequest req);
/** /**
* Return true if specified request represents URI of a Categories Document. * Return true if specified request represents URI of a Categories Document.
*
* @param req Details of HTTP request * @param req Details of HTTP request
*/ */
public boolean isCategoriesURI(AtomRequest req); public boolean isCategoriesURI(AtomRequest req);
/** /**
* Return true if specified request represents URI of a collection. * Return true if specified request represents URI of a collection.
*
* @param req Details of HTTP request * @param req Details of HTTP request
*/ */
public boolean isCollectionURI(AtomRequest req); public boolean isCollectionURI(AtomRequest req);
/** /**
* Return true if specified request represents URI of an Atom entry. * Return true if specified request represents URI of an Atom entry.
*
* @param req Details of HTTP request * @param req Details of HTTP request
*/ */
public boolean isEntryURI(AtomRequest req); public boolean isEntryURI(AtomRequest req);
/** /**
* Return true if specified patrequesthinfo represents media-edit URI. * Return true if specified patrequesthinfo represents media-edit URI.
*
* @param req Details of HTTP request * @param req Details of HTTP request
*/ */
public boolean isMediaEditURI(AtomRequest req); public boolean isMediaEditURI(AtomRequest req);
} }

View file

@ -17,97 +17,74 @@ package org.rometools.propono.atom.server;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
/** /**
* Defines a factory that enables the * Defines a factory that enables the {@link com.sun.syndication.propono.atom.server.AtomServlet} to obtain an
* {@link com.sun.syndication.propono.atom.server.AtomServlet} to obtain an
* {@link com.sun.syndication.propono.atom.server.AtomHandler} that handles an Atom request. * {@link com.sun.syndication.propono.atom.server.AtomHandler} that handles an Atom request.
* *
* <p>To create your own Atom protocol implementation you must sub-class this * <p>
* class with your own factory that is capable of creating instances of your * To create your own Atom protocol implementation you must sub-class this class with your own factory that is capable of creating instances of your
* {@link com.sun.syndication.propono.atom.server.AtomHandler} impementation.</p> * {@link com.sun.syndication.propono.atom.server.AtomHandler} impementation.
* </p>
*/ */
public abstract class AtomHandlerFactory { public abstract class AtomHandlerFactory {
private static Log log = private static Log log = LogFactory.getFactory().getInstance(AtomHandlerFactory.class);
LogFactory.getFactory().getInstance(AtomHandlerFactory.class);
private static final String DEFAULT_PROPERTY_NAME = private static final String DEFAULT_PROPERTY_NAME = "com.sun.syndication.propono.atom.server.AtomHandlerFactory";
"com.sun.syndication.propono.atom.server.AtomHandlerFactory";
private static final String FALLBACK_IMPL_NAME = private static final String FALLBACK_IMPL_NAME = "com.sun.syndication.propono.atom.server.impl.FileBasedAtomHandlerFactory";
"com.sun.syndication.propono.atom.server.impl.FileBasedAtomHandlerFactory";
/* /*
* <p>Protected constructor to prevent instantiation. * <p>Protected constructor to prevent instantiation. Use {@link #newInstance()}.</p>
* Use {@link #newInstance()}.</p>
*/ */
protected AtomHandlerFactory() { protected AtomHandlerFactory() {
} }
/** /**
* Obtain a new instance of a <code>AtomHandlerFactory</code>. This static * Obtain a new instance of a <code>AtomHandlerFactory</code>. This static method creates a new factory instance. This method uses the following ordered
* method creates a new factory instance. This method uses the following * lookup procedure to determine the <code>AtomHandlerFactory</code> implementation class to load:
* ordered lookup procedure to determine the <code>AtomHandlerFactory</code>
* implementation class to load:
* <ul> * <ul>
* <li> * <li>
* Use the <code>com.sun.syndication.propono.atom.server.AtomHandlerFactory</code> * Use the <code>com.sun.syndication.propono.atom.server.AtomHandlerFactory</code> system property.</li>
* system property. * <li>
* </li> * Use the properties file "/propono.properties" in the classpath. This configuration file is in standard <code>java.util.Properties</code> format and
* <li> * contains the fully qualified name of the implementation class with the key being the system property defined above.
* Use the properties file "/propono.properties" in the classpath.
* This configuration file is in standard <code>java.util.Properties</code>
* format and contains the fully qualified name of the implementation
* class with the key being the system property defined above.
* *
* The propono.properties file is read only once by Propono and it's * The propono.properties file is read only once by Propono and it's values are then cached for future use. If the file does not exist when the first
* values are then cached for future use. If the file does not exist * attempt is made to read from it, no further attempts are made to check for its existence. It is not possible to change the value of any property in
* when the first attempt is made to read from it, no further attempts * propono.properties after it has been read for the first time.</li>
* are made to check for its existence. It is not possible to change * <li>
* the value of any property in propono.properties after it has been * If not available, to determine the classname. The Services API will look for a classname in the file:
* read for the first time. * <code>META-INF/services/com.sun.syndication.AtomHandlerFactory</code> in jars available to the runtime.</li>
* </li> * <li>
* <li> * Platform default <code>AtomHandlerFactory</code> instance.</li>
* If not available, to determine the classname. The Services API will look
* for a classname in the file:
* <code>META-INF/services/com.sun.syndication.AtomHandlerFactory</code>
* in jars available to the runtime.
* </li>
* <li>
* Platform default <code>AtomHandlerFactory</code> instance.
* </li>
* </ul> * </ul>
* *
* Once an application has obtained a reference to a <code>AtomHandlerFactory</code> * Once an application has obtained a reference to a <code>AtomHandlerFactory</code> it can use the factory to configure and obtain parser instances.
* it can use the factory to configure and obtain parser instances.
* *
* @return New instance of a <code>AtomHandlerFactory</code> * @return New instance of a <code>AtomHandlerFactory</code>
* *
* @throws FactoryConfigurationError if the implementation is not available * @throws FactoryConfigurationError if the implementation is not available or cannot be instantiated.
* or cannot be instantiated.
*/ */
public static AtomHandlerFactory newInstance() { public static AtomHandlerFactory newInstance() {
try { try {
return (AtomHandlerFactory) return (AtomHandlerFactory) FactoryFinder.find(DEFAULT_PROPERTY_NAME, FALLBACK_IMPL_NAME);
FactoryFinder.find(DEFAULT_PROPERTY_NAME, FALLBACK_IMPL_NAME); } catch (final FactoryFinder.ConfigurationError e) {
} catch (FactoryFinder.ConfigurationError e) {
log.error("ERROR: finding factory", e); log.error("ERROR: finding factory", e);
throw new FactoryConfigurationError(e.getException(), e.getMessage()); throw new FactoryConfigurationError(e.getException(), e.getMessage());
} }
} }
/** /**
* Creates a new instance of a {@link com.sun.syndication.propono.atom.server.AtomHandler} * Creates a new instance of a {@link com.sun.syndication.propono.atom.server.AtomHandler} using the currently configured parameters.
* using the currently configured parameters.
* *
* @return A new instance of a AtomHandler. * @return A new instance of a AtomHandler.
* *
* @throws AtomConfigurationException if a AtomHandler cannot be created * @throws AtomConfigurationException if a AtomHandler cannot be created which satisfies the configuration requested.
* which satisfies the configuration requested.
*/ */
public abstract AtomHandler newAtomHandler( public abstract AtomHandler newAtomHandler(HttpServletRequest req, HttpServletResponse res);
HttpServletRequest req, HttpServletResponse res);
} }

View file

@ -21,6 +21,7 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Date; import java.util.Date;
import javax.activation.FileTypeMap; import javax.activation.FileTypeMap;
import javax.activation.MimetypesFileTypeMap; import javax.activation.MimetypesFileTypeMap;
@ -28,42 +29,42 @@ import javax.activation.MimetypesFileTypeMap;
* Represents a media link entry. * Represents a media link entry.
*/ */
public class AtomMediaResource { public class AtomMediaResource {
private String contentType = null; private String contentType = null;
private long contentLength = 0; private long contentLength = 0;
private InputStream inputStream = null; private InputStream inputStream = null;
private Date lastModified = null; private Date lastModified = null;
private static FileTypeMap map = null; private static FileTypeMap map = null;
static { static {
// TODO: figure out why PNG is missing from Java MIME types // TODO: figure out why PNG is missing from Java MIME types
map = FileTypeMap.getDefaultFileTypeMap(); map = FileTypeMap.getDefaultFileTypeMap();
if (map instanceof MimetypesFileTypeMap) { if (map instanceof MimetypesFileTypeMap) {
try { try {
((MimetypesFileTypeMap)map).addMimeTypes("image/png png PNG"); ((MimetypesFileTypeMap) map).addMimeTypes("image/png png PNG");
} catch (Exception ignored) {} } catch (final Exception ignored) {
}
} }
} }
public AtomMediaResource(File resource) throws FileNotFoundException { public AtomMediaResource(final File resource) throws FileNotFoundException {
contentType = map.getContentType(resource.getName()); contentType = map.getContentType(resource.getName());
contentLength = resource.length(); contentLength = resource.length();
lastModified = new Date(resource.lastModified()); lastModified = new Date(resource.lastModified());
inputStream = new FileInputStream(resource); inputStream = new FileInputStream(resource);
} }
public AtomMediaResource(String name, long length, Date lastModified, InputStream is) public AtomMediaResource(final String name, final long length, final Date lastModified, final InputStream is) throws FileNotFoundException {
throws FileNotFoundException { contentType = map.getContentType(name);
this.contentType = map.getContentType(name); contentLength = length;
this.contentLength = length;
this.lastModified = lastModified; this.lastModified = lastModified;
this.inputStream = is; inputStream = is;
} }
public String getContentType() { public String getContentType() {
return contentType; return contentType;
} }
public void setContentType(String contentType) { public void setContentType(final String contentType) {
this.contentType = contentType; this.contentType = contentType;
} }
@ -71,7 +72,7 @@ public class AtomMediaResource {
return contentLength; return contentLength;
} }
public void setContentLength(long contentLength) { public void setContentLength(final long contentLength) {
this.contentLength = contentLength; this.contentLength = contentLength;
} }
@ -79,7 +80,7 @@ public class AtomMediaResource {
return inputStream; return inputStream;
} }
public void setInputStream(InputStream inputStream) { public void setInputStream(final InputStream inputStream) {
this.inputStream = inputStream; this.inputStream = inputStream;
} }
@ -87,9 +88,8 @@ public class AtomMediaResource {
return lastModified; return lastModified;
} }
public void setLastModified(Date lastModified) { public void setLastModified(final Date lastModified) {
this.lastModified = lastModified; this.lastModified = lastModified;
} }
} }

View file

@ -22,27 +22,31 @@ package org.rometools.propono.atom.server;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
/** /**
* Exception to be thrown by <code>AtomHandler</code> implementations in the * Exception to be thrown by <code>AtomHandler</code> implementations in the case that a user is not authorized to access a resource.
* case that a user is not authorized to access a resource.
*/ */
public class AtomNotAuthorizedException extends AtomException { public class AtomNotAuthorizedException extends AtomException {
/** Construct new exception */ /** Construct new exception */
public AtomNotAuthorizedException() { public AtomNotAuthorizedException() {
super(); super();
} }
/** Construct new exception with message */ /** Construct new exception with message */
public AtomNotAuthorizedException(String msg) { public AtomNotAuthorizedException(final String msg) {
super(msg); super(msg);
} }
/** Construct new exception with message and root cause */ /** Construct new exception with message and root cause */
public AtomNotAuthorizedException(String msg, Throwable t) { public AtomNotAuthorizedException(final String msg, final Throwable t) {
super(msg, t); super(msg, t);
} }
/** Construct new exception to wrap root cause*/
public AtomNotAuthorizedException(Throwable t) { /** Construct new exception to wrap root cause */
public AtomNotAuthorizedException(final Throwable t) {
super(t); super(t);
} }
/** Get HTTP status code of exception (HTTP 403 unauthorized) */ /** Get HTTP status code of exception (HTTP 403 unauthorized) */
@Override
public int getStatus() { public int getStatus() {
return HttpServletResponse.SC_UNAUTHORIZED; return HttpServletResponse.SC_UNAUTHORIZED;
} }

View file

@ -29,19 +29,24 @@ public class AtomNotFoundException extends AtomException {
public AtomNotFoundException() { public AtomNotFoundException() {
super(); super();
} }
/** Construct new exception with message */ /** Construct new exception with message */
public AtomNotFoundException(String msg) { public AtomNotFoundException(final String msg) {
super(msg); super(msg);
} }
/** Construct new exception with message and root cause */ /** Construct new exception with message and root cause */
public AtomNotFoundException(String msg, Throwable t) { public AtomNotFoundException(final String msg, final Throwable t) {
super(msg, t); super(msg, t);
} }
/** Construct new exception with root cause */ /** Construct new exception with root cause */
public AtomNotFoundException(Throwable t) { public AtomNotFoundException(final Throwable t) {
super(t); super(t);
} }
/** Get HTTP status code associated with exception (404 not found) */ /** Get HTTP status code associated with exception (404 not found) */
@Override
public int getStatus() { public int getStatus() {
return HttpServletResponse.SC_NOT_FOUND; return HttpServletResponse.SC_NOT_FOUND;
} }

View file

@ -31,38 +31,32 @@ import java.util.Map;
public interface AtomRequest { public interface AtomRequest {
/** /**
* Returns any extra path information associated with the URL the client * Returns any extra path information associated with the URL the client sent when it made this request.
* sent when it made this request.
*/ */
public String getPathInfo(); public String getPathInfo();
/** /**
* Returns the query string that is contained in the request URL after * Returns the query string that is contained in the request URL after the path.
* the path.
*/ */
public String getQueryString(); public String getQueryString();
/** /**
* Returns the login of the user making this request, if the user has * Returns the login of the user making this request, if the user has been authenticated, or null if the user has not been authenticated.
* been authenticated, or null if the user has not been authenticated.
*/ */
public String getRemoteUser(); public String getRemoteUser();
/** /**
* Returns a boolean indicating whether the authenticated user is included * Returns a boolean indicating whether the authenticated user is included in the specified logical "role".
* in the specified logical "role".
*/ */
public boolean isUserInRole(String arg0); public boolean isUserInRole(String arg0);
/** /**
* Returns a java.security.Principal object containing the name of the * Returns a java.security.Principal object containing the name of the current authenticated user.
* current authenticated user.
*/ */
public Principal getUserPrincipal(); public Principal getUserPrincipal();
/** /**
* Returns the part of this request's URL from the protocol name up to the * Returns the part of this request's URL from the protocol name up to the query string in the first line of the HTTP request.
* query string in the first line of the HTTP request.
*/ */
public String getRequestURI(); public String getRequestURI();
@ -72,31 +66,27 @@ public interface AtomRequest {
public StringBuffer getRequestURL(); public StringBuffer getRequestURL();
/** /**
* Returns the length, in bytes, of the request body and made available by * Returns the length, in bytes, of the request body and made available by the input stream, or -1 if the length is not known.
* the input stream, or -1 if the length is not known.
*/ */
public int getContentLength(); public int getContentLength();
/** /**
* Returns the MIME type of the body of the request, or null if the type * Returns the MIME type of the body of the request, or null if the type is not known.
* is not known. */ */
public String getContentType(); public String getContentType();
/** /**
* Returns the value of a request parameter as a String, or null if the * Returns the value of a request parameter as a String, or null if the parameter does not exist.
* parameter does not exist.
*/ */
public String getParameter(String arg0); public String getParameter(String arg0);
/** /**
* Returns an Enumeration of String objects containing the names of the * Returns an Enumeration of String objects containing the names of the parameters contained in this request.
* parameters contained in this request.
*/ */
public Enumeration getParameterNames(); public Enumeration getParameterNames();
/** /**
* Returns an array of String objects containing all of the values the * Returns an array of String objects containing all of the values the given request parameter has, or null if the parameter does not exist.
* given request parameter has, or null if the parameter does not exist.
*/ */
public String[] getParameterValues(String arg0); public String[] getParameterValues(String arg0);
@ -106,14 +96,13 @@ public interface AtomRequest {
public Map getParameterMap(); public Map getParameterMap();
/** /**
* Retrieves the body of the request as binary data using a * Retrieves the body of the request as binary data using a ServletInputStream.
* ServletInputStream.
*/ */
public InputStream getInputStream() throws IOException; public InputStream getInputStream() throws IOException;
/** /**
* Returns the value of the specified request header as a long value that * Returns the value of the specified request header as a long value that represents a Date object.
* represents a Date object. */ */
public long getDateHeader(String arg0); public long getDateHeader(String arg0);
/** /**
@ -122,8 +111,7 @@ public interface AtomRequest {
public String getHeader(String arg0); public String getHeader(String arg0);
/** /**
* Returns all the values of the specified request header as an Enumeration * Returns all the values of the specified request header as an Enumeration of String objects.
* of String objects.
*/ */
public Enumeration getHeaders(String arg0); public Enumeration getHeaders(String arg0);

View file

@ -24,6 +24,7 @@ import java.io.InputStream;
import java.security.Principal; import java.security.Principal;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Map; import java.util.Map;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
/** /**
@ -32,83 +33,102 @@ import javax.servlet.http.HttpServletRequest;
public class AtomRequestImpl implements AtomRequest { public class AtomRequestImpl implements AtomRequest {
private HttpServletRequest wrapped = null; private HttpServletRequest wrapped = null;
public AtomRequestImpl(HttpServletRequest wrapped) { public AtomRequestImpl(final HttpServletRequest wrapped) {
this.wrapped = wrapped; this.wrapped = wrapped;
} }
@Override
public String getPathInfo() { public String getPathInfo() {
return wrapped.getPathInfo() != null ? wrapped.getPathInfo() : ""; return wrapped.getPathInfo() != null ? wrapped.getPathInfo() : "";
} }
@Override
public String getQueryString() { public String getQueryString() {
return wrapped.getQueryString(); return wrapped.getQueryString();
} }
@Override
public String getRemoteUser() { public String getRemoteUser() {
return wrapped.getRemoteUser(); return wrapped.getRemoteUser();
} }
public boolean isUserInRole(String arg0) { @Override
public boolean isUserInRole(final String arg0) {
return wrapped.isUserInRole(arg0); return wrapped.isUserInRole(arg0);
} }
@Override
public Principal getUserPrincipal() { public Principal getUserPrincipal() {
return wrapped.getUserPrincipal(); return wrapped.getUserPrincipal();
} }
@Override
public String getRequestURI() { public String getRequestURI() {
return wrapped.getRequestURI(); return wrapped.getRequestURI();
} }
@Override
public StringBuffer getRequestURL() { public StringBuffer getRequestURL() {
return wrapped.getRequestURL(); return wrapped.getRequestURL();
} }
@Override
public int getContentLength() { public int getContentLength() {
return wrapped.getContentLength(); return wrapped.getContentLength();
} }
@Override
public String getContentType() { public String getContentType() {
return wrapped.getContentType(); return wrapped.getContentType();
} }
public String getParameter(String arg0) { @Override
public String getParameter(final String arg0) {
return wrapped.getParameter(arg0); return wrapped.getParameter(arg0);
} }
@Override
public Enumeration getParameterNames() { public Enumeration getParameterNames() {
return wrapped.getParameterNames(); return wrapped.getParameterNames();
} }
public String[] getParameterValues(String arg0) { @Override
public String[] getParameterValues(final String arg0) {
return wrapped.getParameterValues(arg0); return wrapped.getParameterValues(arg0);
} }
@Override
public Map getParameterMap() { public Map getParameterMap() {
return wrapped.getParameterMap(); return wrapped.getParameterMap();
} }
@Override
public InputStream getInputStream() throws IOException { public InputStream getInputStream() throws IOException {
return wrapped.getInputStream(); return wrapped.getInputStream();
} }
public long getDateHeader(String arg0) { @Override
public long getDateHeader(final String arg0) {
return wrapped.getDateHeader(arg0); return wrapped.getDateHeader(arg0);
} }
public String getHeader(String arg0) { @Override
public String getHeader(final String arg0) {
return wrapped.getHeader(arg0); return wrapped.getHeader(arg0);
} }
public Enumeration getHeaders(String arg0) { @Override
public Enumeration getHeaders(final String arg0) {
return wrapped.getHeaders(arg0); return wrapped.getHeaders(arg0);
} }
@Override
public Enumeration getHeaderNames() { public Enumeration getHeaderNames() {
return wrapped.getHeaderNames(); return wrapped.getHeaderNames();
} }
public int getIntHeader(String arg0) { @Override
public int getIntHeader(final String arg0) {
return wrapped.getIntHeader(arg0); return wrapped.getIntHeader(arg0);
} }
} }

View file

@ -19,39 +19,39 @@
*/ */
package org.rometools.propono.atom.server; package org.rometools.propono.atom.server;
import com.sun.syndication.feed.atom.Content; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.Writer; import java.io.Writer;
import java.util.Collections;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.jdom2.Document; import org.jdom2.Document;
import org.jdom2.output.Format; import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter; import org.jdom2.output.XMLOutputter;
import org.rometools.propono.atom.common.AtomService;
import org.rometools.propono.atom.common.Categories;
import org.rometools.propono.utils.Utilities;
import com.sun.syndication.feed.atom.Content;
import com.sun.syndication.feed.atom.Entry; import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.feed.atom.Feed; import com.sun.syndication.feed.atom.Feed;
import com.sun.syndication.feed.atom.Link; import com.sun.syndication.feed.atom.Link;
import com.sun.syndication.io.WireFeedOutput; import com.sun.syndication.io.WireFeedOutput;
import com.sun.syndication.io.impl.Atom10Generator; import com.sun.syndication.io.impl.Atom10Generator;
import com.sun.syndication.io.impl.Atom10Parser; import com.sun.syndication.io.impl.Atom10Parser;
import org.rometools.propono.atom.common.AtomService;
import org.rometools.propono.atom.common.Categories;
import org.rometools.propono.utils.Utilities;
import java.io.BufferedReader;
import java.util.Collections;
import java.util.Iterator;
import javax.servlet.ServletConfig;
/** /**
* Atom Servlet implements Atom protocol by calling an * Atom Servlet implements Atom protocol by calling an {@link com.sun.syndication.propono.atom.server.AtomHandler} implementation. This servlet takes care of
* {@link com.sun.syndication.propono.atom.server.AtomHandler} * parsing incoming XML into ROME Atom {@link com.sun.syndication.feed.atom.Entry} objects, passing those to the handler and serializing to the response the
* implementation. This servlet takes care of parsing incoming XML into ROME * entries and feeds returned by the handler.
* Atom {@link com.sun.syndication.feed.atom.Entry} objects, passing those to the handler and serializing
* to the response the entries and feeds returned by the handler.
*/ */
public class AtomServlet extends HttpServlet { public class AtomServlet extends HttpServlet {
@ -61,101 +61,92 @@ public class AtomServlet extends HttpServlet {
public static final String FEED_TYPE = "atom_1.0"; public static final String FEED_TYPE = "atom_1.0";
private static String contextDirPath = null; private static String contextDirPath = null;
private static Log log = private static Log log = LogFactory.getFactory().getInstance(AtomServlet.class);
LogFactory.getFactory().getInstance(AtomServlet.class);
static { static {
Atom10Parser.setResolveURIs(true); Atom10Parser.setResolveURIs(true);
} }
//----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
/** /**
* Create an Atom request handler. * Create an Atom request handler. TODO: make AtomRequestHandler implementation configurable.
* TODO: make AtomRequestHandler implementation configurable.
*/ */
private AtomHandler createAtomRequestHandler( private AtomHandler createAtomRequestHandler(final HttpServletRequest request, final HttpServletResponse response) throws ServletException {
HttpServletRequest request, HttpServletResponse response) final AtomHandlerFactory ahf = AtomHandlerFactory.newInstance();
throws ServletException {
AtomHandlerFactory ahf = AtomHandlerFactory.newInstance();
return ahf.newAtomHandler(request, response); return ahf.newAtomHandler(request, response);
} }
//----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
/** /**
* Handles an Atom GET by calling handler and writing results to response. * Handles an Atom GET by calling handler and writing results to response.
*/ */
protected void doGet(HttpServletRequest req, HttpServletResponse res) @Override
throws ServletException, IOException { protected void doGet(final HttpServletRequest req, final HttpServletResponse res) throws ServletException, IOException {
log.debug("Entering"); log.debug("Entering");
AtomHandler handler = createAtomRequestHandler(req, res); final AtomHandler handler = createAtomRequestHandler(req, res);
String userName = handler.getAuthenticatedUsername(); final String userName = handler.getAuthenticatedUsername();
if (userName != null) { if (userName != null) {
AtomRequest areq = new AtomRequestImpl(req); final AtomRequest areq = new AtomRequestImpl(req);
try { try {
if (handler.isAtomServiceURI(areq)) { if (handler.isAtomServiceURI(areq)) {
// return an Atom Service document // return an Atom Service document
AtomService service = handler.getAtomService(areq); final AtomService service = handler.getAtomService(areq);
Document doc = service.serviceToDocument(); final Document doc = service.serviceToDocument();
res.setContentType("application/atomsvc+xml; charset=utf-8"); res.setContentType("application/atomsvc+xml; charset=utf-8");
Writer writer = res.getWriter(); final Writer writer = res.getWriter();
XMLOutputter outputter = new XMLOutputter(); final XMLOutputter outputter = new XMLOutputter();
outputter.setFormat(Format.getPrettyFormat()); outputter.setFormat(Format.getPrettyFormat());
outputter.output(doc, writer); outputter.output(doc, writer);
writer.close(); writer.close();
res.setStatus(HttpServletResponse.SC_OK); res.setStatus(HttpServletResponse.SC_OK);
} } else if (handler.isCategoriesURI(areq)) {
else if (handler.isCategoriesURI(areq)) { final Categories cats = handler.getCategories(areq);
Categories cats = handler.getCategories(areq);
res.setContentType("application/xml"); res.setContentType("application/xml");
Writer writer = res.getWriter(); final Writer writer = res.getWriter();
Document catsDoc = new Document(); final Document catsDoc = new Document();
catsDoc.setRootElement(cats.categoriesToElement()); catsDoc.setRootElement(cats.categoriesToElement());
XMLOutputter outputter = new XMLOutputter(); final XMLOutputter outputter = new XMLOutputter();
outputter.output(catsDoc, writer); outputter.output(catsDoc, writer);
writer.close(); writer.close();
res.setStatus(HttpServletResponse.SC_OK); res.setStatus(HttpServletResponse.SC_OK);
} } else if (handler.isCollectionURI(areq)) {
else if (handler.isCollectionURI(areq)) {
// return a collection // return a collection
Feed col = handler.getCollection(areq); final Feed col = handler.getCollection(areq);
col.setFeedType(FEED_TYPE); col.setFeedType(FEED_TYPE);
WireFeedOutput wireFeedOutput = new WireFeedOutput(); final WireFeedOutput wireFeedOutput = new WireFeedOutput();
Document feedDoc = wireFeedOutput.outputJDom(col); final Document feedDoc = wireFeedOutput.outputJDom(col);
res.setContentType("application/atom+xml; charset=utf-8"); res.setContentType("application/atom+xml; charset=utf-8");
Writer writer = res.getWriter(); final Writer writer = res.getWriter();
XMLOutputter outputter = new XMLOutputter(); final XMLOutputter outputter = new XMLOutputter();
outputter.setFormat(Format.getPrettyFormat()); outputter.setFormat(Format.getPrettyFormat());
outputter.output(feedDoc, writer); outputter.output(feedDoc, writer);
writer.close(); writer.close();
res.setStatus(HttpServletResponse.SC_OK); res.setStatus(HttpServletResponse.SC_OK);
} } else if (handler.isEntryURI(areq)) {
else if (handler.isEntryURI(areq)) {
// return an entry // return an entry
Entry entry = handler.getEntry(areq); final Entry entry = handler.getEntry(areq);
if (entry != null) { if (entry != null) {
res.setContentType("application/atom+xml; type=entry; charset=utf-8"); res.setContentType("application/atom+xml; type=entry; charset=utf-8");
Writer writer = res.getWriter(); final Writer writer = res.getWriter();
Atom10Generator.serializeEntry(entry, writer); Atom10Generator.serializeEntry(entry, writer);
writer.close(); writer.close();
} else { } else {
res.setStatus(HttpServletResponse.SC_NOT_FOUND); res.setStatus(HttpServletResponse.SC_NOT_FOUND);
} }
} } else if (handler.isMediaEditURI(areq)) {
else if (handler.isMediaEditURI(areq)) { final AtomMediaResource entry = handler.getMediaResource(areq);
AtomMediaResource entry = handler.getMediaResource(areq);
res.setContentType(entry.getContentType()); res.setContentType(entry.getContentType());
res.setContentLength((int)entry.getContentLength()); res.setContentLength((int) entry.getContentLength());
Utilities.copyInputToOutput(entry.getInputStream(), res.getOutputStream()); Utilities.copyInputToOutput(entry.getInputStream(), res.getOutputStream());
res.getOutputStream().flush(); res.getOutputStream().flush();
res.getOutputStream().close(); res.getOutputStream().close();
} } else {
else {
res.setStatus(HttpServletResponse.SC_NOT_FOUND); res.setStatus(HttpServletResponse.SC_NOT_FOUND);
} }
} catch (AtomException ae) { } catch (final AtomException ae) {
res.sendError(ae.getStatus(), ae.getMessage()); res.sendError(ae.getStatus(), ae.getMessage());
log.debug("ERROR processing GET", ae); log.debug("ERROR processing GET", ae);
} catch (Exception e) { } catch (final Exception e) {
res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
log.debug("ERROR processing GET", e); log.debug("ERROR processing GET", e);
} }
@ -166,40 +157,38 @@ public class AtomServlet extends HttpServlet {
log.debug("Exiting"); log.debug("Exiting");
} }
//----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
/** /**
* Handles an Atom POST by calling handler to identify URI, reading/parsing * Handles an Atom POST by calling handler to identify URI, reading/parsing data, calling handler and writing results to response.
* data, calling handler and writing results to response.
*/ */
protected void doPost(HttpServletRequest req, HttpServletResponse res) @Override
throws ServletException, IOException { protected void doPost(final HttpServletRequest req, final HttpServletResponse res) throws ServletException, IOException {
log.debug("Entering"); log.debug("Entering");
AtomHandler handler = createAtomRequestHandler(req, res); final AtomHandler handler = createAtomRequestHandler(req, res);
String userName = handler.getAuthenticatedUsername(); final String userName = handler.getAuthenticatedUsername();
if (userName != null) { if (userName != null) {
AtomRequest areq = new AtomRequestImpl(req); final AtomRequest areq = new AtomRequestImpl(req);
try { try {
if (handler.isCollectionURI(areq)) { if (handler.isCollectionURI(areq)) {
if (req.getContentType().startsWith("application/atom+xml")) { if (req.getContentType().startsWith("application/atom+xml")) {
// parse incoming entry // parse incoming entry
Entry entry = Atom10Parser.parseEntry(new BufferedReader( final Entry entry = Atom10Parser.parseEntry(new BufferedReader(new InputStreamReader(req.getInputStream(), "UTF-8")), null);
new InputStreamReader(req.getInputStream(), "UTF-8")), null);
// call handler to post it // call handler to post it
Entry newEntry = handler.postEntry(areq, entry); final Entry newEntry = handler.postEntry(areq, entry);
// set Location and Content-Location headers // set Location and Content-Location headers
for (Iterator it = newEntry.getOtherLinks().iterator(); it.hasNext();) { for (final Object element : newEntry.getOtherLinks()) {
Link link = (Link) it.next(); final Link link = (Link) element;
if ("edit".equals(link.getRel())) { if ("edit".equals(link.getRel())) {
res.addHeader("Location", link.getHrefResolved()); res.addHeader("Location", link.getHrefResolved());
break; break;
} }
} }
for (Iterator it = newEntry.getAlternateLinks().iterator(); it.hasNext();) { for (final Object element : newEntry.getAlternateLinks()) {
Link link = (Link) it.next(); final Link link = (Link) element;
if ("alternate".equals(link.getRel())) { if ("alternate".equals(link.getRel())) {
res.addHeader("Content-Location", link.getHrefResolved()); res.addHeader("Content-Location", link.getHrefResolved());
break; break;
@ -210,35 +199,35 @@ public class AtomServlet extends HttpServlet {
res.setStatus(HttpServletResponse.SC_CREATED); res.setStatus(HttpServletResponse.SC_CREATED);
res.setContentType("application/atom+xml; type=entry; charset=utf-8"); res.setContentType("application/atom+xml; type=entry; charset=utf-8");
Writer writer = res.getWriter(); final Writer writer = res.getWriter();
Atom10Generator.serializeEntry(newEntry, writer); Atom10Generator.serializeEntry(newEntry, writer);
writer.close(); writer.close();
} else if (req.getContentType() != null) { } else if (req.getContentType() != null) {
// get incoming title and slug from HTTP header // get incoming title and slug from HTTP header
String title = areq.getHeader("Title"); final String title = areq.getHeader("Title");
// create new entry for resource, set title and type // create new entry for resource, set title and type
Entry resource = new Entry(); final Entry resource = new Entry();
resource.setTitle(title); resource.setTitle(title);
Content content = new Content(); final Content content = new Content();
content.setType(areq.getContentType()); content.setType(areq.getContentType());
resource.setContents(Collections.singletonList(content)); resource.setContents(Collections.singletonList(content));
// hand input stream off to hander to post file // hand input stream off to hander to post file
Entry newEntry = handler.postMedia(areq, resource); final Entry newEntry = handler.postMedia(areq, resource);
// set Location and Content-Location headers // set Location and Content-Location headers
for (Iterator it = newEntry.getOtherLinks().iterator(); it.hasNext();) { for (final Object element : newEntry.getOtherLinks()) {
Link link = (Link) it.next(); final Link link = (Link) element;
if ("edit".equals(link.getRel())) { if ("edit".equals(link.getRel())) {
res.addHeader("Location", link.getHrefResolved()); res.addHeader("Location", link.getHrefResolved());
break; break;
} }
} }
for (Iterator it = newEntry.getAlternateLinks().iterator(); it.hasNext();) { for (final Object element : newEntry.getAlternateLinks()) {
Link link = (Link) it.next(); final Link link = (Link) element;
if ("alternate".equals(link.getRel())) { if ("alternate".equals(link.getRel())) {
res.addHeader("Content-Location", link.getHrefResolved()); res.addHeader("Content-Location", link.getHrefResolved());
break; break;
@ -248,23 +237,21 @@ public class AtomServlet extends HttpServlet {
res.setStatus(HttpServletResponse.SC_CREATED); res.setStatus(HttpServletResponse.SC_CREATED);
res.setContentType("application/atom+xml; type=entry; charset=utf-8"); res.setContentType("application/atom+xml; type=entry; charset=utf-8");
Writer writer = res.getWriter(); final Writer writer = res.getWriter();
Atom10Generator.serializeEntry(newEntry, writer); Atom10Generator.serializeEntry(newEntry, writer);
writer.close(); writer.close();
} else { } else {
res.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, res.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, "No content-type specified in request");
"No content-type specified in request");
} }
} else { } else {
res.sendError(HttpServletResponse.SC_NOT_FOUND, res.sendError(HttpServletResponse.SC_NOT_FOUND, "Invalid collection specified in request");
"Invalid collection specified in request");
} }
} catch (AtomException ae) { } catch (final AtomException ae) {
res.sendError(ae.getStatus(), ae.getMessage()); res.sendError(ae.getStatus(), ae.getMessage());
log.debug("ERROR processing POST", ae); log.debug("ERROR processing POST", ae);
} catch (Exception e) { } catch (final Exception e) {
res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
log.debug("ERROR processing POST", e); log.debug("ERROR processing POST", e);
} }
@ -275,24 +262,22 @@ public class AtomServlet extends HttpServlet {
log.debug("Exiting"); log.debug("Exiting");
} }
//----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
/** /**
* Handles an Atom PUT by calling handler to identify URI, reading/parsing * Handles an Atom PUT by calling handler to identify URI, reading/parsing data, calling handler and writing results to response.
* data, calling handler and writing results to response.
*/ */
protected void doPut(HttpServletRequest req, HttpServletResponse res) @Override
throws ServletException, IOException { protected void doPut(final HttpServletRequest req, final HttpServletResponse res) throws ServletException, IOException {
log.debug("Entering"); log.debug("Entering");
AtomHandler handler = createAtomRequestHandler(req, res); final AtomHandler handler = createAtomRequestHandler(req, res);
String userName = handler.getAuthenticatedUsername(); final String userName = handler.getAuthenticatedUsername();
if (userName != null) { if (userName != null) {
AtomRequest areq = new AtomRequestImpl(req); final AtomRequest areq = new AtomRequestImpl(req);
try { try {
if (handler.isEntryURI(areq)) { if (handler.isEntryURI(areq)) {
// parse incoming entry // parse incoming entry
Entry unsavedEntry = Atom10Parser.parseEntry(new BufferedReader( final Entry unsavedEntry = Atom10Parser.parseEntry(new BufferedReader(new InputStreamReader(req.getInputStream(), "UTF-8")), null);
new InputStreamReader(req.getInputStream(), "UTF-8")), null);
// call handler to put entry // call handler to put entry
handler.putEntry(areq, unsavedEntry); handler.putEntry(areq, unsavedEntry);
@ -309,10 +294,10 @@ public class AtomServlet extends HttpServlet {
} else { } else {
res.setStatus(HttpServletResponse.SC_NOT_FOUND); res.setStatus(HttpServletResponse.SC_NOT_FOUND);
} }
} catch (AtomException ae) { } catch (final AtomException ae) {
res.sendError(ae.getStatus(), ae.getMessage()); res.sendError(ae.getStatus(), ae.getMessage());
log.debug("ERROR processing PUT", ae); log.debug("ERROR processing PUT", ae);
} catch (Exception e) { } catch (final Exception e) {
res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
log.debug("ERROR processing PUT", e); log.debug("ERROR processing PUT", e);
} }
@ -325,29 +310,28 @@ public class AtomServlet extends HttpServlet {
log.debug("Exiting"); log.debug("Exiting");
} }
//----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
/** /**
* Handle Atom DELETE by calling appropriate handler. * Handle Atom DELETE by calling appropriate handler.
*/ */
protected void doDelete(HttpServletRequest req, HttpServletResponse res) @Override
throws ServletException, IOException { protected void doDelete(final HttpServletRequest req, final HttpServletResponse res) throws ServletException, IOException {
log.debug("Entering"); log.debug("Entering");
AtomHandler handler = createAtomRequestHandler(req, res); final AtomHandler handler = createAtomRequestHandler(req, res);
String userName = handler.getAuthenticatedUsername(); final String userName = handler.getAuthenticatedUsername();
if (userName != null) { if (userName != null) {
AtomRequest areq = new AtomRequestImpl(req); final AtomRequest areq = new AtomRequestImpl(req);
try { try {
if (handler.isEntryURI(areq)) { if (handler.isEntryURI(areq)) {
handler.deleteEntry(areq); handler.deleteEntry(areq);
res.setStatus(HttpServletResponse.SC_OK); res.setStatus(HttpServletResponse.SC_OK);
} } else {
else {
res.setStatus(HttpServletResponse.SC_NOT_FOUND); res.setStatus(HttpServletResponse.SC_NOT_FOUND);
} }
} catch (AtomException ae) { } catch (final AtomException ae) {
res.sendError(ae.getStatus(), ae.getMessage()); res.sendError(ae.getStatus(), ae.getMessage());
log.debug("ERROR processing DELETE", ae); log.debug("ERROR processing DELETE", ae);
} catch (Exception e) { } catch (final Exception e) {
res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
log.debug("ERROR processing DELETE", e); log.debug("ERROR processing DELETE", e);
} }
@ -363,8 +347,9 @@ public class AtomServlet extends HttpServlet {
/** /**
* Initialize servlet. * Initialize servlet.
*/ */
public void init( ServletConfig config ) throws ServletException { @Override
super.init( config ); public void init(final ServletConfig config) throws ServletException {
super.init(config);
contextDirPath = getServletContext().getRealPath("/"); contextDirPath = getServletContext().getRealPath("/");
} }

View file

@ -16,76 +16,64 @@
package org.rometools.propono.atom.server; package org.rometools.propono.atom.server;
/** /**
* Thrown when a problem with configuration with the * Thrown when a problem with configuration with the {@link com.sun.syndication.propono.atom.server.AtomHandlerFactory} exists. This error will typically be
* {@link com.sun.syndication.propono.atom.server.AtomHandlerFactory} exists. * thrown when the class of a parser factory specified in the system properties cannot be found or instantiated.
* This error will typically be thrown when the class of a parser factory
* specified in the system properties cannot be found or instantiated.
*/ */
public class FactoryConfigurationError extends Error { public class FactoryConfigurationError extends Error {
/** /**
* <code>Exception</code> that represents the error. * <code>Exception</code> that represents the error.
*/ */
private Exception exception; private final Exception exception;
/** /**
* Create a new <code>FactoryConfigurationError</code> with no * Create a new <code>FactoryConfigurationError</code> with no detail mesage.
* detail mesage.
*/ */
public FactoryConfigurationError() { public FactoryConfigurationError() {
super(); super();
this.exception = null; exception = null;
} }
/** /**
* Create a new <code>FactoryConfigurationError</code> with * Create a new <code>FactoryConfigurationError</code> with the <code>String </code> specified as an error message.
* the <code>String </code> specified as an error message.
* *
* @param msg The error message for the exception. * @param msg The error message for the exception.
*/ */
public FactoryConfigurationError(String msg) { public FactoryConfigurationError(final String msg) {
super(msg); super(msg);
this.exception = null; exception = null;
} }
/** /**
* Create a new <code>FactoryConfigurationError</code> with a * Create a new <code>FactoryConfigurationError</code> with a given <code>Exception</code> base cause of the error.
* given <code>Exception</code> base cause of the error.
* *
* @param e The exception to be encapsulated in a * @param e The exception to be encapsulated in a FactoryConfigurationError.
* FactoryConfigurationError.
*/ */
public FactoryConfigurationError(Exception e) { public FactoryConfigurationError(final Exception e) {
super(e.toString()); super(e.toString());
this.exception = e; exception = e;
} }
/** /**
* Create a new <code>FactoryConfigurationError</code> with the * Create a new <code>FactoryConfigurationError</code> with the given <code>Exception</code> base cause and detail message.
* given <code>Exception</code> base cause and detail message.
* *
* @param e The exception to be encapsulated in a * @param e The exception to be encapsulated in a FactoryConfigurationError
* FactoryConfigurationError
* @param msg The detail message. * @param msg The detail message.
*/ */
public FactoryConfigurationError(Exception e, String msg) { public FactoryConfigurationError(final Exception e, final String msg) {
super(msg); super(msg);
this.exception = e; exception = e;
} }
/** /**
* Return the message (if any) for this error . If there is no * Return the message (if any) for this error . If there is no message for the exception and there is an encapsulated exception then the message of that
* message for the exception and there is an encapsulated * exception, if it exists will be returned. Else the name of the encapsulated exception will be returned.
* exception then the message of that exception, if it exists will be
* returned. Else the name of the encapsulated exception will be
* returned.
* *
* @return The error message. * @return The error message.
*/ */
@Override
public String getMessage() { public String getMessage() {
String message = super.getMessage(); final String message = super.getMessage();
if (message == null && exception != null) { if (message == null && exception != null) {
return exception.getMessage(); return exception.getMessage();
@ -95,8 +83,7 @@ public class FactoryConfigurationError extends Error {
} }
/** /**
* Return the actual exception (if any) that caused this exception to * Return the actual exception (if any) that caused this exception to be raised.
* be raised.
* *
* @return The encapsulated exception, or null if there is none. * @return The encapsulated exception, or null if there is none.
*/ */

View file

@ -15,47 +15,37 @@
*/ */
package org.rometools.propono.atom.server; package org.rometools.propono.atom.server;
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.URL; import java.util.Properties;
/** /**
* Find {@link com.sun.syndication.propono.atom.server.AtomHandlerFactory} based on properties files. * Find {@link com.sun.syndication.propono.atom.server.AtomHandlerFactory} based on properties files.
*/ */
class FactoryFinder { class FactoryFinder {
private static boolean debug = false; private static boolean debug = false;
static Properties cacheProps= new Properties(); static Properties cacheProps = new Properties();
static SecuritySupport ss = new SecuritySupport() ; static SecuritySupport ss = new SecuritySupport();
static boolean firstTime = true; static boolean firstTime = true;
private static void dPrint(String msg) { private static void dPrint(final String msg) {
if (debug) { if (debug) {
System.err.println("Propono: " + msg); System.err.println("Propono: " + msg);
} }
} }
/** /**
* Create an instance of a class using the specified ClassLoader and * Create an instance of a class using the specified ClassLoader and optionally fall back to the current ClassLoader if not found.
* optionally fall back to the current ClassLoader if not found.
* *
* @param className Name of the concrete class corresponding to the * @param className Name of the concrete class corresponding to the service provider
* service provider
* *
* @param cl ClassLoader to use to load the class, null means to use * @param cl ClassLoader to use to load the class, null means to use the bootstrap ClassLoader
* the bootstrap ClassLoader
* *
* @param doFallback true if the current ClassLoader should be tried as * @param doFallback true if the current ClassLoader should be tried as a fallback if the class is not found using cl
* a fallback if the class is not found using cl
*/ */
private static Object newInstance( private static Object newInstance(final String className, ClassLoader cl, final boolean doFallback) throws ConfigurationError {
String className, ClassLoader cl, boolean doFallback)
throws ConfigurationError {
try { try {
Class providerClass; Class providerClass;
@ -67,7 +57,7 @@ class FactoryFinder {
} else { } else {
try { try {
providerClass = cl.loadClass(className); providerClass = cl.loadClass(className);
} catch (ClassNotFoundException x) { } catch (final ClassNotFoundException x) {
if (doFallback) { if (doFallback) {
// Fall back to current classloader // Fall back to current classloader
cl = FactoryFinder.class.getClassLoader(); cl = FactoryFinder.class.getClassLoader();
@ -78,36 +68,30 @@ class FactoryFinder {
} }
} }
Object instance = providerClass.newInstance(); final Object instance = providerClass.newInstance();
dPrint("created new instance of " + providerClass + dPrint("created new instance of " + providerClass + " using ClassLoader: " + cl);
" using ClassLoader: " + cl);
return instance; return instance;
} catch (ClassNotFoundException x) { } catch (final ClassNotFoundException x) {
throw new ConfigurationError( throw new ConfigurationError("Provider " + className + " not found", x);
"Provider " + className + " not found", x); } catch (final Exception x) {
} catch (Exception x) { throw new ConfigurationError("Provider " + className + " could not be instantiated: " + x, x);
throw new ConfigurationError(
"Provider " + className + " could not be instantiated: " + x, x);
} }
} }
/** /**
* Finds the implementation Class object in the specified order. Main * Finds the implementation Class object in the specified order. Main entry point.
* entry point. *
* @return Class object of factory, never null * @return Class object of factory, never null
* *
* @param factoryId Name of the factory to find, same as * @param factoryId Name of the factory to find, same as a property name
* a property name * @param fallbackClassName Implementation class name, if nothing else is found. Use null to mean no fallback.
* @param fallbackClassName Implementation class name, if nothing else
* is found. Use null to mean no fallback.
* *
* Package private so this code can be shared. * Package private so this code can be shared.
*/ */
static Object find(String factoryId, String fallbackClassName) static Object find(final String factoryId, final String fallbackClassName) throws ConfigurationError {
throws ConfigurationError {
// Figure out which ClassLoader to use for loading the provider // Figure out which ClassLoader to use for loading the provider
// class. If there is a Context ClassLoader then use it. // class. If there is a Context ClassLoader then use it.
ClassLoader classLoader = ss.getContextClassLoader(); ClassLoader classLoader = ss.getContextClassLoader();
@ -121,53 +105,55 @@ class FactoryFinder {
// Use the system property first // Use the system property first
try { try {
String systemProp = ss.getSystemProperty(factoryId); final String systemProp = ss.getSystemProperty(factoryId);
if( systemProp!=null) { if (systemProp != null) {
dPrint("found system property, value=" + systemProp); dPrint("found system property, value=" + systemProp);
return newInstance(systemProp, classLoader, true ); return newInstance(systemProp, classLoader, true);
} }
} catch (SecurityException se) { } catch (final SecurityException se) {
//if first option fails due to any reason we should try next option in the // if first option fails due to any reason we should try next option in the
//look up algorithm. // look up algorithm.
} }
// try to read from /propono.properties // try to read from /propono.properties
try { try {
String javah = ss.getSystemProperty("java.home"); final String javah = ss.getSystemProperty("java.home");
String configFile = "/propono.properties"; final String configFile = "/propono.properties";
String factoryClassName = null; String factoryClassName = null;
if(firstTime){ if (firstTime) {
synchronized(cacheProps){ synchronized (cacheProps) {
if (firstTime) { if (firstTime) {
try { try {
InputStream is = FactoryFinder.class.getResourceAsStream(configFile); final InputStream is = FactoryFinder.class.getResourceAsStream(configFile);
firstTime = false; firstTime = false;
if (is != null) { if (is != null) {
dPrint("Read properties file: " + configFile); dPrint("Read properties file: " + configFile);
cacheProps.load(is); cacheProps.load(is);
} }
} catch (Exception intentionallyIgnored) {} } catch (final Exception intentionallyIgnored) {
}
} }
} }
} }
factoryClassName = cacheProps.getProperty(factoryId); factoryClassName = cacheProps.getProperty(factoryId);
if(factoryClassName != null){ if (factoryClassName != null) {
dPrint("found in $java.home/propono.properties, value=" + factoryClassName); dPrint("found in $java.home/propono.properties, value=" + factoryClassName);
return newInstance(factoryClassName, classLoader, true); return newInstance(factoryClassName, classLoader, true);
} }
} catch(Exception ex) { } catch (final Exception ex) {
if( debug ) ex.printStackTrace(); if (debug) {
ex.printStackTrace();
}
} }
// Try Jar Service Provider Mechanism // Try Jar Service Provider Mechanism
Object provider = findJarServiceProvider(factoryId); final Object provider = findJarServiceProvider(factoryId);
if (provider != null) { if (provider != null) {
return provider; return provider;
} }
if (fallbackClassName == null) { if (fallbackClassName == null) {
throw new ConfigurationError( throw new ConfigurationError("Provider for " + factoryId + " cannot be found", null);
"Provider for " + factoryId + " cannot be found", null);
} }
dPrint("loaded from fallback value: " + fallbackClassName); dPrint("loaded from fallback value: " + fallbackClassName);
@ -179,10 +165,9 @@ class FactoryFinder {
* *
* @return instance of provider class if found or null * @return instance of provider class if found or null
*/ */
private static Object findJarServiceProvider(String factoryId) private static Object findJarServiceProvider(final String factoryId) throws ConfigurationError {
throws ConfigurationError {
String serviceId = "META-INF/services/" + factoryId; final String serviceId = "META-INF/services/" + factoryId;
InputStream is = null; InputStream is = null;
// First try the Context ClassLoader // First try the Context ClassLoader
@ -207,15 +192,14 @@ class FactoryFinder {
return null; return null;
} }
dPrint("found jar resource=" + serviceId + dPrint("found jar resource=" + serviceId + " using ClassLoader: " + cl);
" using ClassLoader: " + cl);
// Read the service provider name in UTF-8 as specified in // Read the service provider name in UTF-8 as specified in
// the jar spec. Unfortunately this fails in Microsoft // the jar spec. Unfortunately this fails in Microsoft
// VJ++, which does not implement the UTF-8 // VJ++, which does not implement the UTF-8
// encoding. Theoretically, we should simply let it fail in // encoding. Theoretically, we should simply let it fail in
// that case, since the JVM is obviously broken if it // that case, since the JVM is obviously broken if it
// doesn't support such a basic standard. But since there // doesn't support such a basic standard. But since there
// are still some users attempting to use VJ++ for // are still some users attempting to use VJ++ for
// development, we have dropped in a fallback which makes a // development, we have dropped in a fallback which makes a
// second attempt using the platform's default encoding. In // second attempt using the platform's default encoding. In
@ -229,7 +213,7 @@ class FactoryFinder {
BufferedReader rd; BufferedReader rd;
try { try {
rd = new BufferedReader(new InputStreamReader(is, "UTF-8")); rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
} catch (java.io.UnsupportedEncodingException e) { } catch (final java.io.UnsupportedEncodingException e) {
rd = new BufferedReader(new InputStreamReader(is)); rd = new BufferedReader(new InputStreamReader(is));
} }
@ -239,15 +223,13 @@ class FactoryFinder {
// Jar Service Provider specification // Jar Service Provider specification
factoryClassName = rd.readLine(); factoryClassName = rd.readLine();
rd.close(); rd.close();
} catch (IOException x) { } catch (final IOException x) {
// No provider found // No provider found
return null; return null;
} }
if (factoryClassName != null && if (factoryClassName != null && !"".equals(factoryClassName)) {
! "".equals(factoryClassName)) { dPrint("found in resource, value=" + factoryClassName);
dPrint("found in resource, value="
+ factoryClassName);
// Note: here we do not want to fall back to the current // Note: here we do not want to fall back to the current
// ClassLoader because we want to avoid the case where the // ClassLoader because we want to avoid the case where the
@ -261,15 +243,14 @@ class FactoryFinder {
} }
static class ConfigurationError extends Error { static class ConfigurationError extends Error {
private Exception exception; private final Exception exception;
/** /**
* Construct a new instance with the specified detail string and * Construct a new instance with the specified detail string and exception.
* exception.
*/ */
ConfigurationError(String msg, Exception x) { ConfigurationError(final String msg, final Exception x) {
super(msg); super(msg);
this.exception = x; exception = x;
} }
Exception getException() { Exception getException() {

View file

@ -15,57 +15,59 @@
*/ */
package org.rometools.propono.atom.server; package org.rometools.propono.atom.server;
import java.security.*; import java.io.File;
import java.net.*; import java.io.FileInputStream;
import java.io.*; import java.io.FileNotFoundException;
import java.util.*; import java.io.InputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
/** /**
* This class is duplicated for each subpackage, it is package private and * This class is duplicated for each subpackage, it is package private and therefore is not exposed as part of the public API.
* therefore is not exposed as part of the public API.
*/ */
class SecuritySupport { class SecuritySupport {
ClassLoader getContextClassLoader() { ClassLoader getContextClassLoader() {
return (ClassLoader) return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
AccessController.doPrivileged(new PrivilegedAction() { @Override
public Object run() { public Object run() {
ClassLoader cl = null; ClassLoader cl = null;
try { try {
cl = Thread.currentThread().getContextClassLoader(); cl = Thread.currentThread().getContextClassLoader();
} catch (SecurityException ex) { } } catch (final SecurityException ex) {
}
return cl; return cl;
} }
}); });
} }
String getSystemProperty(final String propName) { String getSystemProperty(final String propName) {
return (String) return (String) AccessController.doPrivileged(new PrivilegedAction() {
AccessController.doPrivileged(new PrivilegedAction() { @Override
public Object run() { public Object run() {
return System.getProperty(propName); return System.getProperty(propName);
} }
}); });
} }
FileInputStream getFileInputStream(final File file) FileInputStream getFileInputStream(final File file) throws FileNotFoundException {
throws FileNotFoundException {
try { try {
return (FileInputStream) return (FileInputStream) AccessController.doPrivileged(new PrivilegedExceptionAction() {
AccessController.doPrivileged(new PrivilegedExceptionAction() { @Override
public Object run() throws FileNotFoundException { public Object run() throws FileNotFoundException {
return new FileInputStream(file); return new FileInputStream(file);
} }
}); });
} catch (PrivilegedActionException e) { } catch (final PrivilegedActionException e) {
throw (FileNotFoundException)e.getException(); throw (FileNotFoundException) e.getException();
} }
} }
InputStream getResourceAsStream(final ClassLoader cl, InputStream getResourceAsStream(final ClassLoader cl, final String name) {
final String name) { return (InputStream) AccessController.doPrivileged(new PrivilegedAction() {
return (InputStream) @Override
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() { public Object run() {
InputStream ris; InputStream ris;
if (cl == null) { if (cl == null) {
@ -79,8 +81,8 @@ class SecuritySupport {
} }
boolean doesFileExist(final File f) { boolean doesFileExist(final File f) {
return ((Boolean) return ((Boolean) AccessController.doPrivileged(new PrivilegedAction() {
AccessController.doPrivileged(new PrivilegedAction() { @Override
public Object run() { public Object run() {
return new Boolean(f.exists()); return new Boolean(f.exists());
} }

View file

@ -15,90 +15,91 @@
*/ */
package org.rometools.propono.atom.server.impl; package org.rometools.propono.atom.server.impl;
import org.rometools.propono.atom.server.AtomMediaResource;
import org.apache.commons.codec.binary.Base64;
import org.rometools.propono.atom.server.AtomHandler;
import org.rometools.propono.atom.server.AtomException;
import org.rometools.propono.atom.server.AtomServlet;
import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.feed.atom.Feed;
import org.rometools.propono.atom.common.AtomService;
import org.rometools.propono.atom.common.Categories;
import org.rometools.propono.atom.server.AtomRequest;
import java.io.File; import java.io.File;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import javax.servlet.http.HttpServletRequest; import org.rometools.propono.atom.common.AtomService;
import org.apache.commons.lang.StringUtils; import org.rometools.propono.atom.common.Categories;
import org.rometools.propono.atom.server.AtomException;
import org.rometools.propono.atom.server.AtomHandler;
import org.rometools.propono.atom.server.AtomMediaResource;
import org.rometools.propono.atom.server.AtomRequest;
import org.rometools.propono.atom.server.AtomServlet;
import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.feed.atom.Feed;
/** /**
* File-based {@link com.sun.syndication.propono.atom.server.AtomHandler} * File-based {@link com.sun.syndication.propono.atom.server.AtomHandler} implementation that stores entries and media-entries to disk. Implemented using
* implementation that stores entries and media-entries to disk. Implemented * {@link com.sun.syndication.propono.atom.server.impl.FileBasedAtomService}.
* using {@link com.sun.syndication.propono.atom.server.impl.FileBasedAtomService}.
*/ */
public class FileBasedAtomHandler implements AtomHandler { public class FileBasedAtomHandler implements AtomHandler {
private static Log log = private static Log log = LogFactory.getFactory().getInstance(FileBasedAtomHandler.class);
LogFactory.getFactory().getInstance(FileBasedAtomHandler.class);
private static String fileStoreDir = null; private static String fileStoreDir = null;
private String userName = null; private String userName = null;
private String atomProtocolURL = null; private String atomProtocolURL = null;
private String contextURI = null; private String contextURI = null;
private String uploadurl = null; private final String uploadurl = null;
private FileBasedAtomService service = null; private FileBasedAtomService service = null;
/** /**
* Construct handler to handle one request. * Construct handler to handle one request.
*
* @param req Request to be handled. * @param req Request to be handled.
*/ */
public FileBasedAtomHandler( HttpServletRequest req ) { public FileBasedAtomHandler(final HttpServletRequest req) {
this(req, AtomServlet.getContextDirPath()); this(req, AtomServlet.getContextDirPath());
} }
/** /**
* Contruct handler for one request, using specified file storage directory. * Contruct handler for one request, using specified file storage directory.
* @param req Request to be handled. *
* @param req Request to be handled.
* @param uploaddir File storage upload dir. * @param uploaddir File storage upload dir.
*/ */
public FileBasedAtomHandler(HttpServletRequest req, String uploaddir) { public FileBasedAtomHandler(final HttpServletRequest req, final String uploaddir) {
log.debug("ctor"); log.debug("ctor");
userName = authenticateBASIC(req); userName = authenticateBASIC(req);
atomProtocolURL = req.getScheme() + "://" + req.getServerName() + ":" atomProtocolURL = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + req.getContextPath() + req.getServletPath();
+ req.getServerPort() + req.getContextPath() + req.getServletPath();
contextURI = req.getScheme() + "://" + req.getServerName() + ":" contextURI = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + req.getContextPath();
+ req.getServerPort() + req.getContextPath();
try { try {
service = new FileBasedAtomService(userName, uploaddir, service = new FileBasedAtomService(userName, uploaddir, contextURI, req.getContextPath(), req.getServletPath());
contextURI, req.getContextPath(), req.getServletPath()); } catch (final Throwable t) {
} catch (Throwable t) {
throw new RuntimeException("ERROR creating FileBasedAtomService", t); throw new RuntimeException("ERROR creating FileBasedAtomService", t);
} }
} }
/** /**
* Method used for validating user. Developers can overwrite this method * Method used for validating user. Developers can overwrite this method and use credentials stored in Database or LDAP to confirm if the user is allowed to
* and use credentials stored in Database or LDAP to confirm if the user is * access this service.
* allowed to access this service. *
* @param login user submitted login id * @param login user submitted login id
* @param password user submitted password * @param password user submitted password
*/ */
public boolean validateUser(String login, String password) { public boolean validateUser(final String login, final String password) {
return true; return true;
} }
/** /**
* Get username of authenticated user * Get username of authenticated user
*
* @return User name. * @return User name.
*/ */
@Override
public String getAuthenticatedUsername() { public String getAuthenticatedUsername() {
// For now return userName as the login id entered for authorization // For now return userName as the login id entered for authorization
return userName; return userName;
@ -106,98 +107,108 @@ public class FileBasedAtomHandler implements AtomHandler {
/** /**
* Get base URI of Atom protocol implementation. * Get base URI of Atom protocol implementation.
*
* @return Base URI of Atom protocol implemenation. * @return Base URI of Atom protocol implemenation.
*/ */
public String getAtomProtocolURL( ) { public String getAtomProtocolURL() {
if ( atomProtocolURL == null ) { if (atomProtocolURL == null) {
return "app"; return "app";
} else { } else {
return atomProtocolURL; return atomProtocolURL;
} }
} }
/** /**
* Return introspection document * Return introspection document
*
* @throws com.sun.syndication.propono.atom.server.AtomException Unexpected exception. * @throws com.sun.syndication.propono.atom.server.AtomException Unexpected exception.
* @return AtomService object with workspaces and collections. * @return AtomService object with workspaces and collections.
*/ */
public AtomService getAtomService(AtomRequest areq) throws AtomException { @Override
public AtomService getAtomService(final AtomRequest areq) throws AtomException {
return service; return service;
} }
/** /**
* Returns null because we use in-line categories. * Returns null because we use in-line categories.
*
* @throws com.sun.syndication.propono.atom.server.AtomException Unexpected exception. * @throws com.sun.syndication.propono.atom.server.AtomException Unexpected exception.
* @return Categories object * @return Categories object
*/ */
public Categories getCategories(AtomRequest areq) throws AtomException { @Override
public Categories getCategories(final AtomRequest areq) throws AtomException {
log.debug("getCollection"); log.debug("getCollection");
String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); final String[] pathInfo = StringUtils.split(areq.getPathInfo(), "/");
String handle = pathInfo[0]; final String handle = pathInfo[0];
String collection = pathInfo[1]; final String collection = pathInfo[1];
FileBasedCollection col = service.findCollectionByHandle(handle, collection); final FileBasedCollection col = service.findCollectionByHandle(handle, collection);
return (Categories)col.getCategories(true).get(0); return (Categories) col.getCategories(true).get(0);
} }
/** /**
* Get collection specified by pathinfo. * Get collection specified by pathinfo.
*
* @param areq Details of HTTP request * @param areq Details of HTTP request
* @return ROME feed representing collection. * @return ROME feed representing collection.
* @throws com.sun.syndication.propono.atom.server.AtomException Invalid collection or other exception. * @throws com.sun.syndication.propono.atom.server.AtomException Invalid collection or other exception.
*/ */
public Feed getCollection(AtomRequest areq) throws AtomException { @Override
public Feed getCollection(final AtomRequest areq) throws AtomException {
log.debug("getCollection"); log.debug("getCollection");
String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); final String[] pathInfo = StringUtils.split(areq.getPathInfo(), "/");
String handle = pathInfo[0]; final String handle = pathInfo[0];
String collection = pathInfo[1]; final String collection = pathInfo[1];
FileBasedCollection col = service.findCollectionByHandle(handle, collection); final FileBasedCollection col = service.findCollectionByHandle(handle, collection);
return col.getFeedDocument(); return col.getFeedDocument();
} }
/** /**
* Create a new entry specified by pathInfo and posted entry. We save the * Create a new entry specified by pathInfo and posted entry. We save the submitted Atom entry verbatim, but we do set the id and reset the update time.
* submitted Atom entry verbatim, but we do set the id and reset the update
* time.
* *
* @param entry Entry to be added to collection. * @param entry Entry to be added to collection.
* @param areq Details of HTTP request * @param areq Details of HTTP request
* @throws com.sun.syndication.propono.atom.server.AtomException On invalid collection or other error. * @throws com.sun.syndication.propono.atom.server.AtomException On invalid collection or other error.
* @return Entry as represented on server. * @return Entry as represented on server.
*/ */
public Entry postEntry(AtomRequest areq, Entry entry) throws AtomException { @Override
public Entry postEntry(final AtomRequest areq, final Entry entry) throws AtomException {
log.debug("postEntry"); log.debug("postEntry");
String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); final String[] pathInfo = StringUtils.split(areq.getPathInfo(), "/");
String handle = pathInfo[0]; final String handle = pathInfo[0];
String collection = pathInfo[1]; final String collection = pathInfo[1];
FileBasedCollection col = service.findCollectionByHandle(handle, collection); final FileBasedCollection col = service.findCollectionByHandle(handle, collection);
try { try {
return col.addEntry(entry); return col.addEntry(entry);
} catch (Exception fe) { } catch (final Exception fe) {
fe.printStackTrace(); fe.printStackTrace();
throw new AtomException( fe ); throw new AtomException(fe);
} }
} }
/** /**
* Get entry specified by pathInfo. * Get entry specified by pathInfo.
*
* @param areq Details of HTTP request * @param areq Details of HTTP request
* @throws com.sun.syndication.propono.atom.server.AtomException On invalid pathinfo or other error. * @throws com.sun.syndication.propono.atom.server.AtomException On invalid pathinfo or other error.
* @return ROME Entry object. * @return ROME Entry object.
*/ */
public Entry getEntry(AtomRequest areq) throws AtomException { @Override
public Entry getEntry(final AtomRequest areq) throws AtomException {
log.debug("getEntry"); log.debug("getEntry");
String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); final String[] pathInfo = StringUtils.split(areq.getPathInfo(), "/");
String handle = pathInfo[0]; final String handle = pathInfo[0];
String collection = pathInfo[1]; final String collection = pathInfo[1];
String fileName = pathInfo[2]; final String fileName = pathInfo[2];
FileBasedCollection col = service.findCollectionByHandle(handle, collection); final FileBasedCollection col = service.findCollectionByHandle(handle, collection);
try { try {
return col.getEntry(fileName); return col.getEntry(fileName);
} catch (Exception re) { } catch (final Exception re) {
if (re instanceof AtomException) throw (AtomException)re; if (re instanceof AtomException) {
throw (AtomException) re;
}
throw new AtomException("ERROR: getting entry", re); throw new AtomException("ERROR: getting entry", re);
} }
} }
@ -209,117 +220,123 @@ public class FileBasedAtomHandler implements AtomHandler {
* @param areq Details of HTTP request * @param areq Details of HTTP request
* @throws com.sun.syndication.propono.atom.server.AtomException * @throws com.sun.syndication.propono.atom.server.AtomException
*/ */
public void putEntry(AtomRequest areq, Entry entry) throws AtomException { @Override
public void putEntry(final AtomRequest areq, final Entry entry) throws AtomException {
log.debug("putEntry"); log.debug("putEntry");
String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); final String[] pathInfo = StringUtils.split(areq.getPathInfo(), "/");
String handle = pathInfo[0]; final String handle = pathInfo[0];
String collection = pathInfo[1]; final String collection = pathInfo[1];
String fileName = pathInfo[2]; final String fileName = pathInfo[2];
FileBasedCollection col = service.findCollectionByHandle(handle, collection); final FileBasedCollection col = service.findCollectionByHandle(handle, collection);
try { try {
col.updateEntry(entry, fileName); col.updateEntry(entry, fileName);
} catch ( Exception fe ) { } catch (final Exception fe) {
throw new AtomException( fe ); throw new AtomException(fe);
} }
} }
/** /**
* Delete entry specified by pathInfo. * Delete entry specified by pathInfo.
*
* @param areq Details of HTTP request * @param areq Details of HTTP request
*/ */
public void deleteEntry(AtomRequest areq) throws AtomException { @Override
public void deleteEntry(final AtomRequest areq) throws AtomException {
log.debug("deleteEntry"); log.debug("deleteEntry");
String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); final String[] pathInfo = StringUtils.split(areq.getPathInfo(), "/");
String handle = pathInfo[0]; final String handle = pathInfo[0];
String collection = pathInfo[1]; final String collection = pathInfo[1];
String fileName = pathInfo[2]; final String fileName = pathInfo[2];
FileBasedCollection col = service.findCollectionByHandle(handle, collection); final FileBasedCollection col = service.findCollectionByHandle(handle, collection);
try { try {
col.deleteEntry(fileName); col.deleteEntry(fileName);
} catch (Exception e) { } catch (final Exception e) {
String msg = "ERROR in atom.deleteResource"; final String msg = "ERROR in atom.deleteResource";
log.error(msg,e); log.error(msg, e);
throw new AtomException(msg); throw new AtomException(msg);
} }
} }
/** /**
* Store media data in collection specified by pathInfo, create an Atom * Store media data in collection specified by pathInfo, create an Atom media-link entry to store metadata for the new media file and return that entry to
* media-link entry to store metadata for the new media file and return * the caller.
* that entry to the caller. *
* @param areq Details of HTTP request * @param areq Details of HTTP request
* @param entry New entry initialzied with only title and content type * @param entry New entry initialzied with only title and content type
* @return Location URL of new media entry * @return Location URL of new media entry
*/ */
public Entry postMedia(AtomRequest areq, Entry entry) throws AtomException { @Override
public Entry postMedia(final AtomRequest areq, final Entry entry) throws AtomException {
// get incoming slug from HTTP header // get incoming slug from HTTP header
String slug = areq.getHeader("Slug"); final String slug = areq.getHeader("Slug");
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("postMedia - title: "+entry.getTitle()+" slug:"+slug); log.debug("postMedia - title: " + entry.getTitle() + " slug:" + slug);
} }
try { try {
File tempFile = null; final File tempFile = null;
String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); final String[] pathInfo = StringUtils.split(areq.getPathInfo(), "/");
String handle = pathInfo[0]; final String handle = pathInfo[0];
String collection = pathInfo[1]; final String collection = pathInfo[1];
FileBasedCollection col = service.findCollectionByHandle(handle, collection); final FileBasedCollection col = service.findCollectionByHandle(handle, collection);
try { try {
col.addMediaEntry(entry, slug, areq.getInputStream()); col.addMediaEntry(entry, slug, areq.getInputStream());
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
String msg = "ERROR reading posted file"; final String msg = "ERROR reading posted file";
log.error(msg,e); log.error(msg, e);
throw new AtomException(msg, e); throw new AtomException(msg, e);
} finally { } finally {
if (tempFile != null) tempFile.delete(); if (tempFile != null) {
tempFile.delete();
}
} }
} catch (Exception re) { } catch (final Exception re) {
throw new AtomException("ERROR: posting media"); throw new AtomException("ERROR: posting media");
} }
return entry; return entry;
} }
/** /**
* Update the media file part of a media-link entry. * Update the media file part of a media-link entry.
* @param areq Details of HTTP request *
* Assuming pathInfo of form /user-name/resource/name * @param areq Details of HTTP request Assuming pathInfo of form /user-name/resource/name
*/ */
public void putMedia(AtomRequest areq) throws AtomException { @Override
public void putMedia(final AtomRequest areq) throws AtomException {
log.debug("putMedia"); log.debug("putMedia");
String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); final String[] pathInfo = StringUtils.split(areq.getPathInfo(), "/");
String handle = pathInfo[0]; final String handle = pathInfo[0];
String collection = pathInfo[1]; final String collection = pathInfo[1];
String fileName = pathInfo[3]; final String fileName = pathInfo[3];
FileBasedCollection col = service.findCollectionByHandle(handle, collection); final FileBasedCollection col = service.findCollectionByHandle(handle, collection);
try { try {
col.updateMediaEntry(fileName, areq.getContentType(), areq.getInputStream()); col.updateMediaEntry(fileName, areq.getContentType(), areq.getInputStream());
} catch (Exception re) { } catch (final Exception re) {
throw new AtomException("ERROR: posting media"); throw new AtomException("ERROR: posting media");
} }
} }
public AtomMediaResource getMediaResource(AtomRequest areq) throws AtomException { @Override
public AtomMediaResource getMediaResource(final AtomRequest areq) throws AtomException {
log.debug("putMedia"); log.debug("putMedia");
String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); final String[] pathInfo = StringUtils.split(areq.getPathInfo(), "/");
String handle = pathInfo[0]; final String handle = pathInfo[0];
String collection = pathInfo[1]; final String collection = pathInfo[1];
String fileName = pathInfo[3]; final String fileName = pathInfo[3];
FileBasedCollection col = service.findCollectionByHandle(handle, collection); final FileBasedCollection col = service.findCollectionByHandle(handle, collection);
try { try {
return col.getMediaResource(fileName); return col.getMediaResource(fileName);
} catch (Exception re) { } catch (final Exception re) {
throw new AtomException("ERROR: posting media"); throw new AtomException("ERROR: posting media");
} }
} }
@ -327,18 +344,22 @@ public class FileBasedAtomHandler implements AtomHandler {
/** /**
* Return true if specified pathinfo represents URI of service doc. * Return true if specified pathinfo represents URI of service doc.
*/ */
public boolean isAtomServiceURI(AtomRequest areq) { @Override
String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); public boolean isAtomServiceURI(final AtomRequest areq) {
if (pathInfo.length==0) return true; final String[] pathInfo = StringUtils.split(areq.getPathInfo(), "/");
if (pathInfo.length == 0) {
return true;
}
return false; return false;
} }
/** /**
* Return true if specified pathinfo represents URI of category doc. * Return true if specified pathinfo represents URI of category doc.
*/ */
public boolean isCategoriesURI(AtomRequest areq) { @Override
public boolean isCategoriesURI(final AtomRequest areq) {
log.debug("isCategoriesDocumentURI"); log.debug("isCategoriesDocumentURI");
String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); final String[] pathInfo = StringUtils.split(areq.getPathInfo(), "/");
if (pathInfo.length == 3 && "categories".equals(pathInfo[2])) { if (pathInfo.length == 3 && "categories".equals(pathInfo[2])) {
return true; return true;
} }
@ -348,14 +369,15 @@ public class FileBasedAtomHandler implements AtomHandler {
/** /**
* Return true if specified pathinfo represents URI of a collection. * Return true if specified pathinfo represents URI of a collection.
*/ */
public boolean isCollectionURI(AtomRequest areq) { @Override
public boolean isCollectionURI(final AtomRequest areq) {
log.debug("isCollectionURI"); log.debug("isCollectionURI");
// workspace/collection-plural // workspace/collection-plural
// if length is 2 and points to a valid collection then YES // if length is 2 and points to a valid collection then YES
String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); final String[] pathInfo = StringUtils.split(areq.getPathInfo(), "/");
if (pathInfo.length == 2) { if (pathInfo.length == 2) {
String handle = pathInfo[0]; final String handle = pathInfo[0];
String collection = pathInfo[1]; final String collection = pathInfo[1];
if (service.findCollectionByHandle(handle, collection) != null) { if (service.findCollectionByHandle(handle, collection) != null) {
return true; return true;
} }
@ -367,14 +389,15 @@ public class FileBasedAtomHandler implements AtomHandler {
/** /**
* Return true if specified pathinfo represents URI of an Atom entry. * Return true if specified pathinfo represents URI of an Atom entry.
*/ */
public boolean isEntryURI(AtomRequest areq) { @Override
public boolean isEntryURI(final AtomRequest areq) {
log.debug("isEntryURI"); log.debug("isEntryURI");
// workspace/collection-singular/fsid // workspace/collection-singular/fsid
// if length is 3 and points to a valid collection then YES // if length is 3 and points to a valid collection then YES
String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); final String[] pathInfo = StringUtils.split(areq.getPathInfo(), "/");
if (pathInfo.length == 3) { if (pathInfo.length == 3) {
String handle = pathInfo[0]; final String handle = pathInfo[0];
String collection = pathInfo[1]; final String collection = pathInfo[1];
if (service.findCollectionByHandle(handle, collection) != null) { if (service.findCollectionByHandle(handle, collection) != null) {
return true; return true;
} }
@ -385,16 +408,17 @@ public class FileBasedAtomHandler implements AtomHandler {
/** /**
* Return true if specified pathinfo represents media-edit URI. * Return true if specified pathinfo represents media-edit URI.
*/ */
public boolean isMediaEditURI(AtomRequest areq) { @Override
public boolean isMediaEditURI(final AtomRequest areq) {
log.debug("isMediaEditURI"); log.debug("isMediaEditURI");
// workspace/collection-singular/fsid/media/fsid // workspace/collection-singular/fsid/media/fsid
// if length is 4, points to a valid collection and fsid is mentioned twice then YES // if length is 4, points to a valid collection and fsid is mentioned twice then YES
String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); final String[] pathInfo = StringUtils.split(areq.getPathInfo(), "/");
if (pathInfo.length == 4) { if (pathInfo.length == 4) {
String handle = pathInfo[0]; final String handle = pathInfo[0];
String collection = pathInfo[1]; final String collection = pathInfo[1];
String media = pathInfo[2]; final String media = pathInfo[2];
String fsid = pathInfo[3]; final String fsid = pathInfo[3];
if (service.findCollectionByHandle(handle, collection) != null && media.equals("media")) { if (service.findCollectionByHandle(handle, collection) != null && media.equals("media")) {
return true; return true;
} }
@ -406,36 +430,36 @@ public class FileBasedAtomHandler implements AtomHandler {
/** /**
* BASIC authentication. * BASIC authentication.
*/ */
public String authenticateBASIC(HttpServletRequest request) { public String authenticateBASIC(final HttpServletRequest request) {
log.debug("authenticateBASIC"); log.debug("authenticateBASIC");
boolean valid = false; boolean valid = false;
String userID = null; String userID = null;
String password = null; String password = null;
try { try {
String authHeader = request.getHeader("Authorization"); final String authHeader = request.getHeader("Authorization");
if (authHeader != null) { if (authHeader != null) {
StringTokenizer st = new StringTokenizer(authHeader); final StringTokenizer st = new StringTokenizer(authHeader);
if (st.hasMoreTokens()) { if (st.hasMoreTokens()) {
String basic = st.nextToken(); final String basic = st.nextToken();
if (basic.equalsIgnoreCase("Basic")) { if (basic.equalsIgnoreCase("Basic")) {
String credentials = st.nextToken(); final String credentials = st.nextToken();
String userPass = new String(Base64.decodeBase64(credentials.getBytes())); final String userPass = new String(Base64.decodeBase64(credentials.getBytes()));
int p = userPass.indexOf(":"); final int p = userPass.indexOf(":");
if (p != -1) { if (p != -1) {
userID = userPass.substring(0, p); userID = userPass.substring(0, p);
password = userPass.substring(p+1); password = userPass.substring(p + 1);
// Validate the User. // Validate the User.
valid = validateUser( userID, password ); valid = validateUser(userID, password);
} }
} }
} }
} }
} catch (Exception e) { } catch (final Exception e) {
log.debug(e); log.debug(e);
} }
if (valid) { if (valid) {
//For now assume userID as userName // For now assume userID as userName
return userID; return userID;
} }
return null; return null;

View file

@ -15,11 +15,12 @@
*/ */
package org.rometools.propono.atom.server.impl; package org.rometools.propono.atom.server.impl;
import org.rometools.propono.atom.server.AtomHandlerFactory;
import org.rometools.propono.atom.server.AtomHandler;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.rometools.propono.atom.server.AtomHandler;
import org.rometools.propono.atom.server.AtomHandlerFactory;
/** /**
* Extends {@link com.sun.syndication.propono.atom.server.AtomHandlerFactory} to create and return * Extends {@link com.sun.syndication.propono.atom.server.AtomHandlerFactory} to create and return
* {@link com.sun.syndication.propono.atom.server.impl.FileBasedAtomHandler}. * {@link com.sun.syndication.propono.atom.server.impl.FileBasedAtomHandler}.
@ -29,9 +30,8 @@ public class FileBasedAtomHandlerFactory extends AtomHandlerFactory {
/** /**
* Create new AtomHandler. * Create new AtomHandler.
*/ */
public AtomHandler newAtomHandler( @Override
HttpServletRequest req, HttpServletResponse res ) { public AtomHandler newAtomHandler(final HttpServletRequest req, final HttpServletResponse res) {
return new FileBasedAtomHandler(req); return new FileBasedAtomHandler(req);
} }
} }

View file

@ -15,17 +15,16 @@
*/ */
package org.rometools.propono.atom.server.impl; package org.rometools.propono.atom.server.impl;
import org.rometools.propono.atom.common.AtomService;
import org.rometools.propono.utils.Utilities;
import java.io.InputStream; import java.io.InputStream;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.TreeMap; import java.util.TreeMap;
import org.rometools.propono.atom.common.AtomService;
import org.rometools.propono.utils.Utilities;
/** /**
* File based Atom service. * File based Atom service. Supports one workspace per user. Collections in workspace are defined in /propono.properties, for example:
* Supports one workspace per user.
* Collections in workspace are defined in /propono.properties, for example:
* *
* <pre> * <pre>
* # Define list of collections to be offered * # Define list of collections to be offered
@ -46,99 +45,108 @@ import java.util.TreeMap;
* propono.atomserver.filebased.collection.gifimages.categories=general,category1,category2 * propono.atomserver.filebased.collection.gifimages.categories=general,category1,category2
* </pre> * </pre>
* *
* If no such properties are found, then service will fall back to two * If no such properties are found, then service will fall back to two collections: 'entries' for Atom entries and 'resources' for any content-type.
* collections: 'entries' for Atom entries and 'resources' for any content-type.
* *
* *
* <p><b>URI structure used for accessing collections and entries</b></p> * <p>
* * <b>URI structure used for accessing collections and entries</b>
* <p>Collection feed (URI allows GET to get collection, POST to add to it)<br/>
* <code>[servlet-context-uri]/app/[workspace-handle]/[collection-plural] </code>
* </p> * </p>
* *
* <p>Collection entry (URI allows GET, PUT and DELETE)<br/> * <p>
* <code>[servlet-context-uri]/app/[workspace-handle]/[collection-singular]/[entryid] </code> * Collection feed (URI allows GET to get collection, POST to add to it)<br/>
* <code>[servlet-context-uri]/app/[workspace-handle]/[collection-plural] </code>
* </p> * </p>
* *
* <p>Collection entry media (URI allows GET, PUT and DELETE)<br/> * <p>
* <code>[servlet-context-uri]/app/[workspace-handle]/[collection-singular]/media/[entryid]</code> * Collection entry (URI allows GET, PUT and DELETE)<br/>
* <code>[servlet-context-uri]/app/[workspace-handle]/[collection-singular]/[entryid] </code>
* </p> * </p>
* *
* <p>Categories URI if not using inline categories (URI allows GET)<br/> * <p>
* <code>[servlet-context-uri]/app/[workspace-handle]/[collection-plural]/categories</code> * Collection entry media (URI allows GET, PUT and DELETE)<br/>
* <code>[servlet-context-uri]/app/[workspace-handle]/[collection-singular]/media/[entryid]</code>
* </p>
*
* <p>
* Categories URI if not using inline categories (URI allows GET)<br/>
* <code>[servlet-context-uri]/app/[workspace-handle]/[collection-plural]/categories</code>
* </p> * </p>
* *
* *
* <p><b>Directory structure used to store collections and entries</b></p> * <p>
* * <b>Directory structure used to store collections and entries</b>
* <p>Collection feed (kept constantly up to date)<br/>
* <code>[servlet-context-dir]/[workspace-handle]/[collection-plural]/feed.xml</code>
* </p> * </p>
* *
* <p>Collection entry (individual entries also stored as entry.xml files)<br/> * <p>
* <code>[servlet-context-dir]/[workspace-handle]/[collection-plural]/id/entry.xml</code> * Collection feed (kept constantly up to date)<br/>
* <code>[servlet-context-dir]/[workspace-handle]/[collection-plural]/feed.xml</code>
* </p> * </p>
* *
* <p>Collection entry media (media file stored under entry directory)<br/> * <p>
* <code>[servlet-context-dir]/[workspace-handle]/[collection-plural]/id/media/id</code> * Collection entry (individual entries also stored as entry.xml files)<br/>
* <code>[servlet-context-dir]/[workspace-handle]/[collection-plural]/id/entry.xml</code>
* </p>
*
* <p>
* Collection entry media (media file stored under entry directory)<br/>
* <code>[servlet-context-dir]/[workspace-handle]/[collection-plural]/id/media/id</code>
* </p> * </p>
*/ */
public class FileBasedAtomService extends AtomService { public class FileBasedAtomService extends AtomService {
private Map workspaceMap = new TreeMap(); private final Map workspaceMap = new TreeMap();
private Map collectionMap = new TreeMap(); private final Map collectionMap = new TreeMap();
private static Properties cacheProps = new Properties(); private static Properties cacheProps = new Properties();
private boolean firstTime = true; private boolean firstTime = true;
/** /**
* Creates a new instance of FileBasedAtomService. * Creates a new instance of FileBasedAtomService.
*/ */
public FileBasedAtomService( public FileBasedAtomService(final String userName, final String baseDir, final String contextURI, final String contextPath, final String servletPath)
String userName, String baseDir, String contextURI, String contextPath, String servletPath) throws Exception { throws Exception {
String workspaceHandle = userName; final String workspaceHandle = userName;
// One workspace per user // One workspace per user
FileBasedWorkspace workspace = new FileBasedWorkspace(workspaceHandle, baseDir); final FileBasedWorkspace workspace = new FileBasedWorkspace(workspaceHandle, baseDir);
workspaceMap.put(userName, workspace); workspaceMap.put(userName, workspace);
if (firstTime) { if (firstTime) {
synchronized(cacheProps) { synchronized (cacheProps) {
InputStream is = getClass().getResourceAsStream("/propono.properties"); final InputStream is = getClass().getResourceAsStream("/propono.properties");
if (is != null) cacheProps.load(is); if (is != null) {
firstTime = false; cacheProps.load(is);
}
firstTime = false;
} }
} }
// can't find propono.properties, so use system props instead // can't find propono.properties, so use system props instead
if (cacheProps == null) cacheProps = System.getProperties(); if (cacheProps == null) {
cacheProps = System.getProperties();
}
String relativeURIsString = cacheProps.getProperty( final String relativeURIsString = cacheProps.getProperty("propono.atomserver.filebased.relativeURIs");
"propono.atomserver.filebased.relativeURIs"); final boolean relativeURIs = "true".equals(relativeURIsString);
boolean relativeURIs = "true".equals(relativeURIsString);
String inlineCategoriesString = cacheProps.getProperty( final String inlineCategoriesString = cacheProps.getProperty("propono.atomserver.filebased.inlineCategories");
"propono.atomserver.filebased.inlineCategories"); final boolean inlineCategories = "true".equals(inlineCategoriesString);
boolean inlineCategories = "true".equals(inlineCategoriesString);
String colnames = cacheProps.getProperty("propono.atomserver.filebased.collections"); final String colnames = cacheProps.getProperty("propono.atomserver.filebased.collections");
if (colnames != null) { if (colnames != null) {
// collections specified in propono.properties, use those // collections specified in propono.properties, use those
String[] colarray = Utilities.stringToStringArray(colnames,","); final String[] colarray = Utilities.stringToStringArray(colnames, ",");
for (int i=0; i<colarray.length; i++) { for (final String element : colarray) {
String prefix = "propono.atomserver.filebased.collection." + colarray[i] + "."; final String prefix = "propono.atomserver.filebased.collection." + element + ".";
String collectionTitle = cacheProps.getProperty(prefix + "title"); final String collectionTitle = cacheProps.getProperty(prefix + "title");
String collectionSingular = cacheProps.getProperty(prefix + "singular"); final String collectionSingular = cacheProps.getProperty(prefix + "singular");
String collectionPlural = cacheProps.getProperty(prefix + "plural"); final String collectionPlural = cacheProps.getProperty(prefix + "plural");
String collectionAccept = cacheProps.getProperty(prefix + "accept"); final String collectionAccept = cacheProps.getProperty(prefix + "accept");
String catNamesString = cacheProps.getProperty(prefix + "categories"); final String catNamesString = cacheProps.getProperty(prefix + "categories");
String[] catNames = Utilities.stringToStringArray(catNamesString, ","); final String[] catNames = Utilities.stringToStringArray(catNamesString, ",");
FileBasedCollection entries = new FileBasedCollection( final FileBasedCollection entries = new FileBasedCollection(collectionTitle, workspaceHandle, collectionPlural, collectionSingular,
collectionTitle, workspaceHandle, collectionAccept, inlineCategories, catNames, relativeURIs, contextURI, contextPath, servletPath, baseDir);
collectionPlural, collectionSingular, collectionAccept,
inlineCategories, catNames,
relativeURIs, contextURI, contextPath, servletPath, baseDir);
workspace.addCollection(entries); workspace.addCollection(entries);
// want to be able to look up collection by singular and plural names // want to be able to look up collection by singular and plural names
collectionMap.put(workspaceHandle + "|" + collectionSingular, entries); collectionMap.put(workspaceHandle + "|" + collectionSingular, entries);
@ -149,23 +157,17 @@ public class FileBasedAtomService extends AtomService {
// Fallback to two collections. One collection for accepting entries // Fallback to two collections. One collection for accepting entries
// and other collection for other ( resources/uploaded images etc.) // and other collection for other ( resources/uploaded images etc.)
String[] catNames = new String[] {"general", "category1", "category2"}; final String[] catNames = new String[] { "general", "category1", "category2" };
FileBasedCollection entries = new FileBasedCollection( final FileBasedCollection entries = new FileBasedCollection("Entries", workspaceHandle, "entries", "entry", "application/atom+xml;type=entry",
"Entries", workspaceHandle, inlineCategories, catNames, relativeURIs, contextURI, contextPath, servletPath, baseDir);
"entries", "entry", "application/atom+xml;type=entry",
inlineCategories, catNames,
relativeURIs, contextURI, contextPath, servletPath, baseDir);
workspace.addCollection(entries); workspace.addCollection(entries);
// want to be able to look up collection by singular and plural names // want to be able to look up collection by singular and plural names
collectionMap.put(workspaceHandle + "|entry", entries); collectionMap.put(workspaceHandle + "|entry", entries);
collectionMap.put(workspaceHandle + "|entries", entries); collectionMap.put(workspaceHandle + "|entries", entries);
FileBasedCollection resources = new FileBasedCollection( final FileBasedCollection resources = new FileBasedCollection("Resources", workspaceHandle, "resources", "resource", "*/*", inlineCategories,
"Resources", workspaceHandle, catNames, relativeURIs, contextURI, contextPath, servletPath, baseDir);
"resources", "resource", "*/*",
inlineCategories, catNames,
relativeURIs, contextURI, contextPath, servletPath, baseDir);
// want to be able to look up collection by singular and plural names // want to be able to look up collection by singular and plural names
workspace.addCollection(resources); workspace.addCollection(resources);
collectionMap.put(workspaceHandle + "|resource", resources); collectionMap.put(workspaceHandle + "|resource", resources);
@ -178,11 +180,11 @@ public class FileBasedAtomService extends AtomService {
/** /**
* Find workspace by handle, returns null of not found. * Find workspace by handle, returns null of not found.
*/ */
FileBasedWorkspace findWorkspaceByHandle(String handle) { FileBasedWorkspace findWorkspaceByHandle(final String handle) {
return (FileBasedWorkspace)workspaceMap.get(handle); return (FileBasedWorkspace) workspaceMap.get(handle);
} }
FileBasedCollection findCollectionByHandle(String handle, String collection) { FileBasedCollection findCollectionByHandle(final String handle, final String collection) {
return (FileBasedCollection)collectionMap.get(handle+"|"+collection); return (FileBasedCollection) collectionMap.get(handle + "|" + collection);
} }
} }

View file

@ -15,10 +15,38 @@
*/ */
package org.rometools.propono.atom.server.impl; package org.rometools.propono.atom.server.impl;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import javax.activation.FileTypeMap;
import javax.activation.MimetypesFileTypeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom2.Document; import org.jdom2.Document;
import org.jdom2.output.XMLOutputter; import org.jdom2.output.XMLOutputter;
import org.rometools.propono.atom.common.Categories;
import org.rometools.propono.atom.common.Collection;
import org.rometools.propono.atom.common.rome.AppModule;
import org.rometools.propono.atom.common.rome.AppModuleImpl;
import org.rometools.propono.atom.server.AtomException;
import org.rometools.propono.atom.server.AtomMediaResource;
import org.rometools.propono.atom.server.AtomNotFoundException;
import org.rometools.propono.utils.Utilities;
import com.sun.syndication.feed.WireFeed; import com.sun.syndication.feed.WireFeed;
import com.sun.syndication.feed.atom.Category; import com.sun.syndication.feed.atom.Category;
@ -31,44 +59,13 @@ import com.sun.syndication.io.WireFeedInput;
import com.sun.syndication.io.WireFeedOutput; import com.sun.syndication.io.WireFeedOutput;
import com.sun.syndication.io.impl.Atom10Generator; import com.sun.syndication.io.impl.Atom10Generator;
import com.sun.syndication.io.impl.Atom10Parser; import com.sun.syndication.io.impl.Atom10Parser;
import org.rometools.propono.atom.common.Categories;
import org.rometools.propono.atom.common.Collection;
import org.rometools.propono.atom.common.rome.AppModule;
import org.rometools.propono.atom.common.rome.AppModuleImpl;
import org.rometools.propono.atom.server.AtomException;
import org.rometools.propono.atom.server.AtomMediaResource;
import org.rometools.propono.atom.server.AtomNotFoundException;
import org.rometools.propono.utils.Utilities;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;
import javax.activation.FileTypeMap;
import javax.activation.MimetypesFileTypeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/** /**
* File based Atom collection implementation. This is the heart of the * File based Atom collection implementation. This is the heart of the file-based Atom service implementation. It provides methods for adding, getting updating
* file-based Atom service implementation. It provides methods for adding, * and deleting Atom entries and media entries.
* getting updating and deleting Atom entries and media entries.
*/ */
public class FileBasedCollection extends Collection { public class FileBasedCollection extends Collection {
private static Log log = private static Log log = LogFactory.getFactory().getInstance(FileBasedCollection.class);
LogFactory.getFactory().getInstance(FileBasedCollection.class);
private String handle = null; private String handle = null;
private String singular = null; private String singular = null;
@ -86,41 +83,27 @@ public class FileBasedCollection extends Collection {
private static final String FEED_TYPE = "atom_1.0"; private static final String FEED_TYPE = "atom_1.0";
/** /**
* Construct by providing title (plain text, no HTML), a workspace handle, * Construct by providing title (plain text, no HTML), a workspace handle, a plural collection name (e.g. entries), a singular collection name (e.g. entry),
* a plural collection name (e.g. entries), a singular collection name * the base directory for file storage, the content-type range accepted by the collection and the root Atom protocol URI for the service.
* (e.g. entry), the base directory for file storage, the content-type *
* range accepted by the collection and the root Atom protocol URI for the * @param title Title of collection (plain text, no HTML)
* service. * @param handle Workspace handle
* @param title Title of collection (plain text, no HTML) * @param collection Collection handle, plural
* @param handle Workspace handle * @param singular Collection handle, singular
* @param collection Collection handle, plural * @param accept Content type range accepted by collection
* @param singular Collection handle, singular * @param inlineCats True for inline categories
* @param accept Content type range accepted by collection * @param catNames Category names for this workspace
* @param inlineCats True for inline categories * @param baseDir Base directory for file storage
* @param catNames Category names for this workspace
* @param baseDir Base directory for file storage
* @param relativeURIs True for relative URIs * @param relativeURIs True for relative URIs
* @param contextURI Absolute URI of context that hosts APP service * @param contextURI Absolute URI of context that hosts APP service
* @param contextPath Context path of APP service (e.g. "/sample-atomserver") * @param contextPath Context path of APP service (e.g. "/sample-atomserver")
* @param servletPath Servlet path of APP service (e.g. "/app") * @param servletPath Servlet path of APP service (e.g. "/app")
*/ */
public FileBasedCollection( public FileBasedCollection(final String title, final String handle, final String collection, final String singular, final String accept,
String title, final boolean inlineCats, final String[] catNames, final boolean relativeURIs, final String contextURI, final String contextPath,
String handle, final String servletPath, final String baseDir) {
String collection, super(title, "text", relativeURIs ? servletPath.substring(1) + "/" + handle + "/" + collection : contextURI + servletPath + "/" + handle + "/"
String singular, + collection);
String accept,
boolean inlineCats,
String[] catNames,
boolean relativeURIs,
String contextURI,
String contextPath,
String servletPath,
String baseDir) {
super(title, "text",
relativeURIs
? servletPath.substring(1) + "/" + handle + "/" + collection
: contextURI + servletPath + "/" + handle + "/" + collection);
this.handle = handle; this.handle = handle;
this.collection = collection; this.collection = collection;
@ -138,40 +121,41 @@ public class FileBasedCollection extends Collection {
/** /**
* Get feed document representing collection. * Get feed document representing collection.
*
* @throws com.sun.syndication.propono.atom.server.AtomException On error retrieving feed file. * @throws com.sun.syndication.propono.atom.server.AtomException On error retrieving feed file.
* @return Atom Feed representing collection. * @return Atom Feed representing collection.
*/ */
public Feed getFeedDocument() throws AtomException { public Feed getFeedDocument() throws AtomException {
InputStream in = null; InputStream in = null;
synchronized(FileStore.getFileStore()) { synchronized (FileStore.getFileStore()) {
in = FileStore.getFileStore().getFileInputStream(getFeedPath()); in = FileStore.getFileStore().getFileInputStream(getFeedPath());
if (in == null) { if (in == null) {
in = createDefaultFeedDocument(contextURI + servletPath + "/" + handle + "/" + collection); in = createDefaultFeedDocument(contextURI + servletPath + "/" + handle + "/" + collection);
} }
} }
try { try {
WireFeedInput input = new WireFeedInput(); final WireFeedInput input = new WireFeedInput();
WireFeed wireFeed = input.build(new InputStreamReader(in, "UTF-8")); final WireFeed wireFeed = input.build(new InputStreamReader(in, "UTF-8"));
return (Feed)wireFeed; return (Feed) wireFeed;
} catch (Exception ex) { } catch (final Exception ex) {
throw new AtomException(ex); throw new AtomException(ex);
} }
} }
/** /**
* Get list of one Categories object containing categories allowed by collection. * Get list of one Categories object containing categories allowed by collection.
* @param inline True if Categories object should contain collection of *
* in-line Categories objects or false if it should set the * @param inline True if Categories object should contain collection of in-line Categories objects or false if it should set the Href for out-of-line
* Href for out-of-line categories. * categories.
*/ */
public List getCategories(boolean inline) { public List getCategories(final boolean inline) {
Categories cats = new Categories(); final Categories cats = new Categories();
cats.setFixed(true); cats.setFixed(true);
cats.setScheme(contextURI + "/" + handle + "/" + singular); cats.setScheme(contextURI + "/" + handle + "/" + singular);
if (inline) { if (inline) {
for (int i=0; i<catNames.length; i++) { for (final String catName : catNames) {
Category cat = new Category(); final Category cat = new Category();
cat.setTerm(catNames[i]); cat.setTerm(catName);
cats.addCategory(cat); cats.addCategory(cat);
} }
} else { } else {
@ -181,33 +165,32 @@ public class FileBasedCollection extends Collection {
} }
/** /**
* Get list of one Categories object containing categories allowed by collection, * Get list of one Categories object containing categories allowed by collection, returns in-line categories if collection set to use in-line categories.
* returns in-line categories if collection set to use in-line categories.
*/ */
@Override
public List getCategories() { public List getCategories() {
return getCategories(inlineCats); return getCategories(inlineCats);
} }
/** /**
* Add entry to collection. * Add entry to collection.
* @param entry Entry to be added to collection. Entry will be saved to disk in a *
* directory under the collection's directory and the path will follow the * @param entry Entry to be added to collection. Entry will be saved to disk in a directory under the collection's directory and the path will follow the
* pattern [collection-plural]/[entryid]/entry.xml. The entry will be added * pattern [collection-plural]/[entryid]/entry.xml. The entry will be added to the collection's feed in [collection-plural]/feed.xml.
* to the collection's feed in [collection-plural]/feed.xml.
* @throws java.lang.Exception On error. * @throws java.lang.Exception On error.
* @return Entry as it exists on the server. * @return Entry as it exists on the server.
*/ */
public Entry addEntry(Entry entry) throws Exception { public Entry addEntry(final Entry entry) throws Exception {
synchronized (FileStore.getFileStore()) { synchronized (FileStore.getFileStore()) {
Feed f = getFeedDocument(); final Feed f = getFeedDocument();
String fsid = FileStore.getFileStore().getNextId(); final String fsid = FileStore.getFileStore().getNextId();
updateTimestamps(entry); updateTimestamps(entry);
// Save entry to file // Save entry to file
String entryPath = getEntryPath(fsid); final String entryPath = getEntryPath(fsid);
OutputStream os = FileStore.getFileStore().getFileOutputStream(entryPath); final OutputStream os = FileStore.getFileStore().getFileOutputStream(entryPath);
updateEntryAppLinks(entry, fsid, true); updateEntryAppLinks(entry, fsid, true);
Atom10Generator.serializeEntry(entry, new OutputStreamWriter(os, "UTF-8")); Atom10Generator.serializeEntry(entry, new OutputStreamWriter(os, "UTF-8"));
os.flush(); os.flush();
@ -222,51 +205,50 @@ public class FileBasedCollection extends Collection {
} }
/** /**
* Add media entry to collection. Accepts a media file to be added to collection. * Add media entry to collection. Accepts a media file to be added to collection. The file will be saved to disk in a directory under the collection's
* The file will be saved to disk in a directory under the collection's directory * directory and the path will follow the pattern <code>[collection-plural]/[entryid]/media/[entryid]</code>. An Atom entry will be created to store
* and the path will follow the pattern <code>[collection-plural]/[entryid]/media/[entryid]</code>. * metadata for the entry and it will exist at the path <code>[collection-plural]/[entryid]/entry.xml</code>. The entry will be added to the collection's
* An Atom entry will be created to store metadata for the entry and it will exist * feed in [collection-plural]/feed.xml.
* at the path <code>[collection-plural]/[entryid]/entry.xml</code>. *
* The entry will be added to the collection's feed in [collection-plural]/feed.xml.
* @param entry Entry object * @param entry Entry object
* @param slug String to be used in file-name * @param slug String to be used in file-name
* @param is Source of media data * @param is Source of media data
* @throws java.lang.Exception On Error * @throws java.lang.Exception On Error
* @return Location URI of entry * @return Location URI of entry
*/ */
public String addMediaEntry(Entry entry, String slug, InputStream is) throws Exception { public String addMediaEntry(final Entry entry, final String slug, final InputStream is) throws Exception {
synchronized (FileStore.getFileStore()) { synchronized (FileStore.getFileStore()) {
// Save media file temp file // Save media file temp file
Content content = (Content)entry.getContents().get(0); final Content content = entry.getContents().get(0);
if (entry.getTitle() == null) { if (entry.getTitle() == null) {
entry.setTitle(slug); entry.setTitle(slug);
} }
String fileName = createFileName((slug != null) ? slug : entry.getTitle(), content.getType()); final String fileName = createFileName(slug != null ? slug : entry.getTitle(), content.getType());
File tempFile = File.createTempFile(fileName, "tmp"); final File tempFile = File.createTempFile(fileName, "tmp");
FileOutputStream fos = new FileOutputStream(tempFile); final FileOutputStream fos = new FileOutputStream(tempFile);
Utilities.copyInputToOutput(is, fos); Utilities.copyInputToOutput(is, fos);
fos.close(); fos.close();
// Save media file // Save media file
FileInputStream fis = new FileInputStream(tempFile); final FileInputStream fis = new FileInputStream(tempFile);
saveMediaFile(fileName, content.getType(), tempFile.length(), fis); saveMediaFile(fileName, content.getType(), tempFile.length(), fis);
fis.close(); fis.close();
File resourceFile = new File(getEntryMediaPath(fileName)); final File resourceFile = new File(getEntryMediaPath(fileName));
// Create media-link entry // Create media-link entry
updateTimestamps(entry); updateTimestamps(entry);
// Save media-link entry // Save media-link entry
String entryPath = getEntryPath(fileName); final String entryPath = getEntryPath(fileName);
OutputStream os = FileStore.getFileStore().getFileOutputStream(entryPath); final OutputStream os = FileStore.getFileStore().getFileOutputStream(entryPath);
updateMediaEntryAppLinks(entry, resourceFile.getName(), true); updateMediaEntryAppLinks(entry, resourceFile.getName(), true);
Atom10Generator.serializeEntry(entry, new OutputStreamWriter(os, "UTF-8")); Atom10Generator.serializeEntry(entry, new OutputStreamWriter(os, "UTF-8"));
os.flush(); os.flush();
os.close(); os.close();
// Update feed with new entry // Update feed with new entry
Feed f = getFeedDocument(); final Feed f = getFeedDocument();
updateMediaEntryAppLinks(entry, resourceFile.getName(), false); updateMediaEntryAppLinks(entry, resourceFile.getName(), false);
updateFeedDocumentWithNewEntry(f, entry); updateFeedDocumentWithNewEntry(f, entry);
@ -276,6 +258,7 @@ public class FileBasedCollection extends Collection {
/** /**
* Get an entry from the collection. * Get an entry from the collection.
*
* @param fsid Internal ID of entry to be returned * @param fsid Internal ID of entry to be returned
* @throws java.lang.Exception On error * @throws java.lang.Exception On error
* @return Entry specified by fileName/ID * @return Entry specified by fileName/ID
@ -285,14 +268,14 @@ public class FileBasedCollection extends Collection {
fsid = fsid.substring(0, fsid.length() - ".media-link".length()); fsid = fsid.substring(0, fsid.length() - ".media-link".length());
} }
String entryPath = getEntryPath(fsid); final String entryPath = getEntryPath(fsid);
checkExistence(entryPath); checkExistence(entryPath);
InputStream in = FileStore.getFileStore().getFileInputStream(entryPath); final InputStream in = FileStore.getFileStore().getFileInputStream(entryPath);
final Entry entry; final Entry entry;
String filePath = getEntryMediaPath(fsid); final String filePath = getEntryMediaPath(fsid);
File resource = new File(fsid); final File resource = new File(fsid);
if (resource.exists()) { if (resource.exists()) {
entry = loadAtomResourceEntry(in, resource); entry = loadAtomResourceEntry(in, resource);
updateMediaEntryAppLinks(entry, fsid, true); updateMediaEntryAppLinks(entry, fsid, true);
@ -306,22 +289,23 @@ public class FileBasedCollection extends Collection {
/** /**
* Get media resource wrapping a file. * Get media resource wrapping a file.
*/ */
public AtomMediaResource getMediaResource(String fileName) throws Exception { public AtomMediaResource getMediaResource(final String fileName) throws Exception {
String filePath = getEntryMediaPath(fileName); final String filePath = getEntryMediaPath(fileName);
File resource = new File(filePath); final File resource = new File(filePath);
return new AtomMediaResource(resource); return new AtomMediaResource(resource);
} }
/** /**
* Update an entry in the collection. * Update an entry in the collection.
*
* @param entry Updated entry to be stored * @param entry Updated entry to be stored
* @param fsid Internal ID of entry * @param fsid Internal ID of entry
* @throws java.lang.Exception On error * @throws java.lang.Exception On error
*/ */
public void updateEntry(Entry entry, String fsid) throws Exception { public void updateEntry(final Entry entry, String fsid) throws Exception {
synchronized (FileStore.getFileStore()) { synchronized (FileStore.getFileStore()) {
Feed f = getFeedDocument(); final Feed f = getFeedDocument();
if (fsid.endsWith(".media-link")) { if (fsid.endsWith(".media-link")) {
fsid = fsid.substring(0, fsid.length() - ".media-link".length()); fsid = fsid.substring(0, fsid.length() - ".media-link".length());
@ -332,8 +316,8 @@ public class FileBasedCollection extends Collection {
updateEntryAppLinks(entry, fsid, false); updateEntryAppLinks(entry, fsid, false);
updateFeedDocumentWithExistingEntry(f, entry); updateFeedDocumentWithExistingEntry(f, entry);
String entryPath = getEntryPath(fsid); final String entryPath = getEntryPath(fsid);
OutputStream os = FileStore.getFileStore().getFileOutputStream(entryPath); final OutputStream os = FileStore.getFileStore().getFileOutputStream(entryPath);
updateEntryAppLinks(entry, fsid, true); updateEntryAppLinks(entry, fsid, true);
Atom10Generator.serializeEntry(entry, new OutputStreamWriter(os, "UTF-8")); Atom10Generator.serializeEntry(entry, new OutputStreamWriter(os, "UTF-8"));
os.flush(); os.flush();
@ -343,40 +327,41 @@ public class FileBasedCollection extends Collection {
/** /**
* Update media associated with a media-link entry. * Update media associated with a media-link entry.
*
* @param fileName Internal ID of entry being updated * @param fileName Internal ID of entry being updated
* @param contentType Content type of data * @param contentType Content type of data
* @param is Source of updated data * @param is Source of updated data
* @throws java.lang.Exception On error * @throws java.lang.Exception On error
* @return Updated Entry as it exists on server * @return Updated Entry as it exists on server
*/ */
public Entry updateMediaEntry(String fileName, String contentType, InputStream is) throws Exception { public Entry updateMediaEntry(final String fileName, final String contentType, final InputStream is) throws Exception {
synchronized (FileStore.getFileStore()) { synchronized (FileStore.getFileStore()) {
File tempFile = File.createTempFile(fileName, "tmp"); final File tempFile = File.createTempFile(fileName, "tmp");
FileOutputStream fos = new FileOutputStream(tempFile); final FileOutputStream fos = new FileOutputStream(tempFile);
Utilities.copyInputToOutput(is, fos); Utilities.copyInputToOutput(is, fos);
fos.close(); fos.close();
// Update media file // Update media file
FileInputStream fis = new FileInputStream(tempFile); final FileInputStream fis = new FileInputStream(tempFile);
saveMediaFile(fileName, contentType, tempFile.length(), fis); saveMediaFile(fileName, contentType, tempFile.length(), fis);
fis.close(); fis.close();
File resourceFile = new File(getEntryMediaPath(fileName)); final File resourceFile = new File(getEntryMediaPath(fileName));
// Load media-link entry to return // Load media-link entry to return
String entryPath = getEntryPath(fileName); final String entryPath = getEntryPath(fileName);
InputStream in = FileStore.getFileStore().getFileInputStream(entryPath); final InputStream in = FileStore.getFileStore().getFileInputStream(entryPath);
Entry atomEntry = loadAtomResourceEntry(in, resourceFile); final Entry atomEntry = loadAtomResourceEntry(in, resourceFile);
updateTimestamps(atomEntry); updateTimestamps(atomEntry);
updateMediaEntryAppLinks(atomEntry, fileName, false); updateMediaEntryAppLinks(atomEntry, fileName, false);
// Update feed with new entry // Update feed with new entry
Feed f = getFeedDocument(); final Feed f = getFeedDocument();
updateFeedDocumentWithExistingEntry(f, atomEntry); updateFeedDocumentWithExistingEntry(f, atomEntry);
// Save updated media-link entry // Save updated media-link entry
OutputStream os = FileStore.getFileStore().getFileOutputStream(entryPath); final OutputStream os = FileStore.getFileStore().getFileOutputStream(entryPath);
updateMediaEntryAppLinks(atomEntry, fileName, true); updateMediaEntryAppLinks(atomEntry, fileName, true);
Atom10Generator.serializeEntry(atomEntry, new OutputStreamWriter(os, "UTF-8")); Atom10Generator.serializeEntry(atomEntry, new OutputStreamWriter(os, "UTF-8"));
os.flush(); os.flush();
@ -388,37 +373,41 @@ public class FileBasedCollection extends Collection {
/** /**
* Delete an entry and any associated media file. * Delete an entry and any associated media file.
*
* @param fsid Internal ID of entry * @param fsid Internal ID of entry
* @throws java.lang.Exception On error * @throws java.lang.Exception On error
*/ */
public void deleteEntry(String fsid) throws Exception { public void deleteEntry(final String fsid) throws Exception {
synchronized (FileStore.getFileStore()) { synchronized (FileStore.getFileStore()) {
// Remove entry from Feed // Remove entry from Feed
Feed feed = getFeedDocument(); final Feed feed = getFeedDocument();
updateFeedDocumentRemovingEntry(feed, fsid); updateFeedDocumentRemovingEntry(feed, fsid);
String entryFilePath = this.getEntryPath(fsid); final String entryFilePath = getEntryPath(fsid);
FileStore.getFileStore().deleteFile(entryFilePath); FileStore.getFileStore().deleteFile(entryFilePath);
String entryMediaPath = this.getEntryMediaPath(fsid); final String entryMediaPath = getEntryMediaPath(fsid);
if (entryMediaPath != null) { if (entryMediaPath != null) {
FileStore.getFileStore().deleteFile(entryMediaPath); FileStore.getFileStore().deleteFile(entryMediaPath);
} }
String entryDirPath = getEntryDirPath(fsid); final String entryDirPath = getEntryDirPath(fsid);
FileStore.getFileStore().deleteDirectory(entryDirPath); FileStore.getFileStore().deleteDirectory(entryDirPath);
try {Thread.sleep(500L);}catch(Exception ignored){} try {
Thread.sleep(500L);
} catch (final Exception ignored) {
}
} }
} }
private void updateFeedDocumentWithNewEntry(Feed f, Entry e) throws AtomException { private void updateFeedDocumentWithNewEntry(final Feed f, final Entry e) throws AtomException {
boolean inserted = false; boolean inserted = false;
for (int i=0; i<f.getEntries().size(); i++) { for (int i = 0; i < f.getEntries().size(); i++) {
Entry entry = (Entry)f.getEntries().get(i); final Entry entry = f.getEntries().get(i);
AppModule mod = (AppModule)entry.getModule(AppModule.URI); final AppModule mod = (AppModule) entry.getModule(AppModule.URI);
AppModule newMod = (AppModule)e.getModule(AppModule.URI); final AppModule newMod = (AppModule) e.getModule(AppModule.URI);
if (newMod.getEdited().before(mod.getEdited())) { if (newMod.getEdited().before(mod.getEdited())) {
f.getEntries().add(i, e); f.getEntries().add(i, e);
inserted = true; inserted = true;
@ -431,21 +420,21 @@ public class FileBasedCollection extends Collection {
updateFeedDocument(f); updateFeedDocument(f);
} }
private void updateFeedDocumentRemovingEntry(Feed f, String id) throws AtomException { private void updateFeedDocumentRemovingEntry(final Feed f, final String id) throws AtomException {
Entry e = findEntry("urn:uuid:" + id, f); final Entry e = findEntry("urn:uuid:" + id, f);
f.getEntries().remove(e); f.getEntries().remove(e);
updateFeedDocument(f); updateFeedDocument(f);
} }
private void updateFeedDocumentWithExistingEntry(Feed f, Entry e) throws AtomException { private void updateFeedDocumentWithExistingEntry(final Feed f, final Entry e) throws AtomException {
Entry old = findEntry(e.getId(), f); final Entry old = findEntry(e.getId(), f);
f.getEntries().remove(old); f.getEntries().remove(old);
boolean inserted = false; boolean inserted = false;
for (int i=0; i<f.getEntries().size(); i++) { for (int i = 0; i < f.getEntries().size(); i++) {
Entry entry = (Entry)f.getEntries().get(i); final Entry entry = f.getEntries().get(i);
AppModule entryAppModule = (AppModule)entry.getModule(AppModule.URI); final AppModule entryAppModule = (AppModule) entry.getModule(AppModule.URI);
AppModule eAppModule = (AppModule)entry.getModule(AppModule.URI); final AppModule eAppModule = (AppModule) entry.getModule(AppModule.URI);
if (eAppModule.getEdited().before(entryAppModule.getEdited())) { if (eAppModule.getEdited().before(entryAppModule.getEdited())) {
f.getEntries().add(i, e); f.getEntries().add(i, e);
inserted = true; inserted = true;
@ -458,80 +447,79 @@ public class FileBasedCollection extends Collection {
updateFeedDocument(f); updateFeedDocument(f);
} }
private Entry findEntry(String id, Feed f) { private Entry findEntry(final String id, final Feed f) {
List l = f.getEntries(); final List l = f.getEntries();
for (Iterator it = l.iterator(); it.hasNext();) { for (final Iterator it = l.iterator(); it.hasNext();) {
Entry e = (Entry)it.next(); final Entry e = (Entry) it.next();
if (id.equals(e.getId())) if (id.equals(e.getId())) {
return e; return e;
}
} }
return null; return null;
} }
private void updateFeedDocument(Feed f) throws AtomException{ private void updateFeedDocument(final Feed f) throws AtomException {
try { try {
synchronized(FileStore.getFileStore()) { synchronized (FileStore.getFileStore()) {
WireFeedOutput wireFeedOutput = new WireFeedOutput(); final WireFeedOutput wireFeedOutput = new WireFeedOutput();
Document feedDoc = wireFeedOutput.outputJDom( f ); final Document feedDoc = wireFeedOutput.outputJDom(f);
XMLOutputter outputter = new XMLOutputter(); final XMLOutputter outputter = new XMLOutputter();
//outputter.setFormat(Format.getPrettyFormat()); // outputter.setFormat(Format.getPrettyFormat());
OutputStream fos = FileStore.getFileStore().getFileOutputStream(getFeedPath()); final OutputStream fos = FileStore.getFileStore().getFileOutputStream(getFeedPath());
outputter.output(feedDoc, new OutputStreamWriter(fos, "UTF-8")); outputter.output(feedDoc, new OutputStreamWriter(fos, "UTF-8"));
} }
} catch (FeedException fex) { } catch (final FeedException fex) {
throw new AtomException(fex); throw new AtomException(fex);
}catch (IOException ex) { } catch (final IOException ex) {
throw new AtomException(ex); throw new AtomException(ex);
} }
} }
private InputStream createDefaultFeedDocument(String uri) throws AtomException { private InputStream createDefaultFeedDocument(final String uri) throws AtomException {
Feed f = new Feed(); final Feed f = new Feed();
f.setTitle("Feed"); f.setTitle("Feed");
f.setId(uri); f.setId(uri);
f.setFeedType( FEED_TYPE); f.setFeedType(FEED_TYPE);
Link selfLink = new Link(); final Link selfLink = new Link();
selfLink.setRel("self"); selfLink.setRel("self");
selfLink.setHref(uri); selfLink.setHref(uri);
f.getOtherLinks().add(selfLink); f.getOtherLinks().add(selfLink);
try { try {
WireFeedOutput wireFeedOutput = new WireFeedOutput(); final WireFeedOutput wireFeedOutput = new WireFeedOutput();
Document feedDoc = wireFeedOutput.outputJDom( f ); final Document feedDoc = wireFeedOutput.outputJDom(f);
XMLOutputter outputter = new XMLOutputter(); final XMLOutputter outputter = new XMLOutputter();
//outputter.setFormat(Format.getCompactFormat()); // outputter.setFormat(Format.getCompactFormat());
OutputStream fos = FileStore.getFileStore().getFileOutputStream(getFeedPath()); final OutputStream fos = FileStore.getFileStore().getFileOutputStream(getFeedPath());
outputter.output(feedDoc, new OutputStreamWriter(fos, "UTF-8")); outputter.output(feedDoc, new OutputStreamWriter(fos, "UTF-8"));
} catch (FeedException ex) { } catch (final FeedException ex) {
throw new AtomException(ex); throw new AtomException(ex);
} catch (IOException ex) { } catch (final IOException ex) {
throw new AtomException(ex); throw new AtomException(ex);
} catch ( Exception e ) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
return FileStore.getFileStore().getFileInputStream(getFeedPath()); return FileStore.getFileStore().getFileInputStream(getFeedPath());
} }
private Entry loadAtomResourceEntry(final InputStream in, final File file) {
private Entry loadAtomResourceEntry(InputStream in, File file) {
try { try {
Entry entry = Atom10Parser.parseEntry( final Entry entry = Atom10Parser.parseEntry(new BufferedReader(new InputStreamReader(in)), null);
new BufferedReader(new InputStreamReader(in)), null);
updateMediaEntryAppLinks(entry, file.getName(), true); updateMediaEntryAppLinks(entry, file.getName(), true);
return entry; return entry;
} catch ( Exception e ) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
return null; return null;
} }
} }
private void updateEntryAppLinks(Entry entry, String fsid, boolean singleEntry) { private void updateEntryAppLinks(final Entry entry, final String fsid, final boolean singleEntry) {
entry.setId("urn:uuid:" + fsid); entry.setId("urn:uuid:" + fsid);
@ -539,8 +527,8 @@ public class FileBasedCollection extends Collection {
Link altLink = null; Link altLink = null;
List altLinks = entry.getAlternateLinks(); List altLinks = entry.getAlternateLinks();
if (altLinks != null) { if (altLinks != null) {
for (Iterator it = altLinks.iterator(); it.hasNext();) { for (final Iterator it = altLinks.iterator(); it.hasNext();) {
Link link = (Link)it.next(); final Link link = (Link) it.next();
if (link.getRel() == null || "alternate".equals(link.getRel())) { if (link.getRel() == null || "alternate".equals(link.getRel())) {
altLink = link; altLink = link;
break; break;
@ -564,8 +552,8 @@ public class FileBasedCollection extends Collection {
Link editLink = null; Link editLink = null;
List otherLinks = entry.getOtherLinks(); List otherLinks = entry.getOtherLinks();
if (otherLinks != null) { if (otherLinks != null) {
for (Iterator it = otherLinks.iterator(); it.hasNext();) { for (final Iterator it = otherLinks.iterator(); it.hasNext();) {
Link link = (Link)it.next(); final Link link = (Link) it.next();
if ("edit".equals(link.getRel())) { if ("edit".equals(link.getRel())) {
editLink = link; editLink = link;
break; break;
@ -586,51 +574,49 @@ public class FileBasedCollection extends Collection {
editLink.setHref(getEntryEditURI(fsid, relativeURIs, singleEntry)); editLink.setHref(getEntryEditURI(fsid, relativeURIs, singleEntry));
} }
private void updateMediaEntryAppLinks(Entry entry, String fileName, boolean singleEntry) { private void updateMediaEntryAppLinks(final Entry entry, final String fileName, final boolean singleEntry) {
// TODO: figure out why PNG is missing from Java MIME types // TODO: figure out why PNG is missing from Java MIME types
FileTypeMap map = FileTypeMap.getDefaultFileTypeMap(); final FileTypeMap map = FileTypeMap.getDefaultFileTypeMap();
if (map instanceof MimetypesFileTypeMap) { if (map instanceof MimetypesFileTypeMap) {
try { try {
((MimetypesFileTypeMap)map).addMimeTypes("image/png png PNG"); ((MimetypesFileTypeMap) map).addMimeTypes("image/png png PNG");
} catch (Exception ignored) {} } catch (final Exception ignored) {
}
} }
String contentType = map.getContentType(fileName); final String contentType = map.getContentType(fileName);
entry.setId(getEntryMediaViewURI(fileName)); entry.setId(getEntryMediaViewURI(fileName));
entry.setTitle(fileName); entry.setTitle(fileName);
entry.setUpdated(new Date()); entry.setUpdated(new Date());
List otherlinks = new ArrayList(); final List otherlinks = new ArrayList();
entry.setOtherLinks(otherlinks); entry.setOtherLinks(otherlinks);
Link editlink = new Link(); final Link editlink = new Link();
editlink.setRel("edit"); editlink.setRel("edit");
editlink.setHref(getEntryEditURI(fileName, relativeURIs, singleEntry)); editlink.setHref(getEntryEditURI(fileName, relativeURIs, singleEntry));
otherlinks.add(editlink); otherlinks.add(editlink);
Link editMedialink = new Link(); final Link editMedialink = new Link();
editMedialink.setRel("edit-media"); editMedialink.setRel("edit-media");
editMedialink.setHref(getEntryMediaEditURI(fileName, relativeURIs, singleEntry)); editMedialink.setHref(getEntryMediaEditURI(fileName, relativeURIs, singleEntry));
otherlinks.add(editMedialink); otherlinks.add(editMedialink);
Content content = (Content)entry.getContents().get(0); final Content content = entry.getContents().get(0);
content.setSrc(getEntryMediaViewURI(fileName)); content.setSrc(getEntryMediaViewURI(fileName));
List contents = new ArrayList(); final List contents = new ArrayList();
contents.add(content); contents.add(content);
entry.setContents(contents); entry.setContents(contents);
} }
/** /**
* Create a Rome Atom entry based on a Roller entry. * Create a Rome Atom entry based on a Roller entry. Content is escaped. Link is stored as rel=alternate link.
* Content is escaped.
* Link is stored as rel=alternate link.
*/ */
private Entry loadAtomEntry(InputStream in) { private Entry loadAtomEntry(final InputStream in) {
try { try {
return Atom10Parser.parseEntry( return Atom10Parser.parseEntry(new BufferedReader(new InputStreamReader(in, "UTF-8")), null);
new BufferedReader(new InputStreamReader(in, "UTF-8")), null); } catch (final Exception e) {
} catch ( Exception e ) {
e.printStackTrace(); e.printStackTrace();
return null; return null;
} }
@ -639,35 +625,34 @@ public class FileBasedCollection extends Collection {
/** /**
* Update existing or add new app:edited. * Update existing or add new app:edited.
*/ */
private void updateTimestamps(Entry entry) { private void updateTimestamps(final Entry entry) {
// We're not differenting between an update and an edit (yet) // We're not differenting between an update and an edit (yet)
entry.setUpdated(new Date()); entry.setUpdated(new Date());
AppModule appModule = (AppModule)entry.getModule(AppModule.URI); AppModule appModule = (AppModule) entry.getModule(AppModule.URI);
if (appModule == null) { if (appModule == null) {
appModule = new AppModuleImpl(); appModule = new AppModuleImpl();
List modules = entry.getModules()==null ? new ArrayList() : entry.getModules(); final List modules = entry.getModules() == null ? new ArrayList() : entry.getModules();
modules.add(appModule); modules.add(appModule);
entry.setModules(modules); entry.setModules(modules);
} }
appModule.setEdited(entry.getUpdated()); appModule.setEdited(entry.getUpdated());
} }
/** /**
* Save file to website's resource directory. * Save file to website's resource directory.
*
* @param handle Weblog handle to save to * @param handle Weblog handle to save to
* @param name Name of file to save * @param name Name of file to save
* @param size Size of file to be saved * @param size Size of file to be saved
* @param is Read file from input stream * @param is Read file from input stream
*/ */
private void saveMediaFile( private void saveMediaFile(final String name, final String contentType, final long size, final InputStream is) throws AtomException {
String name, String contentType, long size, InputStream is) throws AtomException {
byte[] buffer = new byte[8192]; final byte[] buffer = new byte[8192];
int bytesRead = 0; int bytesRead = 0;
File dirPath = new File(getEntryMediaPath(name)); final File dirPath = new File(getEntryMediaPath(name));
if (!dirPath.getParentFile().exists()) { if (!dirPath.getParentFile().exists()) {
dirPath.getParentFile().mkdirs(); dirPath.getParentFile().mkdirs();
} }
@ -677,73 +662,67 @@ public class FileBasedCollection extends Collection {
while ((bytesRead = is.read(buffer, 0, 8192)) != -1) { while ((bytesRead = is.read(buffer, 0, 8192)) != -1) {
bos.write(buffer, 0, bytesRead); bos.write(buffer, 0, bytesRead);
} }
} catch (Exception e) { } catch (final Exception e) {
throw new AtomException("ERROR uploading file", e); throw new AtomException("ERROR uploading file", e);
} finally { } finally {
try { try {
bos.flush(); bos.flush();
bos.close(); bos.close();
} catch (Exception ignored) {} } catch (final Exception ignored) {
}
} }
} }
/** /**
* Creates a file name for a file based on a weblog handle, title string and a * Creates a file name for a file based on a weblog handle, title string and a content-type.
* content-type.
* *
* @param handle Weblog handle * @param handle Weblog handle
* @param title Title to be used as basis for file name (or null) * @param title Title to be used as basis for file name (or null)
* @param contentType Content type of file (must not be null) * @param contentType Content type of file (must not be null)
* *
* If a title is specified, the method will apply the same create-anchor * If a title is specified, the method will apply the same create-anchor logic we use for weblog entries to create a file name based on the
* logic we use for weblog entries to create a file name based on the title. * title.
* *
* If title is null, the base file name will be the weblog handle plus a * If title is null, the base file name will be the weblog handle plus a YYYYMMDDHHSS timestamp.
* YYYYMMDDHHSS timestamp.
* *
* The extension will be formed by using the part of content type that * The extension will be formed by using the part of content type that comes after he slash.
* comes after he slash.
* *
* For example: * For example: weblog.handle = "daveblog" title = "Port Antonio" content-type = "image/jpg" Would result in port_antonio.jpg
* weblog.handle = "daveblog"
* title = "Port Antonio"
* content-type = "image/jpg"
* Would result in port_antonio.jpg
* *
* Another example: * Another example: weblog.handle = "daveblog" title = null content-type = "image/jpg" Might result in daveblog-200608201034.jpg
* weblog.handle = "daveblog"
* title = null
* content-type = "image/jpg"
* Might result in daveblog-200608201034.jpg
*/ */
private String createFileName(String title, String contentType) { private String createFileName(final String title, final String contentType) {
if (handle == null) throw new IllegalArgumentException("weblog handle cannot be null"); if (handle == null) {
if (contentType == null) throw new IllegalArgumentException("contentType cannot be null"); throw new IllegalArgumentException("weblog handle cannot be null");
}
if (contentType == null) {
throw new IllegalArgumentException("contentType cannot be null");
}
String fileName = null; String fileName = null;
SimpleDateFormat sdf = new SimpleDateFormat(); final SimpleDateFormat sdf = new SimpleDateFormat();
sdf.applyPattern("yyyyMMddHHssSSS"); sdf.applyPattern("yyyyMMddHHssSSS");
// Determine the extension based on the contentType. This is a hack. // Determine the extension based on the contentType. This is a hack.
// The info we need to map from contentType to file extension is in // The info we need to map from contentType to file extension is in
// JRE/lib/content-type.properties, but Java Activation doesn't provide // JRE/lib/content-type.properties, but Java Activation doesn't provide
// a way to do a reverse mapping or to get at the data. // a way to do a reverse mapping or to get at the data.
String[] typeTokens = contentType.split("/"); final String[] typeTokens = contentType.split("/");
String ext = typeTokens[1]; final String ext = typeTokens[1];
if (title != null && !title.trim().equals("")) { if (title != null && !title.trim().equals("")) {
// We've got a title, so use it to build file name // We've got a title, so use it to build file name
String base = Utilities.replaceNonAlphanumeric(title, ' '); final String base = Utilities.replaceNonAlphanumeric(title, ' ');
StringTokenizer toker = new StringTokenizer(base); final StringTokenizer toker = new StringTokenizer(base);
String tmp = null; String tmp = null;
int count = 0; int count = 0;
while (toker.hasMoreTokens() && count < 5) { while (toker.hasMoreTokens() && count < 5) {
String s = toker.nextToken(); String s = toker.nextToken();
s = s.toLowerCase(); s = s.toLowerCase();
tmp = (tmp == null) ? s : tmp + "_" + s; tmp = tmp == null ? s : tmp + "_" + s;
count++; count++;
} }
fileName = tmp + "-" + sdf.format(new Date()) + "." + ext; fileName = tmp + "-" + sdf.format(new Date()) + "." + ext;
@ -757,9 +736,9 @@ public class FileBasedCollection extends Collection {
return fileName; return fileName;
} }
//------------------------------------------------------------ URI methods // ------------------------------------------------------------ URI methods
private String getEntryEditURI(String fsid, boolean relative, boolean singleEntry) { private String getEntryEditURI(final String fsid, final boolean relative, final boolean singleEntry) {
String entryURI = null; String entryURI = null;
if (relative) { if (relative) {
if (singleEntry) { if (singleEntry) {
@ -773,11 +752,11 @@ public class FileBasedCollection extends Collection {
return entryURI; return entryURI;
} }
private String getEntryViewURI(String fsid) { private String getEntryViewURI(final String fsid) {
return contextURI + "/" + handle + "/" + collection + "/" + fsid + "/entry.xml"; return contextURI + "/" + handle + "/" + collection + "/" + fsid + "/entry.xml";
} }
private String getEntryMediaEditURI(String fsid, boolean relative, boolean singleEntry) { private String getEntryMediaEditURI(final String fsid, final boolean relative, final boolean singleEntry) {
String entryURI = null; String entryURI = null;
if (relative) { if (relative) {
if (singleEntry) { if (singleEntry) {
@ -792,7 +771,7 @@ public class FileBasedCollection extends Collection {
} }
private String getEntryMediaViewURI(String fsid) { private String getEntryMediaViewURI(final String fsid) {
return contextURI + "/" + handle + "/" + collection + "/" + fsid + "/media/" + fsid; return contextURI + "/" + handle + "/" + collection + "/" + fsid + "/media/" + fsid;
} }
@ -804,31 +783,29 @@ public class FileBasedCollection extends Collection {
} }
} }
//------------------------------------------------------- File path methods // ------------------------------------------------------- File path methods
private String getBaseDir() { private String getBaseDir() {
return baseDir; return baseDir;
} }
private String getFeedPath() { private String getFeedPath() {
return getBaseDir() + handle return getBaseDir() + handle + File.separator + collection + File.separator + "feed.xml";
+ File.separator + collection + File.separator+ "feed.xml";
} }
private String getEntryDirPath(String id) { private String getEntryDirPath(final String id) {
return getBaseDir() + handle return getBaseDir() + handle + File.separator + collection + File.separator + id;
+ File.separator + collection + File.separator + id;
} }
private String getEntryPath(String id) { private String getEntryPath(final String id) {
return getEntryDirPath(id) + File.separator + "entry.xml"; return getEntryDirPath(id) + File.separator + "entry.xml";
} }
private String getEntryMediaPath(String id) { private String getEntryMediaPath(final String id) {
return getEntryDirPath(id) + File.separator + "media" + File.separator + id; return getEntryDirPath(id) + File.separator + "media" + File.separator + id;
} }
private static void checkExistence(String path) throws AtomNotFoundException{ private static void checkExistence(final String path) throws AtomNotFoundException {
if (!FileStore.getFileStore().exists(path)) { if (!FileStore.getFileStore().exists(path)) {
throw new AtomNotFoundException("Entry does not exist"); throw new AtomNotFoundException("Entry does not exist");
} }

View file

@ -25,7 +25,7 @@ public class FileBasedWorkspace extends Workspace {
private String handle = null; private String handle = null;
/** Creates a new instance of FileBasedWorkspace */ /** Creates a new instance of FileBasedWorkspace */
public FileBasedWorkspace(String handle, String baseDir) { public FileBasedWorkspace(final String handle, final String baseDir) {
super(handle, "text"); super(handle, "text");
this.handle = handle; this.handle = handle;
this.baseDir = baseDir; this.baseDir = baseDir;

View file

@ -24,6 +24,7 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import org.apache.commons.lang.RandomStringUtils; import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -33,59 +34,58 @@ import org.apache.commons.logging.LogFactory;
*/ */
class FileStore { class FileStore {
private static Log log = private static Log log = LogFactory.getFactory().getInstance(FileStore.class);
LogFactory.getFactory().getInstance(FileStore.class);
private static final FileStore fileStore = new FileStore(); private static final FileStore fileStore = new FileStore();
public String getNextId() { public String getNextId() {
//return UUID.randomUUID().toString(); // requires JDK 1.5 // return UUID.randomUUID().toString(); // requires JDK 1.5
return RandomStringUtils.randomAlphanumeric(20); return RandomStringUtils.randomAlphanumeric(20);
} }
public boolean exists(String path) { public boolean exists(final String path) {
File f = new File(path); final File f = new File(path);
return f.exists(); return f.exists();
} }
public InputStream getFileInputStream(String path) { public InputStream getFileInputStream(final String path) {
log.debug("getFileContents path: " + path); log.debug("getFileContents path: " + path);
try { try {
return new BufferedInputStream(new FileInputStream(path)); return new BufferedInputStream(new FileInputStream(path));
} catch (FileNotFoundException e) { } catch (final FileNotFoundException e) {
log.debug(" File not found: " + path); log.debug(" File not found: " + path);
return null; return null;
} }
} }
public OutputStream getFileOutputStream(String path) { public OutputStream getFileOutputStream(final String path) {
log.debug("getFileOutputStream path: " + path); log.debug("getFileOutputStream path: " + path);
try { try {
File f = new File(path); final File f = new File(path);
f.getParentFile().mkdirs(); f.getParentFile().mkdirs();
return new BufferedOutputStream(new FileOutputStream(f)); return new BufferedOutputStream(new FileOutputStream(f));
} catch (FileNotFoundException e) { } catch (final FileNotFoundException e) {
log.debug(" File not found: " + path); log.debug(" File not found: " + path);
return null; return null;
} }
} }
public void createOrUpdateFile(String path, InputStream content) throws FileNotFoundException, IOException { public void createOrUpdateFile(final String path, final InputStream content) throws FileNotFoundException, IOException {
log.debug("createOrUpdateFile path: " + path); log.debug("createOrUpdateFile path: " + path);
File f = new File(path); final File f = new File(path);
f.mkdirs(); f.mkdirs();
FileOutputStream out = new FileOutputStream(f); final FileOutputStream out = new FileOutputStream(f);
byte[] buffer = new byte[2048]; final byte[] buffer = new byte[2048];
int read; int read;
while ((read = content.read(buffer)) != -1) { while ((read = content.read(buffer)) != -1) {
out.write(buffer, 0, read); out.write(buffer, 0, read);
} }
} }
public void deleteFile(String path) { public void deleteFile(final String path) {
log.debug("deleteFile path: " + path); log.debug("deleteFile path: " + path);
File f = new File(path); final File f = new File(path);
if (!f.delete()) { if (!f.delete()) {
log.debug(" Failed to delete: " + f.getAbsolutePath()); log.debug(" Failed to delete: " + f.getAbsolutePath());
} }
@ -95,22 +95,22 @@ class FileStore {
return fileStore; return fileStore;
} }
public boolean deleteDirectory(String path) { public boolean deleteDirectory(final String path) {
return deleteDirectory(new File(path)); return deleteDirectory(new File(path));
} }
public boolean deleteDirectory(File path) { public boolean deleteDirectory(final File path) {
log.debug("deleteDirectory path: " + path); log.debug("deleteDirectory path: " + path);
if( path.exists() ) { if (path.exists()) {
File[] files = path.listFiles(); final File[] files = path.listFiles();
for(int i=0; i<files.length; i++) { for (final File file : files) {
if(files[i].isDirectory()) { if (file.isDirectory()) {
deleteDirectory(files[i]); deleteDirectory(file);
} else { } else {
files[i].delete(); file.delete();
} }
} }
} }
return( path.delete() ); return path.delete();
} }
} }

View file

@ -23,29 +23,29 @@ import java.util.List;
* Base implementation of a blog entry. * Base implementation of a blog entry.
*/ */
public abstract class BaseBlogEntry implements BlogEntry { public abstract class BaseBlogEntry implements BlogEntry {
protected String id = null; protected String id = null;
protected Person author = null; protected Person author = null;
protected Content content = null; protected Content content = null;
protected String title = null; protected String title = null;
protected String permalink = null; protected String permalink = null;
protected String summary = null; protected String summary = null;
protected Date modificationDate = null; protected Date modificationDate = null;
protected Date publicationDate = null; protected Date publicationDate = null;
protected List categories = new ArrayList(); protected List categories = new ArrayList();
protected boolean draft = false; protected boolean draft = false;
private Blog blog = null; private Blog blog = null;
/** /**
* Contruct abstract blog entry. * Contruct abstract blog entry.
*/ */
public BaseBlogEntry(Blog blog) { public BaseBlogEntry(final Blog blog) {
this.blog = blog; this.blog = blog;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String getId() { public String getId() {
return id; return id;
} }
@ -53,17 +53,19 @@ public abstract class BaseBlogEntry implements BlogEntry {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String getPermalink() { public String getPermalink() {
return permalink; return permalink;
} }
void setPermalink(String permalink) { void setPermalink(final String permalink) {
this.permalink = permalink; this.permalink = permalink;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public Person getAuthor() { public Person getAuthor() {
return author; return author;
} }
@ -71,13 +73,15 @@ public abstract class BaseBlogEntry implements BlogEntry {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void setAuthor(Person author) { @Override
public void setAuthor(final Person author) {
this.author = author; this.author = author;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public Content getContent() { public Content getContent() {
return content; return content;
} }
@ -85,13 +89,15 @@ public abstract class BaseBlogEntry implements BlogEntry {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void setContent(Content content) { @Override
public void setContent(final Content content) {
this.content = content; this.content = content;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public boolean getDraft() { public boolean getDraft() {
return draft; return draft;
} }
@ -99,13 +105,15 @@ public abstract class BaseBlogEntry implements BlogEntry {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void setDraft(boolean draft) { @Override
public void setDraft(final boolean draft) {
this.draft = draft; this.draft = draft;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public Date getPublicationDate() { public Date getPublicationDate() {
return publicationDate; return publicationDate;
} }
@ -113,13 +121,15 @@ public abstract class BaseBlogEntry implements BlogEntry {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void setPublicationDate(Date pubDate) { @Override
this.publicationDate = pubDate; public void setPublicationDate(final Date pubDate) {
publicationDate = pubDate;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public Date getModificationDate() { public Date getModificationDate() {
return modificationDate; return modificationDate;
} }
@ -127,13 +137,15 @@ public abstract class BaseBlogEntry implements BlogEntry {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void setModificationDate(Date date) { @Override
public void setModificationDate(final Date date) {
modificationDate = date; modificationDate = date;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String getTitle() { public String getTitle() {
return title; return title;
} }
@ -141,13 +153,15 @@ public abstract class BaseBlogEntry implements BlogEntry {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void setTitle(String title) { @Override
public void setTitle(final String title) {
this.title = title; this.title = title;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String getSummary() { public String getSummary() {
return summary; return summary;
} }
@ -155,13 +169,15 @@ public abstract class BaseBlogEntry implements BlogEntry {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void setSummary(String summary) { @Override
public void setSummary(final String summary) {
this.summary = summary; this.summary = summary;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public List getCategories() { public List getCategories() {
return categories; return categories;
} }
@ -169,24 +185,27 @@ public abstract class BaseBlogEntry implements BlogEntry {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void setCategories(List categories) { @Override
public void setCategories(final List categories) {
this.categories = categories; this.categories = categories;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public Blog getBlog() { public Blog getBlog() {
return blog; return blog;
} }
void setBlog(Blog blog) { void setBlog(final Blog blog) {
this.blog = blog; this.blog = blog;
} }
/** /**
* String representation, returns id. * String representation, returns id.
*/ */
@Override
public String toString() { public String toString() {
return id; return id;
} }

View file

@ -15,32 +15,34 @@
*/ */
package org.rometools.propono.blogclient; package org.rometools.propono.blogclient;
import java.util.List;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
/** /**
* <p>Represents a blog, which has collections of entries and resources. * <p>
* You can access the collections using the getCollections() and * Represents a blog, which has collections of entries and resources. You can access the collections using the getCollections() and getCollection(String name)
* getCollection(String name) methods, which return Blog.Collection objects, * methods, which return Blog.Collection objects, which you can use to create, retrieve update or delete entries within a collection.
* which you can use to create, retrieve update or delete entries within * </p>
* a collection.</p>
*/ */
public interface Blog { public interface Blog {
/** /**
* Token can be used to fetch this blog again from getBlog() method. * Token can be used to fetch this blog again from getBlog() method.
*
* @return Blog object specified by token. * @return Blog object specified by token.
*/ */
public String getToken(); public String getToken();
/** /**
* Name of this blog. * Name of this blog.
*
* @return Display name of this blog. * @return Display name of this blog.
*/ */
public String getName(); public String getName();
/** /**
* Get a single BlogEntry (or BlogResource) by token. * Get a single BlogEntry (or BlogResource) by token.
*
* @param token Token from blog entry's getToken() method. * @param token Token from blog entry's getToken() method.
* @throws com.sun.syndication.propono.blogclient.BlogClientException On error fetching the blog entry. * @throws com.sun.syndication.propono.blogclient.BlogClientException On error fetching the blog entry.
* @return Blog entry specified by token. * @return Blog entry specified by token.
@ -48,8 +50,8 @@ public interface Blog {
public BlogEntry getEntry(String token) throws BlogClientException; public BlogEntry getEntry(String token) throws BlogClientException;
/** /**
* Gets listing of entry and resource collections available in the blog, * Gets listing of entry and resource collections available in the blog, including the primary collections.
* including the primary collections. *
* @throws BlogClientException On error fetching collections. * @throws BlogClientException On error fetching collections.
* @return List of Blog.Collection objects. * @return List of Blog.Collection objects.
*/ */
@ -57,6 +59,7 @@ public interface Blog {
/** /**
* Get collection by token. * Get collection by token.
*
* @param token Token from a collection's getToken() method. * @param token Token from a collection's getToken() method.
* @throws BlogClientException On error fetching collection. * @throws BlogClientException On error fetching collection.
* @return Blog.Collection object. * @return Blog.Collection object.
@ -70,30 +73,35 @@ public interface Blog {
/** /**
* Get blog that contains this collection. * Get blog that contains this collection.
*
* @return Blog that contains this collection. * @return Blog that contains this collection.
*/ */
public Blog getBlog(); public Blog getBlog();
/** /**
* Title of collection. * Title of collection.
*
* @return Title of collecton. * @return Title of collecton.
*/ */
public String getTitle(); public String getTitle();
/** /**
* Token that can be used to fetch collection. * Token that can be used to fetch collection.
*
* @return Token that can be used to fetch collection. * @return Token that can be used to fetch collection.
*/ */
public String getToken(); public String getToken();
/** /**
* Content-types accepted by collection. * Content-types accepted by collection.
*
* @return Comma-separated list of content-types accepted. * @return Comma-separated list of content-types accepted.
*/ */
public List getAccepts(); public List getAccepts();
/** /**
* Determines if collection will accept a content-type. * Determines if collection will accept a content-type.
*
* @param contentType Content-type to be considered. * @param contentType Content-type to be considered.
* @return True of content type will be accepted, false otherwise. * @return True of content type will be accepted, false otherwise.
*/ */
@ -101,25 +109,26 @@ public interface Blog {
/** /**
* Return categories allowed by colletion. * Return categories allowed by colletion.
*
* @throws BlogClientException On error fetching categories. * @throws BlogClientException On error fetching categories.
* @return List of BlogEntry.Category objects for this collection. * @return List of BlogEntry.Category objects for this collection.
*/ */
public List getCategories() throws BlogClientException; public List getCategories() throws BlogClientException;
/** /**
* Create but do not save new entry in collection. * Create but do not save new entry in collection. To save entry, call its save() method.
* To save entry, call its save() method. *
* @throws BlogClientException On error creating entry. * @throws BlogClientException On error creating entry.
* @return New BlogEntry object. * @return New BlogEntry object.
*/ */
public BlogEntry newEntry() throws BlogClientException; public BlogEntry newEntry() throws BlogClientException;
/** /**
* Create but do not save new resource in collection. * Create but do not save new resource in collection. To save resource, call its save() method.
* To save resource, call its save() method. *
* @param name Name of new resource. * @param name Name of new resource.
* @param contentType MIME content-type of new resource. * @param contentType MIME content-type of new resource.
* @param bytes Data for new resource. * @param bytes Data for new resource.
* @throws BlogClientException On error creating entry. * @throws BlogClientException On error creating entry.
* @return New BlogResource object, * @return New BlogResource object,
*/ */
@ -127,14 +136,15 @@ public interface Blog {
/** /**
* Get iterator over entries/resources in this collection. * Get iterator over entries/resources in this collection.
*
* @return List of BlogEntry objects, some may be BlogResources. * @return List of BlogEntry objects, some may be BlogResources.
* @throws BlogClientException On error fetching entries/resources. * @throws BlogClientException On error fetching entries/resources.
*/ */
public Iterator getEntries() throws BlogClientException; public Iterator getEntries() throws BlogClientException;
/** /**
* Save or update a BlogEntry in this collection by adding it to this * Save or update a BlogEntry in this collection by adding it to this collection and then calling it's entry.save() method.
* collection and then calling it's entry.save() method. *
* @param entry BlogEntry to be saved. * @param entry BlogEntry to be saved.
* @throws BlogClientException On error saving entry. * @throws BlogClientException On error saving entry.
* @return URI of entry. * @return URI of entry.
@ -143,6 +153,7 @@ public interface Blog {
/** /**
* Save or update resource in this collection * Save or update resource in this collection
*
* @param resource BlogResource to be saved. * @param resource BlogResource to be saved.
* @throws BlogClientException On error saving resource. * @throws BlogClientException On error saving resource.
* @return URI of resource. * @return URI of resource.
@ -150,64 +161,66 @@ public interface Blog {
public String saveResource(BlogResource resource) throws BlogClientException; public String saveResource(BlogResource resource) throws BlogClientException;
} }
// Deprecated primary collection methods, instead use collections directly. // Deprecated primary collection methods, instead use collections directly.
/** /**
* Get iterator over entries in primary entries collection (the first * Get iterator over entries in primary entries collection (the first collection that accepts entries). Note that entries may be partial, so don't try to
* collection that accepts entries). Note that entries may be partial, * update and save them: to update and entry, first fetch it with getEntry(), change fields, then call entry.save();
* so don't try to update and save them: to update and entry, first fetch *
* it with getEntry(), change fields, then call entry.save();
* @return To iterate over all entries in collection. * @return To iterate over all entries in collection.
* @throws BlogClientException On failure or if there is no primary entries collection. * @throws BlogClientException On failure or if there is no primary entries collection.
* *
* @deprecated Instead use collections directly. * @deprecated Instead use collections directly.
*/ */
@Deprecated
public Iterator getEntries() throws BlogClientException; public Iterator getEntries() throws BlogClientException;
/** /**
* Get entries in primary resources collection (the first * Get entries in primary resources collection (the first collection that accepts anything other than entries).
* collection that accepts anything other than entries). *
* @throws BlogClientException On failure or if there is no primary resources collection. * @throws BlogClientException On failure or if there is no primary resources collection.
* @return To iterate over all resojrces in collection. * @return To iterate over all resojrces in collection.
* *
* @deprecated Instead use collections directly. * @deprecated Instead use collections directly.
*/ */
@Deprecated
public Iterator getResources() throws BlogClientException; public Iterator getResources() throws BlogClientException;
/** /**
* Create but do not save it to server new BlogEntry in primary entries collection * Create but do not save it to server new BlogEntry in primary entries collection (the first collection found that accepts entries). To save the entry to
* (the first collection found that accepts entries). To save the entry to the * the server to a collection, use the entry's save() method.
* server to a collection, use the entry's save() method. *
* @throws BlogClientException On error or if there is no primary entries collection. * @throws BlogClientException On error or if there is no primary entries collection.
* @return Unsaved BlogEntry in primary entries collection. * @return Unsaved BlogEntry in primary entries collection.
* *
* @deprecated Instead use collections directly. * @deprecated Instead use collections directly.
*/ */
@Deprecated
public BlogEntry newEntry() throws BlogClientException; public BlogEntry newEntry() throws BlogClientException;
/** /**
* Create but do not save it to server new BlogResource in primary resources collection * Create but do not save it to server new BlogResource in primary resources collection (the first collection found that accepts resources). To save the
* (the first collection found that accepts resources). To save the resource to the * resource to the server to a collection, use the resource's save() method.
* server to a collection, use the resource's save() method. *
* @param name Name of resource to be saved. * @param name Name of resource to be saved.
* @param type MIME content type of resource data. * @param type MIME content type of resource data.
* @param bytes Bytes of resource data. * @param bytes Bytes of resource data.
* @throws BlogClientException On error or if there is no primary respurces collection. * @throws BlogClientException On error or if there is no primary respurces collection.
* @return Unsaved BlogEntry in primary resources collection. * @return Unsaved BlogEntry in primary resources collection.
* *
* @deprecated Instead use collections directly. * @deprecated Instead use collections directly.
*/ */
public BlogResource newResource(String name, String type, byte[] bytes) @Deprecated
throws BlogClientException; public BlogResource newResource(String name, String type, byte[] bytes) throws BlogClientException;
/** /**
* Returns list of available BlogEntry.Category in primary entries collection. * Returns list of available BlogEntry.Category in primary entries collection.
*
* @throws BlogClientException On error or if there is no primary entries collection. * @throws BlogClientException On error or if there is no primary entries collection.
* @return List of BlogEntry.Category objects. * @return List of BlogEntry.Category objects.
* *
* @deprecated Instead use collections directly. * @deprecated Instead use collections directly.
*/ */
@Deprecated
public List getCategories() throws BlogClientException; public List getCategories() throws BlogClientException;
} }

View file

@ -16,25 +16,26 @@
package org.rometools.propono.blogclient; package org.rometools.propono.blogclient;
/** /**
* Represents a Blog Client exception, the library throws these instead of * Represents a Blog Client exception, the library throws these instead of implementation specific exceptions.
* implementation specific exceptions.
*/ */
public class BlogClientException extends Exception { public class BlogClientException extends Exception {
/** /**
* Construct a new exception * Construct a new exception
*
* @param msg Text message that explains exception * @param msg Text message that explains exception
*/ */
public BlogClientException(String msg) { public BlogClientException(final String msg) {
super(msg); super(msg);
} }
/** /**
* Construct a new exception which wraps a throwable. * Construct a new exception which wraps a throwable.
*
* @param msg Text message that explains exception * @param msg Text message that explains exception
* @param t Throwable to be wrapped by exception * @param t Throwable to be wrapped by exception
*/ */
public BlogClientException(String msg, Throwable t) { public BlogClientException(final String msg, final Throwable t) {
super(msg, t); super(msg, t);
} }
} }

View file

@ -18,8 +18,7 @@ package org.rometools.propono.blogclient;
import java.util.List; import java.util.List;
/** /**
* A BlogConnection is a single-user connection to a blog server where the user * A BlogConnection is a single-user connection to a blog server where the user has access to multiple blogs, which are each represented by a Blog interface.
* has access to multiple blogs, which are each represented by a Blog interface.
*/ */
public interface BlogConnection { public interface BlogConnection {

View file

@ -27,54 +27,46 @@ public class BlogConnectionFactory {
// 2) privide contructor that accepts three strings args: url, username and password. // 2) privide contructor that accepts three strings args: url, username and password.
// TODO: make implementations configurable // TODO: make implementations configurable
private static String ATOMPROTOCOL_IMPL_CLASS = private static String ATOMPROTOCOL_IMPL_CLASS = "com.sun.syndication.propono.blogclient.atomprotocol.AtomConnection";
"com.sun.syndication.propono.blogclient.atomprotocol.AtomConnection";
private static String METAWEBLOG_IMPL_CLASS = private static String METAWEBLOG_IMPL_CLASS = "com.sun.syndication.propono.blogclient.metaweblog.MetaWeblogConnection";
"com.sun.syndication.propono.blogclient.metaweblog.MetaWeblogConnection";
/** /**
* Create a connection to a blog server. * Create a connection to a blog server.
* @param type Connection type, must be "atom" or "metaweblog" *
* @param url End-point URL to connect to * @param type Connection type, must be "atom" or "metaweblog"
* @param username Username for login to blog server * @param url End-point URL to connect to
* @param password Password for login to blog server * @param username Username for login to blog server
*/ * @param password Password for login to blog server
public static BlogConnection getBlogConnection( */
String type, String url, String username, String password) public static BlogConnection getBlogConnection(final String type, final String url, final String username, final String password)
throws BlogClientException { throws BlogClientException {
BlogConnection blogConnection = null; BlogConnection blogConnection = null;
if (type == null || type.equals("metaweblog")) { if (type == null || type.equals("metaweblog")) {
blogConnection = createBlogConnection( blogConnection = createBlogConnection(METAWEBLOG_IMPL_CLASS, url, username, password);
METAWEBLOG_IMPL_CLASS, url, username, password); } else if (type.equals("atom")) {
} else if (type.equals("atom")) { blogConnection = createBlogConnection(ATOMPROTOCOL_IMPL_CLASS, url, username, password);
blogConnection = createBlogConnection( } else {
ATOMPROTOCOL_IMPL_CLASS, url, username, password); throw new BlogClientException("Type must be 'atom' or 'metaweblog'");
} else { }
throw new BlogClientException("Type must be 'atom' or 'metaweblog'"); return blogConnection;
} }
return blogConnection;
}
private static BlogConnection createBlogConnection( private static BlogConnection createBlogConnection(final String className, final String url, final String username, final String password)
String className, String url, String username, String password) throws BlogClientException {
throws BlogClientException { Class conClass;
Class conClass; try {
try { conClass = Class.forName(className);
conClass = Class.forName(className); } catch (final ClassNotFoundException ex) {
} catch (ClassNotFoundException ex) { throw new BlogClientException("BlogConnection impl. class not found: " + className, ex);
throw new BlogClientException( }
"BlogConnection impl. class not found: "+className, ex); final Class[] args = new Class[] { String.class, String.class, String.class };
} Constructor ctor;
Class[] args = new Class[] {String.class, String.class, String.class}; try {
Constructor ctor; ctor = conClass.getConstructor(args);
try { return (BlogConnection) ctor.newInstance(new Object[] { url, username, password });
ctor = conClass.getConstructor(args); } catch (final Throwable t) {
return (BlogConnection) throw new BlogClientException("ERROR instantiating BlogConnection impl.", t);
ctor.newInstance(new Object[] {url, username, password}); }
} catch (Throwable t) { }
throw new BlogClientException(
"ERROR instantiating BlogConnection impl.", t);
}
}
} }

View file

@ -17,7 +17,6 @@ package org.rometools.propono.blogclient;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.io.InputStream;
/** /**
* Represents a single blog entry. * Represents a single blog entry.
@ -28,8 +27,7 @@ public interface BlogEntry {
public String getToken(); public String getToken();
/** /**
* Save this entry to it's collection. If this is a new entry and does not * Save this entry to it's collection. If this is a new entry and does not have a collection yet, then save() will save it to the primary collection.
* have a collection yet, then save() will save it to the primary collection.
*/ */
public void save() throws BlogClientException; public void save() throws BlogClientException;
@ -100,40 +98,45 @@ public interface BlogEntry {
String src = null; String src = null;
/** Construct content */ /** Construct content */
public Content() {} public Content() {
}
/** Construct content with value (and type="html") */ /** Construct content with value (and type="html") */
public Content(String value) { public Content(final String value) {
this.value = value; this.value = value;
} }
/** Get value of content if in-line */ /** Get value of content if in-line */
public String getValue() { public String getValue() {
return value; return value;
} }
/** Set value of content if in-line */ /** Set value of content if in-line */
public void setValue(String value) { public void setValue(final String value) {
this.value = value; this.value = value;
} }
/** /**
* Get type of content, either "text", "html", "xhtml" or a MIME content-type. * Get type of content, either "text", "html", "xhtml" or a MIME content-type. Defaults to HTML.
* Defaults to HTML.
*/ */
public String getType() { public String getType() {
return type; return type;
} }
/** /**
* Set type of content, either "text", "html", "xhtml" or a MIME content-type. * Set type of content, either "text", "html", "xhtml" or a MIME content-type. Defaults to HTML.
* Defaults to HTML.
*/ */
public void setType(String type) { public void setType(final String type) {
this.type = type; this.type = type;
} }
/** Get URI of content if out-of-line */ /** Get URI of content if out-of-line */
public String getSrc() { public String getSrc() {
return src; return src;
} }
/** Set URI of content if out-of-line */ /** Set URI of content if out-of-line */
public void setSrc(String src) { public void setSrc(final String src) {
this.src = src; this.src = src;
} }
} }
@ -143,31 +146,39 @@ public interface BlogEntry {
String name; String name;
String email; String email;
String url; String url;
/** Get person's email */ /** Get person's email */
public String getEmail() { public String getEmail() {
return email; return email;
} }
/** Set person's email */
public void setEmail(String email) { /** Set person's email */
public void setEmail(final String email) {
this.email = email; this.email = email;
} }
/** Get person's name */ /** Get person's name */
public String getName() { public String getName() {
return name; return name;
} }
/** Set person's name */ /** Set person's name */
public void setName(String name) { public void setName(final String name) {
this.name = name; this.name = name;
} }
/** Get person's URL */ /** Get person's URL */
public String getUrl() { public String getUrl() {
return url; return url;
} }
/** Set person's URL */ /** Set person's URL */
public void setUrl(String url) { public void setUrl(final String url) {
this.url = url; this.url = url;
} }
/** Returns person's name */ /** Returns person's name */
@Override
public String toString() { public String toString() {
return name; return name;
} }
@ -178,54 +189,70 @@ public interface BlogEntry {
String id; String id;
String name; String name;
String url; String url;
/** /**
* Create new Catetory * Create new Catetory
*/ */
public Category() {} public Category() {
}
/** /**
* Create new category with name. * Create new category with name.
*/ */
public Category(String id) { public Category(final String id) {
this.id = id; this.id = id;
this.name = id; name = id;
} }
/** /**
* Determines if categories are equal based on id. * Determines if categories are equal based on id.
*/ */
public boolean equals(Object obj) { @Override
Category other = (Category)obj; public boolean equals(final Object obj) {
if (obj == null) return false; final Category other = (Category) obj;
if (getId() != null && other.getId() != null if (obj == null) {
&& getId().equals(other.getId())) return true; return false;
}
if (getId() != null && other.getId() != null && getId().equals(other.getId())) {
return true;
}
return false; return false;
} }
/** Get category id */ /** Get category id */
public String getId() { public String getId() {
return id; return id;
} }
/** Set category id */ /** Set category id */
public void setId(String id) { public void setId(final String id) {
this.id = id; this.id = id;
} }
/** Get category display name */ /** Get category display name */
public String getName() { public String getName() {
return name; return name;
} }
/** Set category display name */ /** Set category display name */
public void setName(String name) { public void setName(final String name) {
this.name = name; this.name = name;
} }
/** Get URL of category domain */ /** Get URL of category domain */
public String getUrl() { public String getUrl() {
return url; return url;
} }
/** Set URL of category domain */ /** Set URL of category domain */
public void setUrl(String url) { public void setUrl(final String url) {
this.url = url; this.url = url;
} }
/** Return category's name or id for display */ /** Return category's name or id for display */
@Override
public String toString() { public String toString() {
return name!=null ? name : id; return name != null ? name : id;
} }
} }
} }

View file

@ -20,10 +20,8 @@ import java.io.InputStream;
/** /**
* Represents a file that has been uploaded to a blog. * Represents a file that has been uploaded to a blog.
* <p /> * <p />
* Resources are modeled as a type of BlogEntry, but be aware: not all servers * Resources are modeled as a type of BlogEntry, but be aware: not all servers can save resource metadata (i.e. title, category, author, etc.). MetaWeblog based
* can save resource metadata (i.e. title, category, author, etc.). MetaWeblog * servers can't save metadata at all and Atom protocol servers are not required to preserve uploaded file metadata.
* based servers can't save metadata at all and Atom protocol servers are not
* required to preserve uploaded file metadata.
*/ */
public interface BlogResource extends BlogEntry { public interface BlogResource extends BlogEntry {
@ -36,4 +34,3 @@ public interface BlogResource extends BlogEntry {
/** Update resource by immediately uploading new bytes to server */ /** Update resource by immediately uploading new bytes to server */
public void update(byte[] newBytes) throws BlogClientException; public void update(byte[] newBytes) throws BlogClientException;
} }

View file

@ -15,59 +15,56 @@
*/ */
package org.rometools.propono.blogclient.atomprotocol; package org.rometools.propono.blogclient.atomprotocol;
import org.rometools.propono.utils.ProponoException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.rometools.propono.blogclient.Blog;
import org.rometools.propono.blogclient.BlogClientException;
import org.rometools.propono.blogclient.BlogEntry;
import org.rometools.propono.blogclient.BlogResource;
import org.rometools.propono.atom.client.ClientAtomService; import org.rometools.propono.atom.client.ClientAtomService;
import org.rometools.propono.atom.client.ClientCollection; import org.rometools.propono.atom.client.ClientCollection;
import org.rometools.propono.atom.client.ClientEntry; import org.rometools.propono.atom.client.ClientEntry;
import org.rometools.propono.atom.client.ClientMediaEntry; import org.rometools.propono.atom.client.ClientMediaEntry;
import org.rometools.propono.atom.client.ClientWorkspace; import org.rometools.propono.atom.client.ClientWorkspace;
import java.util.Map; import org.rometools.propono.blogclient.Blog;
import java.util.TreeMap; import org.rometools.propono.blogclient.BlogClientException;
import org.rometools.propono.blogclient.BlogEntry;
import org.rometools.propono.blogclient.BlogResource;
import org.rometools.propono.utils.ProponoException;
/** /**
* Atom protocol implementation of the BlogClient Blog interface. * Atom protocol implementation of the BlogClient Blog interface.
*/ */
public class AtomBlog implements Blog { public class AtomBlog implements Blog {
static final Log logger = LogFactory.getLog(AtomBlog.class); static final Log logger = LogFactory.getLog(AtomBlog.class);
private HttpClient httpClient = null; private final HttpClient httpClient = null;
private String name = null; private String name = null;
private ClientAtomService service; private ClientAtomService service;
private ClientWorkspace workspace = null; private ClientWorkspace workspace = null;
private AtomCollection entriesCollection = null; private AtomCollection entriesCollection = null;
private AtomCollection resourcesCollection = null; private AtomCollection resourcesCollection = null;
private Map collections = new TreeMap(); private final Map collections = new TreeMap();
/** /**
* Create AtomBlog using specified HTTPClient, user account and workspace, * Create AtomBlog using specified HTTPClient, user account and workspace, called by AtomConnection. Fetches Atom Service document and creates an
* called by AtomConnection. Fetches Atom Service document and creates * AtomCollection object for each collection found. The first entry collection is considered the primary entry collection. And the first resource collection
* an AtomCollection object for each collection found. The first entry * is considered the primary resource collection.
* collection is considered the primary entry collection. And the first
* resource collection is considered the primary resource collection.
*/ */
AtomBlog(ClientAtomService service, ClientWorkspace workspace) { AtomBlog(final ClientAtomService service, final ClientWorkspace workspace) {
this.setService(service); setService(service);
this.setWorkspace(workspace); setWorkspace(workspace);
this.name = workspace.getTitle(); name = workspace.getTitle();
Iterator members = workspace.getCollections().iterator(); final Iterator members = workspace.getCollections().iterator();
while (members.hasNext()) { while (members.hasNext()) {
ClientCollection col = (ClientCollection) members.next(); final ClientCollection col = (ClientCollection) members.next();
if (col.accepts("entry") && entriesCollection == null) { if (col.accepts("entry") && entriesCollection == null) {
// first entry collection is primary entry collection // first entry collection is primary entry collection
entriesCollection = new AtomCollection(this, col); entriesCollection = new AtomCollection(this, col);
} } else if (!col.accepts("entry") && resourcesCollection == null) {
else if (!col.accepts("entry") && resourcesCollection == null) {
// first non-entry collection is primary resource collection // first non-entry collection is primary resource collection
resourcesCollection = new AtomCollection(this, col); resourcesCollection = new AtomCollection(this, col);
} }
@ -78,39 +75,52 @@ public class AtomBlog implements Blog {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public String getName() { return name; } @Override
public String getName() {
return name;
}
/** /**
* String display of blog, returns name. * String display of blog, returns name.
*/ */
public String toString() { return getName(); } @Override
public String toString() {
return getName();
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public String getToken() { return entriesCollection.getToken(); } @Override
public String getToken() {
return entriesCollection.getToken();
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public BlogEntry newEntry() throws BlogClientException { public BlogEntry newEntry() throws BlogClientException {
if (entriesCollection == null) throw new BlogClientException("No entry collection"); if (entriesCollection == null) {
throw new BlogClientException("No entry collection");
}
return entriesCollection.newEntry(); return entriesCollection.newEntry();
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public BlogEntry getEntry(String token) throws BlogClientException { @Override
public BlogEntry getEntry(final String token) throws BlogClientException {
ClientEntry clientEntry = null; ClientEntry clientEntry = null;
AtomEntry atomEntry = null; final AtomEntry atomEntry = null;
try { try {
clientEntry = getService().getEntry(token); clientEntry = getService().getEntry(token);
} catch (ProponoException ex) { } catch (final ProponoException ex) {
throw new BlogClientException("ERROR: fetching entry", ex); throw new BlogClientException("ERROR: fetching entry", ex);
} }
if (clientEntry != null && clientEntry instanceof ClientMediaEntry) { if (clientEntry != null && clientEntry instanceof ClientMediaEntry) {
return new AtomResource(this, (ClientMediaEntry)clientEntry); return new AtomResource(this, (ClientMediaEntry) clientEntry);
} else if (clientEntry != null && clientEntry instanceof ClientEntry) { } else if (clientEntry != null && clientEntry instanceof ClientEntry) {
return new AtomEntry(this, clientEntry); return new AtomEntry(this, clientEntry);
} else { } else {
@ -121,61 +131,76 @@ public class AtomBlog implements Blog {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public Iterator getEntries() throws BlogClientException { public Iterator getEntries() throws BlogClientException {
if (entriesCollection == null) throw new BlogClientException("No primary entry collection"); if (entriesCollection == null) {
throw new BlogClientException("No primary entry collection");
}
return new AtomEntryIterator(entriesCollection); return new AtomEntryIterator(entriesCollection);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public Iterator getResources() throws BlogClientException { public Iterator getResources() throws BlogClientException {
if (resourcesCollection == null) throw new BlogClientException("No primary entry collection"); if (resourcesCollection == null) {
throw new BlogClientException("No primary entry collection");
}
return new AtomEntryIterator(resourcesCollection); return new AtomEntryIterator(resourcesCollection);
} }
String saveEntry(BlogEntry entry) throws BlogClientException { String saveEntry(final BlogEntry entry) throws BlogClientException {
if (entriesCollection == null) throw new BlogClientException("No primary entry collection"); if (entriesCollection == null) {
throw new BlogClientException("No primary entry collection");
}
return entriesCollection.saveEntry(entry); return entriesCollection.saveEntry(entry);
} }
void deleteEntry(BlogEntry entry) throws BlogClientException { void deleteEntry(final BlogEntry entry) throws BlogClientException {
if (entriesCollection == null) throw new BlogClientException("No primary entry collection"); if (entriesCollection == null) {
throw new BlogClientException("No primary entry collection");
}
entriesCollection.deleteEntry(entry); entriesCollection.deleteEntry(entry);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public List getCategories() throws BlogClientException { public List getCategories() throws BlogClientException {
if (entriesCollection == null) throw new BlogClientException("No primary entry collection"); if (entriesCollection == null) {
throw new BlogClientException("No primary entry collection");
}
return entriesCollection.getCategories(); return entriesCollection.getCategories();
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public BlogResource newResource( @Override
String name, String contentType, byte[] bytes) throws BlogClientException { public BlogResource newResource(final String name, final String contentType, final byte[] bytes) throws BlogClientException {
if (resourcesCollection == null) { if (resourcesCollection == null) {
throw new BlogClientException("No resource collection"); throw new BlogClientException("No resource collection");
} }
return resourcesCollection.newResource(name, contentType, bytes); return resourcesCollection.newResource(name, contentType, bytes);
} }
String saveResource(final BlogResource res) throws BlogClientException {
String saveResource(BlogResource res) throws BlogClientException { if (resourcesCollection == null) {
if (resourcesCollection == null) throw new BlogClientException("No primary resource collection"); throw new BlogClientException("No primary resource collection");
}
return resourcesCollection.saveResource(res); return resourcesCollection.saveResource(res);
} }
void deleteResource(BlogResource resource) throws BlogClientException { void deleteResource(final BlogResource resource) throws BlogClientException {
deleteEntry((BlogEntry)resource); deleteEntry(resource);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public List getCollections() throws BlogClientException { public List getCollections() throws BlogClientException {
return new ArrayList(collections.values()); return new ArrayList(collections.values());
} }
@ -183,15 +208,16 @@ public class AtomBlog implements Blog {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public Blog.Collection getCollection(String token) throws BlogClientException { @Override
return (Blog.Collection)collections.get(token); public Blog.Collection getCollection(final String token) throws BlogClientException {
return (Blog.Collection) collections.get(token);
} }
ClientAtomService getService() { ClientAtomService getService() {
return service; return service;
} }
void setService(ClientAtomService service) { void setService(final ClientAtomService service) {
this.service = service; this.service = service;
} }
@ -199,7 +225,7 @@ public class AtomBlog implements Blog {
return workspace; return workspace;
} }
void setWorkspace(ClientWorkspace workspace) { void setWorkspace(final ClientWorkspace workspace) {
this.workspace = workspace; this.workspace = workspace;
} }

View file

@ -15,21 +15,23 @@
*/ */
package org.rometools.propono.blogclient.atomprotocol; package org.rometools.propono.blogclient.atomprotocol;
import com.sun.syndication.feed.atom.Category;
import org.rometools.propono.atom.client.ClientAtomService;
import org.rometools.propono.atom.common.Categories;
import org.rometools.propono.atom.client.ClientCollection;
import org.rometools.propono.atom.client.ClientEntry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.rometools.propono.atom.client.ClientAtomService;
import org.rometools.propono.atom.client.ClientCollection;
import org.rometools.propono.atom.client.ClientEntry;
import org.rometools.propono.atom.common.Categories;
import org.rometools.propono.blogclient.Blog; import org.rometools.propono.blogclient.Blog;
import org.rometools.propono.blogclient.BlogClientException; import org.rometools.propono.blogclient.BlogClientException;
import org.rometools.propono.blogclient.BlogEntry; import org.rometools.propono.blogclient.BlogEntry;
import org.rometools.propono.blogclient.BlogResource; import org.rometools.propono.blogclient.BlogResource;
import com.sun.syndication.feed.atom.Category;
/** /**
* Atom protocol implementation of BlogClient Blog.Collection. * Atom protocol implementation of BlogClient Blog.Collection.
*/ */
@ -41,15 +43,14 @@ public class AtomCollection implements Blog.Collection {
private ClientCollection clientCollection = null; private ClientCollection clientCollection = null;
AtomCollection(final AtomBlog blog, final ClientCollection col) {
AtomCollection(AtomBlog blog, ClientCollection col) {
this.blog = blog; this.blog = blog;
this.clientCollection = col; clientCollection = col;
for (Iterator catsIter = col.getCategories().iterator(); catsIter.hasNext();) { for (final Iterator catsIter = col.getCategories().iterator(); catsIter.hasNext();) {
Categories cats = (Categories)catsIter.next(); final Categories cats = (Categories) catsIter.next();
for (Iterator catIter = cats.getCategories().iterator(); catIter.hasNext();) { for (final Iterator catIter = cats.getCategories().iterator(); catIter.hasNext();) {
Category cat = (Category)catIter.next(); final Category cat = (Category) catIter.next();
BlogEntry.Category blogCat = new BlogEntry.Category(cat.getTerm()); final BlogEntry.Category blogCat = new BlogEntry.Category(cat.getTerm());
blogCat.setName(cat.getLabel()); blogCat.setName(cat.getLabel());
blogCat.setUrl(cat.getScheme()); blogCat.setUrl(cat.getScheme());
getCategories().add(blogCat); getCategories().add(blogCat);
@ -60,6 +61,7 @@ public class AtomCollection implements Blog.Collection {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String getTitle() { public String getTitle() {
return getClientCollection().getTitle(); return getClientCollection().getTitle();
} }
@ -67,6 +69,7 @@ public class AtomCollection implements Blog.Collection {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String getToken() { public String getToken() {
return getClientCollection().getHrefResolved(); return getClientCollection().getHrefResolved();
} }
@ -74,6 +77,7 @@ public class AtomCollection implements Blog.Collection {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public List getAccepts() { public List getAccepts() {
return getClientCollection().getAccepts(); return getClientCollection().getAccepts();
} }
@ -81,13 +85,15 @@ public class AtomCollection implements Blog.Collection {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public boolean accepts(String ct) { @Override
public boolean accepts(final String ct) {
return getClientCollection().accepts(ct); return getClientCollection().accepts(ct);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public Iterator getEntries() throws BlogClientException { public Iterator getEntries() throws BlogClientException {
return new AtomEntryIterator(this); return new AtomEntryIterator(this);
} }
@ -95,24 +101,27 @@ public class AtomCollection implements Blog.Collection {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public BlogEntry newEntry() throws BlogClientException { public BlogEntry newEntry() throws BlogClientException {
AtomBlog atomBlog = (AtomBlog)getBlog(); final AtomBlog atomBlog = (AtomBlog) getBlog();
BlogEntry entry = new AtomEntry(atomBlog, this); final BlogEntry entry = new AtomEntry(atomBlog, this);
return entry; return entry;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public BlogResource newResource(String name, String contentType, byte[] bytes) throws BlogClientException { @Override
public BlogResource newResource(final String name, final String contentType, final byte[] bytes) throws BlogClientException {
return new AtomResource(this, name, contentType, bytes); return new AtomResource(this, name, contentType, bytes);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public String saveResource(BlogResource res) throws BlogClientException { @Override
((AtomResource)res).setCollection(this); public String saveResource(final BlogResource res) throws BlogClientException {
((AtomResource) res).setCollection(this);
res.save(); res.save();
return res.getContent().getSrc(); return res.getContent().getSrc();
} }
@ -120,19 +129,20 @@ public class AtomCollection implements Blog.Collection {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public String saveEntry(BlogEntry entry) throws BlogClientException { @Override
((AtomEntry)entry).setCollection(this); public String saveEntry(final BlogEntry entry) throws BlogClientException {
((AtomEntry) entry).setCollection(this);
entry.save(); entry.save();
return entry.getPermalink(); return entry.getPermalink();
} }
void deleteEntry(BlogEntry entry) throws BlogClientException { void deleteEntry(final BlogEntry entry) throws BlogClientException {
try { try {
ClientAtomService service = ((AtomBlog)getBlog()).getService(); final ClientAtomService service = ((AtomBlog) getBlog()).getService();
ClientEntry clientEntry = service.getEntry(entry.getToken()); final ClientEntry clientEntry = service.getEntry(entry.getToken());
clientEntry.remove(); clientEntry.remove();
} catch (Exception e) { } catch (final Exception e) {
throw new BlogClientException("ERROR deleting entry", e); throw new BlogClientException("ERROR deleting entry", e);
} }
} }
@ -140,22 +150,24 @@ public class AtomCollection implements Blog.Collection {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public Blog getBlog() { public Blog getBlog() {
return blog; return blog;
} }
void setBlog(AtomBlog blog) { void setBlog(final AtomBlog blog) {
this.blog = blog; this.blog = blog;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public List getCategories() { public List getCategories() {
return categories; return categories;
} }
void setCategories(List categories) { void setCategories(final List categories) {
this.categories = categories; this.categories = categories;
} }

View file

@ -15,57 +15,53 @@
*/ */
package org.rometools.propono.blogclient.atomprotocol; package org.rometools.propono.blogclient.atomprotocol;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom2.Document;
import org.rometools.propono.atom.client.AtomClientFactory; import org.rometools.propono.atom.client.AtomClientFactory;
import org.rometools.propono.atom.client.BasicAuthStrategy; import org.rometools.propono.atom.client.BasicAuthStrategy;
import org.rometools.propono.atom.client.ClientAtomService; import org.rometools.propono.atom.client.ClientAtomService;
import org.rometools.propono.atom.client.ClientWorkspace; import org.rometools.propono.atom.client.ClientWorkspace;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom2.Document;
import org.rometools.propono.blogclient.BlogConnection;
import org.rometools.propono.blogclient.Blog; import org.rometools.propono.blogclient.Blog;
import org.rometools.propono.blogclient.BlogClientException; import org.rometools.propono.blogclient.BlogClientException;
import org.rometools.propono.blogclient.BlogConnection;
/** /**
* Atom protocol of BlogConnection. Connects to Atom server, creates AtomBlog * Atom protocol of BlogConnection. Connects to Atom server, creates AtomBlog object for each Atom workspace found and within each blog a collection for each
* object for each Atom workspace found and within each blog a collection for each
* Atom collection found. * Atom collection found.
*/ */
public class AtomConnection implements BlogConnection { public class AtomConnection implements BlogConnection {
private static Log logger = LogFactory.getLog(AtomConnection.class); private static Log logger = LogFactory.getLog(AtomConnection.class);
private HttpClient httpClient = null; private final HttpClient httpClient = null;
private Map blogs = new HashMap(); private final Map blogs = new HashMap();
/** /**
* Create Atom blog client instance for specified URL and user account. * Create Atom blog client instance for specified URL and user account.
* @param uri End-point URL of Atom service *
* @param uri End-point URL of Atom service
* @param username Username of account * @param username Username of account
* @param password Password of account * @param password Password of account
*/ */
public AtomConnection(String uri, String username, String password) public AtomConnection(final String uri, final String username, final String password) throws BlogClientException {
throws BlogClientException {
Document doc = null; final Document doc = null;
try { try {
ClientAtomService service = (ClientAtomService) final ClientAtomService service = AtomClientFactory.getAtomService(uri, new BasicAuthStrategy(username, password));
AtomClientFactory.getAtomService(uri, new BasicAuthStrategy(username, password)); final Iterator iter = service.getWorkspaces().iterator();
Iterator iter = service.getWorkspaces().iterator(); final int count = 0;
int count = 0;
while (iter.hasNext()) { while (iter.hasNext()) {
ClientWorkspace workspace = (ClientWorkspace)iter.next(); final ClientWorkspace workspace = (ClientWorkspace) iter.next();
Blog blog = new AtomBlog(service, workspace); final Blog blog = new AtomBlog(service, workspace);
blogs.put(blog.getToken(), blog); blogs.put(blog.getToken(), blog);
} }
} catch (Throwable t) { } catch (final Throwable t) {
throw new BlogClientException("Error connecting to blog server", t); throw new BlogClientException("Error connecting to blog server", t);
} }
} }
@ -73,6 +69,7 @@ public class AtomConnection implements BlogConnection {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public List getBlogs() { public List getBlogs() {
return new ArrayList(blogs.values()); return new ArrayList(blogs.values());
} }
@ -80,13 +77,15 @@ public class AtomConnection implements BlogConnection {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public Blog getBlog(String token) { @Override
return (AtomBlog)blogs.get(token); public Blog getBlog(final String token) {
return (AtomBlog) blogs.get(token);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void setAppkey(String appkey) { @Override
public void setAppkey(final String appkey) {
} }
} }

View file

@ -15,22 +15,23 @@
*/ */
package org.rometools.propono.blogclient.atomprotocol; package org.rometools.propono.blogclient.atomprotocol;
import org.rometools.propono.utils.ProponoException;
import org.rometools.propono.atom.common.rome.AppModule;
import org.rometools.propono.atom.common.rome.AppModuleImpl;
import org.rometools.propono.blogclient.BlogClientException;
import org.rometools.propono.blogclient.BlogEntry;
import org.rometools.propono.blogclient.BaseBlogEntry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.feed.atom.Link;
import org.rometools.propono.atom.client.ClientEntry;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.rometools.propono.blogclient.BlogEntry.Person; import org.rometools.propono.atom.client.ClientEntry;
import org.rometools.propono.atom.common.rome.AppModule;
import org.rometools.propono.atom.common.rome.AppModuleImpl;
import org.rometools.propono.blogclient.BaseBlogEntry;
import org.rometools.propono.blogclient.BlogClientException;
import org.rometools.propono.blogclient.BlogEntry;
import org.rometools.propono.utils.ProponoException;
import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.feed.atom.Link;
/** /**
* Atom protocol implementation of BlogEntry. * Atom protocol implementation of BlogEntry.
@ -41,26 +42,27 @@ public class AtomEntry extends BaseBlogEntry implements BlogEntry {
String editURI = null; String editURI = null;
AtomCollection collection = null; AtomCollection collection = null;
AtomEntry(AtomBlog blog, AtomCollection collection) throws BlogClientException { AtomEntry(final AtomBlog blog, final AtomCollection collection) throws BlogClientException {
super(blog); super(blog);
this.collection = collection; this.collection = collection;
} }
AtomEntry(AtomCollection collection, ClientEntry entry) throws BlogClientException { AtomEntry(final AtomCollection collection, final ClientEntry entry) throws BlogClientException {
this((AtomBlog)collection.getBlog(), collection); this((AtomBlog) collection.getBlog(), collection);
//clientEntry = entry; // clientEntry = entry;
copyFromRomeEntry(entry); copyFromRomeEntry(entry);
} }
AtomEntry(AtomBlog blog, ClientEntry entry) throws BlogClientException { AtomEntry(final AtomBlog blog, final ClientEntry entry) throws BlogClientException {
super(blog); super(blog);
//clientEntry = entry; // clientEntry = entry;
copyFromRomeEntry(entry); copyFromRomeEntry(entry);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String getToken() { public String getToken() {
return editURI; return editURI;
} }
@ -69,16 +71,17 @@ public class AtomEntry extends BaseBlogEntry implements BlogEntry {
return collection; return collection;
} }
void setCollection(AtomCollection collection) { void setCollection(final AtomCollection collection) {
this.collection = collection; this.collection = collection;
} }
/** /**
* True if entry's token's are equal. * True if entry's token's are equal.
*/ */
public boolean equals(Object o) { @Override
public boolean equals(final Object o) {
if (o instanceof AtomEntry) { if (o instanceof AtomEntry) {
AtomEntry other = (AtomEntry)o; final AtomEntry other = (AtomEntry) o;
if (other.getToken() != null && getToken() != null) { if (other.getToken() != null && getToken() != null) {
return other.getToken().equals(getToken()); return other.getToken().equals(getToken());
} }
@ -89,27 +92,28 @@ public class AtomEntry extends BaseBlogEntry implements BlogEntry {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void save() throws BlogClientException { public void save() throws BlogClientException {
boolean create = (getToken() == null); final boolean create = getToken() == null;
if (create && getCollection() == null) { if (create && getCollection() == null) {
throw new BlogClientException("Cannot save entry, no collection"); throw new BlogClientException("Cannot save entry, no collection");
} else if (create) { } else if (create) {
try { try {
ClientEntry clientEntry = collection.getClientCollection().createEntry(); final ClientEntry clientEntry = collection.getClientCollection().createEntry();
copyToRomeEntry(clientEntry); copyToRomeEntry(clientEntry);
collection.getClientCollection().addEntry(clientEntry); collection.getClientCollection().addEntry(clientEntry);
copyFromRomeEntry(clientEntry); copyFromRomeEntry(clientEntry);
} catch (ProponoException ex) { } catch (final ProponoException ex) {
throw new BlogClientException("Error saving entry", ex); throw new BlogClientException("Error saving entry", ex);
} }
} else { } else {
try { try {
ClientEntry clientEntry = ((AtomBlog)getBlog()).getService().getEntry(getToken()); final ClientEntry clientEntry = ((AtomBlog) getBlog()).getService().getEntry(getToken());
copyToRomeEntry(clientEntry); copyToRomeEntry(clientEntry);
clientEntry.update(); clientEntry.update();
copyFromRomeEntry(clientEntry); copyFromRomeEntry(clientEntry);
} catch (ProponoException ex) { } catch (final ProponoException ex) {
throw new BlogClientException("Error updating entry", ex); throw new BlogClientException("Error updating entry", ex);
} }
} }
} }
@ -117,36 +121,37 @@ public class AtomEntry extends BaseBlogEntry implements BlogEntry {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void delete() throws BlogClientException { public void delete() throws BlogClientException {
if (getToken() == null) { if (getToken() == null) {
throw new BlogClientException("Cannot delete unsaved entry"); throw new BlogClientException("Cannot delete unsaved entry");
} }
try { try {
ClientEntry clientEntry = ((AtomBlog)getBlog()).getService().getEntry(editURI); final ClientEntry clientEntry = ((AtomBlog) getBlog()).getService().getEntry(editURI);
clientEntry.remove(); clientEntry.remove();
} catch (ProponoException ex) { } catch (final ProponoException ex) {
throw new BlogClientException("Error removing entry", ex); throw new BlogClientException("Error removing entry", ex);
} }
} }
void copyFromRomeEntry(ClientEntry entry) { void copyFromRomeEntry(final ClientEntry entry) {
id = entry.getId(); id = entry.getId();
title = entry.getTitle(); title = entry.getTitle();
editURI = entry.getEditURI(); editURI = entry.getEditURI();
List altlinks = entry.getAlternateLinks(); final List altlinks = entry.getAlternateLinks();
if (altlinks != null) { if (altlinks != null) {
for (Iterator iter = altlinks.iterator(); iter.hasNext();) { for (final Iterator iter = altlinks.iterator(); iter.hasNext();) {
Link link = (Link)iter.next(); final Link link = (Link) iter.next();
if ("alternate".equals(link.getRel()) || link.getRel()==null) { if ("alternate".equals(link.getRel()) || link.getRel() == null) {
permalink = link.getHrefResolved(); permalink = link.getHrefResolved();
break; break;
} }
} }
} }
List contents = entry.getContents(); final List contents = entry.getContents();
com.sun.syndication.feed.atom.Content romeContent = null; com.sun.syndication.feed.atom.Content romeContent = null;
if (contents != null && contents.size() > 0) { if (contents != null && contents.size() > 0) {
romeContent = (com.sun.syndication.feed.atom.Content)contents.get(0); romeContent = (com.sun.syndication.feed.atom.Content) contents.get(0);
} }
if (romeContent != null) { if (romeContent != null) {
content = new BlogEntry.Content(romeContent.getValue()); content = new BlogEntry.Content(romeContent.getValue());
@ -154,12 +159,11 @@ public class AtomEntry extends BaseBlogEntry implements BlogEntry {
content.setSrc(romeContent.getSrc()); content.setSrc(romeContent.getSrc());
} }
if (entry.getCategories() != null) { if (entry.getCategories() != null) {
List cats = new ArrayList(); final List cats = new ArrayList();
List romeCats = entry.getCategories(); final List romeCats = entry.getCategories();
for (Iterator iter=romeCats.iterator(); iter.hasNext();) { for (final Iterator iter = romeCats.iterator(); iter.hasNext();) {
com.sun.syndication.feed.atom.Category romeCat = final com.sun.syndication.feed.atom.Category romeCat = (com.sun.syndication.feed.atom.Category) iter.next();
(com.sun.syndication.feed.atom.Category)iter.next(); final BlogEntry.Category cat = new BlogEntry.Category();
BlogEntry.Category cat = new BlogEntry.Category();
cat.setId(romeCat.getTerm()); cat.setId(romeCat.getTerm());
cat.setUrl(romeCat.getScheme()); cat.setUrl(romeCat.getScheme());
cat.setName(romeCat.getLabel()); cat.setName(romeCat.getLabel());
@ -167,10 +171,9 @@ public class AtomEntry extends BaseBlogEntry implements BlogEntry {
} }
categories = cats; categories = cats;
} }
List authors = entry.getAuthors(); final List authors = entry.getAuthors();
if (authors!=null && authors.size() > 0) { if (authors != null && authors.size() > 0) {
com.sun.syndication.feed.atom.Person romeAuthor = final com.sun.syndication.feed.atom.Person romeAuthor = (com.sun.syndication.feed.atom.Person) authors.get(0);
(com.sun.syndication.feed.atom.Person)authors.get(0);
if (romeAuthor != null) { if (romeAuthor != null) {
author = new Person(); author = new Person();
author.setName(romeAuthor.getName()); author.setName(romeAuthor.getName());
@ -181,43 +184,41 @@ public class AtomEntry extends BaseBlogEntry implements BlogEntry {
publicationDate = entry.getPublished(); publicationDate = entry.getPublished();
modificationDate = entry.getModified(); modificationDate = entry.getModified();
AppModule control = (AppModule)entry.getModule(AppModule.URI); final AppModule control = (AppModule) entry.getModule(AppModule.URI);
if (control != null && control.getDraft() != null) { if (control != null && control.getDraft() != null) {
draft = control.getDraft().booleanValue(); draft = control.getDraft().booleanValue();
} else { } else {
draft = false; draft = false;
} }
} }
Entry copyToRomeEntry(ClientEntry entry) {
Entry copyToRomeEntry(final ClientEntry entry) {
if (id != null) { if (id != null) {
entry.setId(id); entry.setId(id);
} }
entry.setTitle(title); entry.setTitle(title);
if (author != null) { if (author != null) {
com.sun.syndication.feed.atom.Person person = final com.sun.syndication.feed.atom.Person person = new com.sun.syndication.feed.atom.Person();
new com.sun.syndication.feed.atom.Person();
person.setName(author.getName()); person.setName(author.getName());
person.setEmail(author.getEmail()); person.setEmail(author.getEmail());
person.setUrl(author.getUrl()); person.setUrl(author.getUrl());
List authors = new ArrayList(); final List authors = new ArrayList();
authors.add(person); authors.add(person);
entry.setAuthors(authors); entry.setAuthors(authors);
} }
if (content != null) { if (content != null) {
com.sun.syndication.feed.atom.Content romeContent = final com.sun.syndication.feed.atom.Content romeContent = new com.sun.syndication.feed.atom.Content();
new com.sun.syndication.feed.atom.Content();
romeContent.setValue(content.getValue()); romeContent.setValue(content.getValue());
romeContent.setType(content.getType()); romeContent.setType(content.getType());
List contents = new ArrayList(); final List contents = new ArrayList();
contents.add(romeContent); contents.add(romeContent);
entry.setContents(contents); entry.setContents(contents);
} }
if (categories != null) { if (categories != null) {
List romeCats = new ArrayList(); final List romeCats = new ArrayList();
for (Iterator iter=categories.iterator(); iter.hasNext();) { for (final Iterator iter = categories.iterator(); iter.hasNext();) {
BlogEntry.Category cat = (BlogEntry.Category)iter.next(); final BlogEntry.Category cat = (BlogEntry.Category) iter.next();
com.sun.syndication.feed.atom.Category romeCategory = final com.sun.syndication.feed.atom.Category romeCategory = new com.sun.syndication.feed.atom.Category();
new com.sun.syndication.feed.atom.Category();
romeCategory.setTerm(cat.getId()); romeCategory.setTerm(cat.getId());
romeCategory.setScheme(cat.getUrl()); romeCategory.setScheme(cat.getUrl());
romeCategory.setLabel(cat.getName()); romeCategory.setLabel(cat.getName());
@ -225,11 +226,11 @@ public class AtomEntry extends BaseBlogEntry implements BlogEntry {
} }
entry.setCategories(romeCats); entry.setCategories(romeCats);
} }
entry.setPublished((publicationDate == null) ? new Date() : publicationDate); entry.setPublished(publicationDate == null ? new Date() : publicationDate);
entry.setModified((modificationDate == null) ? new Date() : modificationDate); entry.setModified(modificationDate == null ? new Date() : modificationDate);
List modules = new ArrayList(); final List modules = new ArrayList();
AppModule control = new AppModuleImpl(); final AppModule control = new AppModuleImpl();
control.setDraft(new Boolean(draft)); control.setDraft(new Boolean(draft));
modules.add(control); modules.add(control);
entry.setModules(modules); entry.setModules(modules);

View file

@ -15,11 +15,12 @@
*/ */
package org.rometools.propono.blogclient.atomprotocol; package org.rometools.propono.blogclient.atomprotocol;
import org.rometools.propono.atom.client.ClientEntry;
import org.rometools.propono.atom.client.ClientMediaEntry;
import java.util.Iterator; import java.util.Iterator;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.rometools.propono.atom.client.ClientEntry;
import org.rometools.propono.atom.client.ClientMediaEntry;
import org.rometools.propono.blogclient.BlogClientException; import org.rometools.propono.blogclient.BlogClientException;
/** /**
@ -30,11 +31,11 @@ public class AtomEntryIterator implements Iterator {
private Iterator iterator = null; private Iterator iterator = null;
private AtomCollection collection = null; private AtomCollection collection = null;
AtomEntryIterator(AtomCollection collection) throws BlogClientException { AtomEntryIterator(final AtomCollection collection) throws BlogClientException {
try { try {
this.collection = collection; this.collection = collection;
iterator = collection.getClientCollection().getEntries(); iterator = collection.getClientCollection().getEntries();
} catch (Exception e) { } catch (final Exception e) {
throw new BlogClientException("ERROR fetching collection", e); throw new BlogClientException("ERROR fetching collection", e);
} }
} }
@ -42,6 +43,7 @@ public class AtomEntryIterator implements Iterator {
/** /**
* True if more entries are available. * True if more entries are available.
*/ */
@Override
public boolean hasNext() { public boolean hasNext() {
return iterator.hasNext(); return iterator.hasNext();
} }
@ -49,15 +51,16 @@ public class AtomEntryIterator implements Iterator {
/** /**
* Get next entry. * Get next entry.
*/ */
@Override
public Object next() { public Object next() {
try { try {
ClientEntry entry = (ClientEntry)iterator.next(); final ClientEntry entry = (ClientEntry) iterator.next();
if (entry instanceof ClientMediaEntry) { if (entry instanceof ClientMediaEntry) {
return new AtomResource(collection, (ClientMediaEntry)entry); return new AtomResource(collection, (ClientMediaEntry) entry);
} else { } else {
return new AtomEntry(collection, entry); return new AtomEntry(collection, entry);
} }
} catch (Exception e) { } catch (final Exception e) {
logger.error("ERROR fetching entry", e); logger.error("ERROR fetching entry", e);
} }
return null; return null;
@ -66,6 +69,7 @@ public class AtomEntryIterator implements Iterator {
/** /**
* Remove is not supported. * Remove is not supported.
*/ */
@Override
public void remove() { public void remove() {
// optional method, not implemented // optional method, not implemented
} }

View file

@ -16,17 +16,18 @@
package org.rometools.propono.blogclient.atomprotocol; package org.rometools.propono.blogclient.atomprotocol;
import java.io.InputStream; import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import org.rometools.propono.blogclient.BlogClientException;
import org.rometools.propono.blogclient.BlogEntry;
import org.rometools.propono.blogclient.BlogResource;
import com.sun.syndication.feed.atom.Link;
import org.rometools.propono.atom.client.ClientAtomService; import org.rometools.propono.atom.client.ClientAtomService;
import org.rometools.propono.atom.client.ClientCollection; import org.rometools.propono.atom.client.ClientCollection;
import org.rometools.propono.atom.client.ClientEntry; import org.rometools.propono.atom.client.ClientEntry;
import org.rometools.propono.atom.client.ClientMediaEntry; import org.rometools.propono.atom.client.ClientMediaEntry;
import java.util.Iterator; import org.rometools.propono.blogclient.BlogClientException;
import java.util.List; import org.rometools.propono.blogclient.BlogEntry;
import org.rometools.propono.blogclient.BlogResource;
import com.sun.syndication.feed.atom.Link;
/** /**
* Atom protocol implementation of BlogResource. * Atom protocol implementation of BlogResource.
@ -35,28 +36,27 @@ public class AtomResource extends AtomEntry implements BlogResource {
private AtomCollection collection; private AtomCollection collection;
private byte[] bytes; private byte[] bytes;
AtomResource(AtomCollection collection, String name, String contentType, byte[] bytes) AtomResource(final AtomCollection collection, final String name, final String contentType, final byte[] bytes) throws BlogClientException {
throws BlogClientException { super((AtomBlog) collection.getBlog(), collection);
super((AtomBlog)collection.getBlog(), collection);
this.collection = collection; this.collection = collection;
this.bytes = bytes; this.bytes = bytes;
BlogEntry.Content rcontent = new BlogEntry.Content(); final BlogEntry.Content rcontent = new BlogEntry.Content();
rcontent.setType(contentType); rcontent.setType(contentType);
setContent(rcontent); setContent(rcontent);
} }
AtomResource(AtomCollection collection, ClientMediaEntry entry) AtomResource(final AtomCollection collection, final ClientMediaEntry entry) throws BlogClientException {
throws BlogClientException {
super(collection, entry); super(collection, entry);
} }
AtomResource(AtomBlog blog, ClientMediaEntry entry) throws BlogClientException { AtomResource(final AtomBlog blog, final ClientMediaEntry entry) throws BlogClientException {
super(blog, entry); super(blog, entry);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String getName() { public String getName() {
return getTitle(); return getTitle();
} }
@ -68,10 +68,11 @@ public class AtomResource extends AtomEntry implements BlogResource {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public InputStream getAsStream() throws BlogClientException { public InputStream getAsStream() throws BlogClientException {
try { try {
return null; //((ClientMediaEntry)clientEntry).getAsStream(); return null; // ((ClientMediaEntry)clientEntry).getAsStream();
} catch (Exception e) { } catch (final Exception e) {
throw new BlogClientException("Error creating entry", e); throw new BlogClientException("Error creating entry", e);
} }
} }
@ -79,26 +80,25 @@ public class AtomResource extends AtomEntry implements BlogResource {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void save() throws BlogClientException { public void save() throws BlogClientException {
try { try {
if (getToken() == null) { if (getToken() == null) {
ClientAtomService clientService = ((AtomBlog)getBlog()).getService(); final ClientAtomService clientService = ((AtomBlog) getBlog()).getService();
ClientCollection clientCollection = collection.getClientCollection(); final ClientCollection clientCollection = collection.getClientCollection();
ClientMediaEntry clientEntry = final ClientMediaEntry clientEntry = new ClientMediaEntry(clientService, clientCollection, getTitle(), "", getContent().getType(), getBytes());
new ClientMediaEntry(clientService, clientCollection, getTitle(),
"", getContent().getType(), getBytes());
copyToRomeEntry(clientEntry); copyToRomeEntry(clientEntry);
collection.getClientCollection().addEntry(clientEntry); collection.getClientCollection().addEntry(clientEntry);
this.editURI = clientEntry.getEditURI(); editURI = clientEntry.getEditURI();
} else { } else {
ClientAtomService clientService = ((AtomBlog)getBlog()).getService(); final ClientAtomService clientService = ((AtomBlog) getBlog()).getService();
ClientMediaEntry clientEntry = (ClientMediaEntry)clientService.getEntry(editURI); final ClientMediaEntry clientEntry = (ClientMediaEntry) clientService.getEntry(editURI);
clientEntry.update(); clientEntry.update();
} }
} catch (Exception e) { } catch (final Exception e) {
throw new BlogClientException("Error creating entry", e); throw new BlogClientException("Error creating entry", e);
} }
} }
@ -106,22 +106,24 @@ public class AtomResource extends AtomEntry implements BlogResource {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void update(byte[] newBytes) throws BlogClientException { @Override
public void update(final byte[] newBytes) throws BlogClientException {
try { try {
//((ClientMediaEntry)clientEntry).setBytes(newBytes); // ((ClientMediaEntry)clientEntry).setBytes(newBytes);
//clientEntry.update(); // clientEntry.update();
} catch (Exception e) { } catch (final Exception e) {
throw new BlogClientException("Error creating entry", e); throw new BlogClientException("Error creating entry", e);
} }
} }
void copyFromRomeEntry(ClientEntry entry) { @Override
void copyFromRomeEntry(final ClientEntry entry) {
super.copyFromRomeEntry(entry); super.copyFromRomeEntry(entry);
List links = entry.getOtherLinks(); final List links = entry.getOtherLinks();
if (links != null) { if (links != null) {
for (Iterator iter = links.iterator(); iter.hasNext();) { for (final Iterator iter = links.iterator(); iter.hasNext();) {
Link link = (Link)iter.next(); final Link link = (Link) iter.next();
if ("edit-media".equals(link.getRel())) { if ("edit-media".equals(link.getRel())) {
id = link.getHrefResolved(); id = link.getHrefResolved();
break; break;
@ -129,6 +131,5 @@ public class AtomResource extends AtomEntry implements BlogResource {
} }
} }
} }
} }

View file

@ -17,53 +17,63 @@ package org.rometools.propono.blogclient.metaweblog;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Iterator;
import org.rometools.propono.blogclient.BlogEntry;
import org.rometools.propono.blogclient.Blog;
import org.rometools.propono.blogclient.BlogClientException;
import org.rometools.propono.blogclient.BlogResource;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
import org.apache.xmlrpc.client.XmlRpcClient; import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl; import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
import org.rometools.propono.blogclient.Blog;
import org.rometools.propono.blogclient.BlogClientException;
import org.rometools.propono.blogclient.BlogEntry;
import org.rometools.propono.blogclient.BlogResource;
/** /**
* Blog implementation that uses a mix of Blogger and MetaWeblog API methods. * Blog implementation that uses a mix of Blogger and MetaWeblog API methods.
*/ */
public class MetaWeblogBlog implements Blog { public class MetaWeblogBlog implements Blog {
private String blogid; private final String blogid;
private String name; private final String name;
private URL url; private final URL url;
private String userName; private final String userName;
private String password; private final String password;
private String appkey = "dummy"; private String appkey = "dummy";
private Map collections; private final Map collections;
private XmlRpcClient xmlRpcClient = null; private XmlRpcClient xmlRpcClient = null;
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public String getName() { return name; } @Override
public String getName() {
return name;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public String getToken() { return blogid; } @Override
public String getToken() {
return blogid;
}
/** /**
* String representation of blog, returns the name. * String representation of blog, returns the name.
*/ */
public String toString() { return getName(); } @Override
public String toString() {
return getName();
}
private XmlRpcClient getXmlRpcClient() { private XmlRpcClient getXmlRpcClient() {
if (xmlRpcClient == null) { if (xmlRpcClient == null) {
XmlRpcClientConfigImpl xmlrpcConfig = new XmlRpcClientConfigImpl(); final XmlRpcClientConfigImpl xmlrpcConfig = new XmlRpcClientConfigImpl();
xmlrpcConfig.setServerURL(url); xmlrpcConfig.setServerURL(url);
xmlRpcClient = new XmlRpcClient(); xmlRpcClient = new XmlRpcClient();
xmlRpcClient.setConfig(xmlrpcConfig); xmlRpcClient.setConfig(xmlrpcConfig);
@ -71,22 +81,18 @@ public class MetaWeblogBlog implements Blog {
return xmlRpcClient; return xmlRpcClient;
} }
MetaWeblogBlog(String blogid, String name, MetaWeblogBlog(final String blogid, final String name, final URL url, final String userName, final String password) {
URL url, String userName, String password) {
this.blogid = blogid; this.blogid = blogid;
this.name = name; this.name = name;
this.url = url; this.url = url;
this.userName = userName; this.userName = userName;
this.password = password; this.password = password;
this.collections = new TreeMap(); collections = new TreeMap();
collections.put("entries", collections.put("entries", new MetaWeblogBlogCollection(this, "entries", "Entries", "entry"));
new MetaWeblogBlogCollection(this, "entries", "Entries", "entry")); collections.put("resources", new MetaWeblogBlogCollection(this, "resources", "Resources", "*"));
collections.put("resources",
new MetaWeblogBlogCollection(this, "resources", "Resources", "*"));
} }
MetaWeblogBlog(String blogId, String name, MetaWeblogBlog(final String blogId, final String name, final URL url, final String userName, final String password, final String appkey) {
URL url, String userName, String password, String appkey) {
this(blogId, name, url, userName, password); this(blogId, name, url, userName, password);
this.appkey = appkey; this.appkey = appkey;
} }
@ -94,33 +100,33 @@ public class MetaWeblogBlog implements Blog {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public BlogEntry newEntry() { public BlogEntry newEntry() {
return new MetaWeblogEntry(this, new HashMap()); return new MetaWeblogEntry(this, new HashMap());
} }
String saveEntry(BlogEntry entry) throws BlogClientException { String saveEntry(final BlogEntry entry) throws BlogClientException {
Blog.Collection col = (Blog.Collection)collections.get("entries"); final Blog.Collection col = (Blog.Collection) collections.get("entries");
return col.saveEntry(entry); return col.saveEntry(entry);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public BlogEntry getEntry(String id) throws BlogClientException { @Override
public BlogEntry getEntry(final String id) throws BlogClientException {
try { try {
Map result = (Map) final Map result = (Map) getXmlRpcClient().execute("metaWeblog.getPost", new Object[] { id, userName, password });
getXmlRpcClient().execute("metaWeblog.getPost", new Object[] {id, userName, password});
return new MetaWeblogEntry(this, result); return new MetaWeblogEntry(this, result);
} catch (Exception e) { } catch (final Exception e) {
throw new BlogClientException("ERROR: XML-RPC error getting entry", e); throw new BlogClientException("ERROR: XML-RPC error getting entry", e);
} }
} }
void deleteEntry(String id) throws BlogClientException { void deleteEntry(final String id) throws BlogClientException {
try { try {
getXmlRpcClient().execute("blogger.deletePost", getXmlRpcClient().execute("blogger.deletePost", new Object[] { appkey, id, userName, password, Boolean.FALSE });
new Object[] {appkey, id, userName, password, Boolean.FALSE}); } catch (final Exception e) {
} catch (Exception e) {
throw new BlogClientException("ERROR: XML-RPC error getting entry", e); throw new BlogClientException("ERROR: XML-RPC error getting entry", e);
} }
} }
@ -128,6 +134,7 @@ public class MetaWeblogBlog implements Blog {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public Iterator getEntries() throws BlogClientException { public Iterator getEntries() throws BlogClientException {
return new EntryIterator(); return new EntryIterator();
} }
@ -135,78 +142,80 @@ public class MetaWeblogBlog implements Blog {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public BlogResource newResource(String name, String contentType, byte[] bytes) throws BlogClientException { @Override
public BlogResource newResource(final String name, final String contentType, final byte[] bytes) throws BlogClientException {
return new MetaWeblogResource(this, name, contentType, bytes); return new MetaWeblogResource(this, name, contentType, bytes);
} }
String saveResource(MetaWeblogResource resource) throws BlogClientException { String saveResource(final MetaWeblogResource resource) throws BlogClientException {
Blog.Collection col = (Blog.Collection)collections.get("resources"); final Blog.Collection col = (Blog.Collection) collections.get("resources");
return col.saveResource(resource); return col.saveResource(resource);
} }
BlogResource getResource(String token) throws BlogClientException { BlogResource getResource(final String token) throws BlogClientException {
return null; return null;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public Iterator getResources() throws BlogClientException { public Iterator getResources() throws BlogClientException {
return new NoOpIterator(); return new NoOpIterator();
} }
void deleteResource(BlogResource resource) throws BlogClientException { void deleteResource(final BlogResource resource) throws BlogClientException {
// no-op // no-op
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public List getCategories() throws BlogClientException { public List getCategories() throws BlogClientException {
ArrayList ret = new ArrayList(); final ArrayList ret = new ArrayList();
try { try {
Object result = final Object result = getXmlRpcClient().execute("metaWeblog.getCategories", new Object[] { blogid, userName, password });
getXmlRpcClient().execute ("metaWeblog.getCategories",
new Object[] {blogid, userName, password});
if (result != null && result instanceof HashMap) { if (result != null && result instanceof HashMap) {
// Standard MetaWeblog API style: struct of struts // Standard MetaWeblog API style: struct of struts
Map catsmap = (Map)result; final Map catsmap = (Map) result;
Iterator keys = catsmap.keySet().iterator(); final Iterator keys = catsmap.keySet().iterator();
while (keys.hasNext()) { while (keys.hasNext()) {
String key = (String)keys.next(); final String key = (String) keys.next();
Map catmap = (Map)catsmap.get(key); final Map catmap = (Map) catsmap.get(key);
BlogEntry.Category category = new BlogEntry.Category(key); final BlogEntry.Category category = new BlogEntry.Category(key);
category.setName((String)catmap.get("description")); category.setName((String) catmap.get("description"));
// catmap.get("htmlUrl"); // catmap.get("htmlUrl");
// catmap.get("rssUrl"); // catmap.get("rssUrl");
ret.add(category); ret.add(category);
} }
} else if (result != null && result instanceof Object[]) { } else if (result != null && result instanceof Object[]) {
// Wordpress style: array of structs // Wordpress style: array of structs
Object[] resultArray = (Object[])result; final Object[] resultArray = (Object[]) result;
for (int i=0; i<resultArray.length; i++) { for (final Object element : resultArray) {
Map catmap = (Map)resultArray[i]; final Map catmap = (Map) element;
String categoryId = (String)catmap.get("categoryId"); final String categoryId = (String) catmap.get("categoryId");
String categoryName = (String)catmap.get("categoryName"); final String categoryName = (String) catmap.get("categoryName");
BlogEntry.Category category = new BlogEntry.Category(categoryId); final BlogEntry.Category category = new BlogEntry.Category(categoryId);
category.setName(categoryName); category.setName(categoryName);
ret.add(category); ret.add(category);
} }
} }
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
return ret; return ret;
} }
private HashMap createPostStructure(BlogEntry entry) { private HashMap createPostStructure(final BlogEntry entry) {
return ((MetaWeblogEntry)entry).toPostStructure(); return ((MetaWeblogEntry) entry).toPostStructure();
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public List getCollections() throws BlogClientException { public List getCollections() throws BlogClientException {
return new ArrayList(collections.values()); return new ArrayList(collections.values());
} }
@ -214,11 +223,12 @@ public class MetaWeblogBlog implements Blog {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public Blog.Collection getCollection(String token) throws BlogClientException { @Override
return (Blog.Collection)collections.get(token); public Blog.Collection getCollection(final String token) throws BlogClientException {
return (Blog.Collection) collections.get(token);
} }
//------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** MetaWeblog API impplementation of Blog.Collection */ /** MetaWeblog API impplementation of Blog.Collection */
public class MetaWeblogBlogCollection implements Blog.Collection { public class MetaWeblogBlogCollection implements Blog.Collection {
@ -228,11 +238,11 @@ public class MetaWeblogBlog implements Blog {
private Blog blog = null; private Blog blog = null;
/** /**
* @param token Identifier for collection, unique within blog * @param token Identifier for collection, unique within blog
* @param title Title of collection * @param title Title of collection
* @param accept Content types accepted, either "entry" or "*" * @param accept Content types accepted, either "entry" or "*"
*/ */
public MetaWeblogBlogCollection(Blog blog, String token, String title, String accept) { public MetaWeblogBlogCollection(final Blog blog, final String token, final String title, final String accept) {
this.blog = blog; this.blog = blog;
this.accept = accept; this.accept = accept;
this.title = title; this.title = title;
@ -242,6 +252,7 @@ public class MetaWeblogBlog implements Blog {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String getTitle() { public String getTitle() {
return title; return title;
} }
@ -249,6 +260,7 @@ public class MetaWeblogBlog implements Blog {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String getToken() { public String getToken() {
return token; return token;
} }
@ -256,6 +268,7 @@ public class MetaWeblogBlog implements Blog {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public List getAccepts() { public List getAccepts() {
return Collections.singletonList(accept); return Collections.singletonList(accept);
} }
@ -263,13 +276,15 @@ public class MetaWeblogBlog implements Blog {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public BlogResource newResource(String name, String contentType, byte[] bytes) throws BlogClientException { @Override
public BlogResource newResource(final String name, final String contentType, final byte[] bytes) throws BlogClientException {
return blog.newResource(name, contentType, bytes); return blog.newResource(name, contentType, bytes);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public BlogEntry newEntry() throws BlogClientException { public BlogEntry newEntry() throws BlogClientException {
return blog.newEntry(); return blog.newEntry();
} }
@ -277,7 +292,8 @@ public class MetaWeblogBlog implements Blog {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public boolean accepts(String ct) { @Override
public boolean accepts(final String ct) {
if (accept.equals("*")) { if (accept.equals("*")) {
// everything accepted // everything accepted
return true; return true;
@ -291,12 +307,13 @@ public class MetaWeblogBlog implements Blog {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public Iterator getEntries() throws BlogClientException { public Iterator getEntries() throws BlogClientException {
Iterator ret = null; Iterator ret = null;
if (accept.equals("entry")) { if (accept.equals("entry")) {
ret = MetaWeblogBlog.this.getEntries(); ret = MetaWeblogBlog.this.getEntries();
} else { } else {
ret = MetaWeblogBlog.this.getResources(); ret = getResources();
} }
return ret; return ret;
} }
@ -304,20 +321,21 @@ public class MetaWeblogBlog implements Blog {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public String saveEntry(BlogEntry entry) throws BlogClientException { @Override
public String saveEntry(final BlogEntry entry) throws BlogClientException {
String ret = entry.getId(); String ret = entry.getId();
if (entry.getId() == null) { if (entry.getId() == null) {
try { try {
ret = (String)getXmlRpcClient().execute("metaWeblog.newPost", ret = (String) getXmlRpcClient().execute("metaWeblog.newPost",
new Object[] {blogid, userName, password, createPostStructure(entry), new Boolean(!entry.getDraft()) }); new Object[] { blogid, userName, password, createPostStructure(entry), new Boolean(!entry.getDraft()) });
} catch (Exception e) { } catch (final Exception e) {
throw new BlogClientException("ERROR: XML-RPC error saving new entry", e); throw new BlogClientException("ERROR: XML-RPC error saving new entry", e);
} }
} else { } else {
try { try {
getXmlRpcClient().execute("metaWeblog.editPost", getXmlRpcClient().execute("metaWeblog.editPost",
new Object[] {entry.getId(),userName,password,createPostStructure(entry),new Boolean(!entry.getDraft())}); new Object[] { entry.getId(), userName, password, createPostStructure(entry), new Boolean(!entry.getDraft()) });
} catch (Exception e) { } catch (final Exception e) {
throw new BlogClientException("ERROR: XML-RPC error updating entry", e); throw new BlogClientException("ERROR: XML-RPC error updating entry", e);
} }
} }
@ -327,20 +345,19 @@ public class MetaWeblogBlog implements Blog {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public String saveResource(BlogResource res) throws BlogClientException { @Override
MetaWeblogResource resource = (MetaWeblogResource)res; public String saveResource(final BlogResource res) throws BlogClientException {
final MetaWeblogResource resource = (MetaWeblogResource) res;
try { try {
HashMap resmap = new HashMap(); final HashMap resmap = new HashMap();
resmap.put("name", resource.getName()); resmap.put("name", resource.getName());
resmap.put("type", resource.getContent().getType()); resmap.put("type", resource.getContent().getType());
resmap.put("bits", resource.getBytes()); resmap.put("bits", resource.getBytes());
Map result = (Map) final Map result = (Map) getXmlRpcClient().execute("metaWeblog.newMediaObject", new Object[] { blogid, userName, password, resmap });
getXmlRpcClient().execute("metaWeblog.newMediaObject", final String url = (String) result.get("url");
new Object[] {blogid, userName, password, resmap});
String url = (String)result.get("url");
res.getContent().setSrc(url); res.getContent().setSrc(url);
return url; return url;
} catch (Exception e) { } catch (final Exception e) {
throw new BlogClientException("ERROR: loading or uploading file", e); throw new BlogClientException("ERROR: loading or uploading file", e);
} }
} }
@ -348,6 +365,7 @@ public class MetaWeblogBlog implements Blog {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public List getCategories() throws BlogClientException { public List getCategories() throws BlogClientException {
return MetaWeblogBlog.this.getCategories(); return MetaWeblogBlog.this.getCategories();
} }
@ -355,12 +373,13 @@ public class MetaWeblogBlog implements Blog {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public Blog getBlog() { public Blog getBlog() {
return blog; return blog;
} }
} }
//------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** /**
* Iterates over MetaWeblog API entries. * Iterates over MetaWeblog API entries.
*/ */
@ -369,48 +388,60 @@ public class MetaWeblogBlog implements Blog {
private boolean eod = false; private boolean eod = false;
private static final int BUFSIZE = 30; private static final int BUFSIZE = 30;
private List results = null; private List results = null;
/** /**
* Iterator for looping over MetaWeblog API entries. * Iterator for looping over MetaWeblog API entries.
*/ */
public EntryIterator() throws BlogClientException { public EntryIterator() throws BlogClientException {
getNextEntries(); getNextEntries();
} }
/** /**
* Returns true if more entries are avialable. * Returns true if more entries are avialable.
*/ */
@Override
public boolean hasNext() { public boolean hasNext() {
if (pos == results.size() && !eod) { if (pos == results.size() && !eod) {
try { getNextEntries(); } catch (Exception ignored) {} try {
getNextEntries();
} catch (final Exception ignored) {
}
} }
return (pos < results.size()); return pos < results.size();
} }
/** /**
* Get next entry. * Get next entry.
*/ */
@Override
public Object next() { public Object next() {
Map entryHash = (Map)results.get(pos++); final Map entryHash = (Map) results.get(pos++);
return new MetaWeblogEntry(MetaWeblogBlog.this, entryHash); return new MetaWeblogEntry(MetaWeblogBlog.this, entryHash);
} }
/** /**
* Remove is not implemented. * Remove is not implemented.
*/ */
@Override
public void remove() { public void remove() {
} }
private void getNextEntries() throws BlogClientException { private void getNextEntries() throws BlogClientException {
int requestSize = pos + BUFSIZE; final int requestSize = pos + BUFSIZE;
try { try {
Object[] resultsArray = (Object[]) final Object[] resultsArray = (Object[]) getXmlRpcClient().execute("metaWeblog.getRecentPosts",
getXmlRpcClient().execute("metaWeblog.getRecentPosts", new Object[] { blogid, userName, password, new Integer(requestSize) });
new Object[] {blogid, userName, password, new Integer(requestSize)} );
results = Arrays.asList(resultsArray); results = Arrays.asList(resultsArray);
} catch (Exception e) { } catch (final Exception e) {
throw new BlogClientException("ERROR: XML-RPC error getting entry", e); throw new BlogClientException("ERROR: XML-RPC error getting entry", e);
} }
if (results.size() < requestSize) eod = true; if (results.size() < requestSize) {
eod = true;
}
} }
} }
//------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** /**
* No-op iterator. * No-op iterator.
*/ */
@ -418,19 +449,25 @@ public class MetaWeblogBlog implements Blog {
/** /**
* No-op * No-op
*/ */
@Override
public boolean hasNext() { public boolean hasNext() {
return false; return false;
} }
/** /**
* No-op * No-op
*/ */
@Override
public Object next() { public Object next() {
return null; return null;
} }
/** /**
* No-op * No-op
*/ */
public void remove() {} @Override
public void remove() {
}
} }
} }

View file

@ -15,21 +15,19 @@
*/ */
package org.rometools.propono.blogclient.metaweblog; package org.rometools.propono.blogclient.metaweblog;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.io.IOException; import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.rometools.propono.blogclient.BlogConnection;
import org.rometools.propono.blogclient.Blog;
import org.rometools.propono.blogclient.BlogClientException;
import org.apache.xmlrpc.XmlRpcException; import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient; import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl; import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
import org.rometools.propono.blogclient.Blog;
import org.rometools.propono.blogclient.BlogClientException;
import org.rometools.propono.blogclient.BlogConnection;
/** /**
* BlogClient implementation that uses a mix of Blogger and MetaWeblog API methods. * BlogClient implementation that uses a mix of Blogger and MetaWeblog API methods.
@ -43,21 +41,20 @@ public class MetaWeblogConnection implements BlogConnection {
private XmlRpcClient xmlRpcClient = null; private XmlRpcClient xmlRpcClient = null;
public MetaWeblogConnection(String url, String userName, String password) public MetaWeblogConnection(final String url, final String userName, final String password) throws BlogClientException {
throws BlogClientException {
this.userName = userName; this.userName = userName;
this.password = password; this.password = password;
try { try {
this.url = new URL(url); this.url = new URL(url);
blogs = createBlogMap(); blogs = createBlogMap();
} catch (Throwable t) { } catch (final Throwable t) {
throw new BlogClientException("ERROR connecting to server", t); throw new BlogClientException("ERROR connecting to server", t);
} }
} }
private XmlRpcClient getXmlRpcClient() { private XmlRpcClient getXmlRpcClient() {
if (xmlRpcClient == null) { if (xmlRpcClient == null) {
XmlRpcClientConfigImpl xmlrpcConfig = new XmlRpcClientConfigImpl(); final XmlRpcClientConfigImpl xmlrpcConfig = new XmlRpcClientConfigImpl();
xmlrpcConfig.setServerURL(url); xmlrpcConfig.setServerURL(url);
xmlRpcClient = new XmlRpcClient(); xmlRpcClient = new XmlRpcClient();
xmlRpcClient.setConfig(xmlrpcConfig); xmlRpcClient.setConfig(xmlrpcConfig);
@ -68,6 +65,7 @@ public class MetaWeblogConnection implements BlogConnection {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public List getBlogs() { public List getBlogs() {
return new ArrayList(blogs.values()); return new ArrayList(blogs.values());
} }
@ -76,30 +74,30 @@ public class MetaWeblogConnection implements BlogConnection {
* {@inheritDoc} * {@inheritDoc}
*/ */
private Map createBlogMap() throws XmlRpcException, IOException { private Map createBlogMap() throws XmlRpcException, IOException {
Map blogMap = new HashMap(); final Map blogMap = new HashMap();
Object[] results = (Object[])getXmlRpcClient().execute("blogger.getUsersBlogs", final Object[] results = (Object[]) getXmlRpcClient().execute("blogger.getUsersBlogs", new Object[] { appkey, userName, password });
new Object[] {appkey, userName, password}); for (final Object result : results) {
for (int i = 0; i < results.length; i++) { final Map blog = (Map) result;
Map blog = (Map)results[i]; final String blogid = (String) blog.get("blogid");
String blogid = (String)blog.get("blogid"); final String name = (String) blog.get("blogName");
String name = (String)blog.get("blogName");
blogMap.put(blogid, new MetaWeblogBlog(blogid, name, url, userName, password)); blogMap.put(blogid, new MetaWeblogBlog(blogid, name, url, userName, password));
} }
return blogMap; return blogMap;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public Blog getBlog(String token) { @Override
return (Blog)blogs.get(token); public Blog getBlog(final String token) {
return (Blog) blogs.get(token);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void setAppkey(String appkey) { @Override
public void setAppkey(final String appkey) {
this.appkey = appkey; this.appkey = appkey;
} }
} }

View file

@ -19,22 +19,22 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import org.rometools.propono.blogclient.BlogClientException;
import org.rometools.propono.blogclient.BaseBlogEntry;
import org.rometools.propono.blogclient.BlogEntry;
import java.util.Map; import java.util.Map;
import org.rometools.propono.blogclient.BaseBlogEntry;
import org.rometools.propono.blogclient.BlogClientException;
import org.rometools.propono.blogclient.BlogEntry;
/** /**
* MetaWeblog API implementation of an entry. * MetaWeblog API implementation of an entry.
*/ */
public class MetaWeblogEntry extends BaseBlogEntry { public class MetaWeblogEntry extends BaseBlogEntry {
MetaWeblogEntry(MetaWeblogBlog blog, Map entryMap) { MetaWeblogEntry(final MetaWeblogBlog blog, final Map entryMap) {
super(blog); super(blog);
id = (String)entryMap.get("postid"); id = (String) entryMap.get("postid");
content = new Content((String)entryMap.get("description")); content = new Content((String) entryMap.get("description"));
// let's pretend MetaWeblog API has a content-type // let's pretend MetaWeblog API has a content-type
content.setType("application/metaweblog+xml"); content.setType("application/metaweblog+xml");
@ -42,19 +42,19 @@ public class MetaWeblogEntry extends BaseBlogEntry {
// no way to tell if entry is draft or not // no way to tell if entry is draft or not
draft = false; draft = false;
title = (String)entryMap.get("title"); title = (String) entryMap.get("title");
publicationDate = (Date)entryMap.get("dateCreated"); publicationDate = (Date) entryMap.get("dateCreated");
permalink = (String)entryMap.get("permaLink"); permalink = (String) entryMap.get("permaLink");
// AlexisMP: fix to get the author value populated. // AlexisMP: fix to get the author value populated.
author.setName( (String)entryMap.get("userid") ); author.setName((String) entryMap.get("userid"));
author.setEmail( (String)entryMap.get("author") ); author.setEmail((String) entryMap.get("author"));
categories = new ArrayList(); categories = new ArrayList();
Object[] catArray = (Object[])entryMap.get("categories"); final Object[] catArray = (Object[]) entryMap.get("categories");
if (catArray != null) { if (catArray != null) {
for (int i=0; i<catArray.length; i++) { for (final Object element : catArray) {
Category cat = new Category((String)catArray[i]); final Category cat = new Category((String) element);
categories.add(cat); categories.add(cat);
} }
} }
@ -63,6 +63,7 @@ public class MetaWeblogEntry extends BaseBlogEntry {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String getToken() { public String getToken() {
return id; return id;
} }
@ -70,9 +71,10 @@ public class MetaWeblogEntry extends BaseBlogEntry {
/** /**
* True if tokens are equal * True if tokens are equal
*/ */
public boolean equals(Object o) { @Override
public boolean equals(final Object o) {
if (o instanceof MetaWeblogEntry) { if (o instanceof MetaWeblogEntry) {
MetaWeblogEntry other = (MetaWeblogEntry)o; final MetaWeblogEntry other = (MetaWeblogEntry) o;
if (other.id != null && id != null) { if (other.id != null && id != null) {
return other.id.equals(id); return other.id.equals(id);
} }
@ -83,19 +85,21 @@ public class MetaWeblogEntry extends BaseBlogEntry {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void save() throws BlogClientException { public void save() throws BlogClientException {
id = ((MetaWeblogBlog)getBlog()).saveEntry(this); id = ((MetaWeblogBlog) getBlog()).saveEntry(this);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void delete() throws BlogClientException { public void delete() throws BlogClientException {
((MetaWeblogBlog)getBlog()).deleteEntry(id); ((MetaWeblogBlog) getBlog()).deleteEntry(id);
} }
HashMap toPostStructure() { HashMap toPostStructure() {
HashMap struct = new HashMap(); final HashMap struct = new HashMap();
if (getTitle() != null) { if (getTitle() != null) {
struct.put("title", getTitle()); struct.put("title", getTitle());
} }
@ -103,10 +107,10 @@ public class MetaWeblogEntry extends BaseBlogEntry {
struct.put("description", getContent().getValue()); struct.put("description", getContent().getValue());
} }
if (getCategories() != null && getCategories().size() > 0) { if (getCategories() != null && getCategories().size() > 0) {
List catArray = new ArrayList(); final List catArray = new ArrayList();
List cats = getCategories(); final List cats = getCategories();
for (int i=0; i<cats.size(); i++) { for (int i = 0; i < cats.size(); i++) {
BlogEntry.Category cat = (BlogEntry.Category)cats.get(i); final BlogEntry.Category cat = (BlogEntry.Category) cats.get(i);
catArray.add(cat.getName()); catArray.add(cat.getName());
} }
struct.put("categories", catArray); struct.put("categories", catArray);

View file

@ -15,36 +15,37 @@
*/ */
package org.rometools.propono.blogclient.metaweblog; package org.rometools.propono.blogclient.metaweblog;
import org.rometools.propono.blogclient.BlogClientException;
import java.io.InputStream; import java.io.InputStream;
import java.util.HashMap;
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.GetMethod;
import org.rometools.propono.blogclient.BlogClientException;
import org.rometools.propono.blogclient.BlogResource; import org.rometools.propono.blogclient.BlogResource;
import java.util.HashMap;
/** /**
* MetaWeblog API implementation of an resource entry. * MetaWeblog API implementation of an resource entry.
*/ */
public class MetaWeblogResource extends MetaWeblogEntry implements BlogResource { public class MetaWeblogResource extends MetaWeblogEntry implements BlogResource {
private MetaWeblogBlog blog; private final MetaWeblogBlog blog;
private String name; private final String name;
private String contentType; private final String contentType;
private byte[] bytes; private byte[] bytes;
MetaWeblogResource(MetaWeblogBlog blog, MetaWeblogResource(final MetaWeblogBlog blog, final String name, final String contentType, final byte[] bytes) {
String name, String contentType, byte[] bytes) {
super(blog, new HashMap()); super(blog, new HashMap());
this.blog = blog; this.blog = blog;
this.name = name; this.name = name;
this.contentType = contentType; this.contentType = contentType;
this.bytes = bytes; this.bytes = bytes;
this.content = new Content(); content = new Content();
this.content.setType(contentType); content.setType(contentType);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String getName() { public String getName() {
return name; return name;
} }
@ -52,24 +53,28 @@ public class MetaWeblogResource extends MetaWeblogEntry implements BlogResource
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public String getToken() { public String getToken() {
return null; return null;
} }
/** /**
* Get content-type of associated media resource. * Get content-type of associated media resource.
*/ */
public String getContentType() { public String getContentType() {
return contentType; return contentType;
} }
/** /**
* Get media resource as input stream. * Get media resource as input stream.
*/ */
@Override
public InputStream getAsStream() throws BlogClientException { public InputStream getAsStream() throws BlogClientException {
HttpClient httpClient = new HttpClient(); final HttpClient httpClient = new HttpClient();
GetMethod method = new GetMethod(permalink); final GetMethod method = new GetMethod(permalink);
try { try {
httpClient.executeMethod(method); httpClient.executeMethod(method);
} catch (Exception e) { } catch (final Exception e) {
throw new BlogClientException("ERROR: error reading file", e); throw new BlogClientException("ERROR: error reading file", e);
} }
if (method.getStatusCode() != 200) { if (method.getStatusCode() != 200) {
@ -77,7 +82,7 @@ public class MetaWeblogResource extends MetaWeblogEntry implements BlogResource
} }
try { try {
return method.getResponseBodyAsStream(); return method.getResponseBodyAsStream();
} catch (Exception e) { } catch (final Exception e) {
throw new BlogClientException("ERROR: error reading file", e); throw new BlogClientException("ERROR: error reading file", e);
} }
} }
@ -85,6 +90,7 @@ public class MetaWeblogResource extends MetaWeblogEntry implements BlogResource
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override
public void save() throws BlogClientException { public void save() throws BlogClientException {
blog.saveResource(this); blog.saveResource(this);
} }
@ -92,7 +98,8 @@ public class MetaWeblogResource extends MetaWeblogEntry implements BlogResource
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void update(byte[] bytes) throws BlogClientException { @Override
public void update(final byte[] bytes) throws BlogClientException {
this.bytes = bytes; this.bytes = bytes;
save(); save();
} }
@ -107,6 +114,7 @@ public class MetaWeblogResource extends MetaWeblogEntry implements BlogResource
/** /**
* Not supported by MetaWeblog API * Not supported by MetaWeblog API
*/ */
@Override
public void delete() throws BlogClientException { public void delete() throws BlogClientException {
} }
} }

View file

@ -18,7 +18,6 @@ package org.rometools.propono.utils;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.PrintWriter; import java.io.PrintWriter;
/** /**
* Base Propono exception class. * Base Propono exception class.
*/ */
@ -27,7 +26,6 @@ public class ProponoException extends Exception {
private Throwable mRootCause = null; private Throwable mRootCause = null;
private String longMessage = null; private String longMessage = null;
/** /**
* Construct emtpy exception object. * Construct emtpy exception object.
*/ */
@ -35,87 +33,90 @@ public class ProponoException extends Exception {
super(); super();
} }
/** /**
* Construct ProponoException with message string. * Construct ProponoException with message string.
*
* @param s Error message string. * @param s Error message string.
*/ */
public ProponoException(String s) { public ProponoException(final String s) {
super(s); super(s);
} }
/** /**
* Construct ProponoException with message string. * Construct ProponoException with message string.
*
* @param s Error message string. * @param s Error message string.
*/ */
public ProponoException(String s, String longMessage) { public ProponoException(final String s, final String longMessage) {
super(s); super(s);
this.longMessage = longMessage; this.longMessage = longMessage;
} }
/** /**
* Construct ProponoException, wrapping existing throwable. * Construct ProponoException, wrapping existing throwable.
*
* @param s Error message * @param s Error message
* @param t Existing connection to wrap. * @param t Existing connection to wrap.
*/ */
public ProponoException(String s, Throwable t) { public ProponoException(final String s, final Throwable t) {
super(s); super(s);
mRootCause = t; mRootCause = t;
} }
/** /**
* Construct ProponoException, wrapping existing throwable. * Construct ProponoException, wrapping existing throwable.
*
* @param s Error message * @param s Error message
* @param t Existing connection to wrap. * @param t Existing connection to wrap.
*/ */
public ProponoException(String s, String longMessge, Throwable t) { public ProponoException(final String s, final String longMessge, final Throwable t) {
super(s); super(s);
mRootCause = t; mRootCause = t;
this.longMessage = longMessage; longMessage = longMessage;
} }
/** /**
* Construct ProponoException, wrapping existing throwable. * Construct ProponoException, wrapping existing throwable.
*
* @param t Existing exception to be wrapped. * @param t Existing exception to be wrapped.
*/ */
public ProponoException(Throwable t) { public ProponoException(final Throwable t) {
mRootCause = t; mRootCause = t;
} }
/** /**
* Get root cause object, or null if none. * Get root cause object, or null if none.
*
* @return Root cause or null if none. * @return Root cause or null if none.
*/ */
public Throwable getRootCause() { public Throwable getRootCause() {
return mRootCause; return mRootCause;
} }
/** /**
* Get root cause message. * Get root cause message.
*
* @return Root cause message. * @return Root cause message.
*/ */
public String getRootCauseMessage() { public String getRootCauseMessage() {
String rcmessage = null; String rcmessage = null;
if (getRootCause()!=null) { if (getRootCause() != null) {
if (getRootCause().getCause()!=null) { if (getRootCause().getCause() != null) {
rcmessage = getRootCause().getCause().getMessage(); rcmessage = getRootCause().getCause().getMessage();
} }
rcmessage = (rcmessage == null) ? getRootCause().getMessage() : rcmessage; rcmessage = rcmessage == null ? getRootCause().getMessage() : rcmessage;
rcmessage = (rcmessage == null) ? super.getMessage() : rcmessage; rcmessage = rcmessage == null ? super.getMessage() : rcmessage;
rcmessage = (rcmessage == null) ? "NONE" : rcmessage; rcmessage = rcmessage == null ? "NONE" : rcmessage;
} }
return rcmessage; return rcmessage;
} }
/** /**
* Print stack trace for exception and for root cause exception if htere is one. * Print stack trace for exception and for root cause exception if htere is one.
*
* @see java.lang.Throwable#printStackTrace() * @see java.lang.Throwable#printStackTrace()
*/ */
@Override
public void printStackTrace() { public void printStackTrace() {
super.printStackTrace(); super.printStackTrace();
if (mRootCause != null) { if (mRootCause != null) {
@ -124,12 +125,13 @@ public class ProponoException extends Exception {
} }
} }
/** /**
* Print stack trace for exception and for root cause exception if htere is one. * Print stack trace for exception and for root cause exception if htere is one.
*
* @param s Stream to print to. * @param s Stream to print to.
*/ */
public void printStackTrace(PrintStream s) { @Override
public void printStackTrace(final PrintStream s) {
super.printStackTrace(s); super.printStackTrace(s);
if (mRootCause != null) { if (mRootCause != null) {
s.println("--- ROOT CAUSE ---"); s.println("--- ROOT CAUSE ---");
@ -137,12 +139,13 @@ public class ProponoException extends Exception {
} }
} }
/** /**
* Print stack trace for exception and for root cause exception if htere is one. * Print stack trace for exception and for root cause exception if htere is one.
*
* @param s Writer to write to. * @param s Writer to write to.
*/ */
public void printStackTrace(PrintWriter s) { @Override
public void printStackTrace(final PrintWriter s) {
super.printStackTrace(s); super.printStackTrace(s);
if (null != mRootCause) { if (null != mRootCause) {
s.println("--- ROOT CAUSE ---"); s.println("--- ROOT CAUSE ---");

View file

@ -27,6 +27,7 @@ import java.io.OutputStream;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.jdom2.Document; import org.jdom2.Document;
import org.jdom2.Element; import org.jdom2.Element;
import org.jdom2.Namespace; import org.jdom2.Namespace;
@ -42,11 +43,11 @@ public class Utilities {
/** /**
* Returns the contents of the file in a byte array (from JavaAlmanac). * Returns the contents of the file in a byte array (from JavaAlmanac).
*/ */
public static byte[] getBytesFromFile(File file) throws IOException { public static byte[] getBytesFromFile(final File file) throws IOException {
InputStream is = new FileInputStream(file); final InputStream is = new FileInputStream(file);
// Get the size of the file // Get the size of the file
long length = file.length(); final long length = file.length();
// You cannot create an array using a long type. // You cannot create an array using a long type.
// It needs to be an int type. // It needs to be an int type.
@ -57,19 +58,18 @@ public class Utilities {
} }
// Create the byte array to hold the data // Create the byte array to hold the data
byte[] bytes = new byte[(int)length]; final byte[] bytes = new byte[(int) length];
// Read in the bytes // Read in the bytes
int offset = 0; int offset = 0;
int numRead = 0; int numRead = 0;
while (offset < bytes.length while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
&& (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
offset += numRead; offset += numRead;
} }
// Ensure all the bytes have been read in // Ensure all the bytes have been read in
if (offset < bytes.length) { if (offset < bytes.length) {
throw new IOException("Could not completely read file "+file.getName()); throw new IOException("Could not completely read file " + file.getName());
} }
// Close the input stream and return bytes // Close the input stream and return bytes
@ -80,9 +80,9 @@ public class Utilities {
/** /**
* Read input from stream and into string. * Read input from stream and into string.
*/ */
public static String streamToString(InputStream is) throws IOException { public static String streamToString(final InputStream is) throws IOException {
StringBuffer sb = new StringBuffer(); final StringBuffer sb = new StringBuffer();
BufferedReader in = new BufferedReader(new InputStreamReader(is)); final BufferedReader in = new BufferedReader(new InputStreamReader(is));
String line; String line;
while ((line = in.readLine()) != null) { while ((line = in.readLine()) != null) {
sb.append(line); sb.append(line);
@ -94,39 +94,36 @@ public class Utilities {
/** /**
* Copy input stream to output stream using 8K buffer. * Copy input stream to output stream using 8K buffer.
*/ */
public static void copyInputToOutput( public static void copyInputToOutput(final InputStream input, final OutputStream output) throws IOException {
InputStream input, final BufferedInputStream in = new BufferedInputStream(input);
OutputStream output) final BufferedOutputStream out = new BufferedOutputStream(output);
throws IOException { final byte buffer[] = new byte[8192];
BufferedInputStream in = new BufferedInputStream(input);
BufferedOutputStream out = new BufferedOutputStream(output);
byte buffer[] = new byte[8192];
for (int count = 0; count != -1;) { for (int count = 0; count != -1;) {
count = in.read(buffer, 0, 8192); count = in.read(buffer, 0, 8192);
if (count != -1) if (count != -1) {
out.write(buffer, 0, count); out.write(buffer, 0, count);
}
} }
try { try {
in.close(); in.close();
out.close(); out.close();
} catch (IOException ex) { } catch (final IOException ex) {
throw new IOException("Closing file streams, " + ex.getMessage()); throw new IOException("Closing file streams, " + ex.getMessage());
} }
} }
/** /**
* Replaces occurences of non-alphanumeric characters with a supplied char. * Replaces occurences of non-alphanumeric characters with a supplied char.
*/ */
public static String replaceNonAlphanumeric(String str, char subst) { public static String replaceNonAlphanumeric(final String str, final char subst) {
StringBuffer ret = new StringBuffer(str.length()); final StringBuffer ret = new StringBuffer(str.length());
char[] testChars = str.toCharArray(); final char[] testChars = str.toCharArray();
for (int i = 0; i < testChars.length; i++) { for (final char testChar : testChars) {
if (Character.isLetterOrDigit(testChars[i])) { if (Character.isLetterOrDigit(testChar)) {
ret.append(testChars[i]); ret.append(testChar);
} else { } else {
ret.append( subst ); ret.append(subst);
} }
} }
return ret.toString(); return ret.toString();
@ -135,10 +132,9 @@ public class Utilities {
/** /**
* Convert string to string array. * Convert string to string array.
*/ */
public static String[] stringToStringArray(String instr, String delim) public static String[] stringToStringArray(final String instr, final String delim) throws NoSuchElementException, NumberFormatException {
throws NoSuchElementException, NumberFormatException { final StringTokenizer toker = new StringTokenizer(instr, delim);
StringTokenizer toker = new StringTokenizer(instr, delim); final String stringArray[] = new String[toker.countTokens()];
String stringArray[] = new String[toker.countTokens()];
int i = 0; int i = 0;
while (toker.hasMoreTokens()) { while (toker.hasMoreTokens()) {
stringArray[i++] = toker.nextToken(); stringArray[i++] = toker.nextToken();
@ -149,53 +145,54 @@ public class Utilities {
/** /**
* Convert string array to string. * Convert string array to string.
*/ */
public static String stringArrayToString(String[] stringArray, String delim) { public static String stringArrayToString(final String[] stringArray, final String delim) {
String ret = ""; String ret = "";
for (int i = 0; i < stringArray.length; i++) { for (final String element : stringArray) {
if (ret.length() > 0) if (ret.length() > 0) {
ret = ret + delim + stringArray[i]; ret = ret + delim + element;
else } else {
ret = stringArray[i]; ret = element;
}
} }
return ret; return ret;
} }
static Pattern absoluteURIPattern = Pattern.compile("^[a-z0-9]*:.*$");
static Pattern absoluteURIPattern = Pattern.compile("^[a-z0-9]*:.*$"); private static boolean isAbsoluteURI(final String uri) {
private static boolean isAbsoluteURI(String uri) {
return absoluteURIPattern.matcher(uri).find(); return absoluteURIPattern.matcher(uri).find();
} }
private static boolean isRelativeURI(String uri) { private static boolean isRelativeURI(final String uri) {
return !isAbsoluteURI(uri); return !isAbsoluteURI(uri);
} }
/** /**
* } * } Resolve URI based considering xml:base and baseURI.
* Resolve URI based considering xml:base and baseURI. *
* @param baseURI Base URI of feed * @param baseURI Base URI of feed
* @param parent Parent from which to consider xml:base * @param parent Parent from which to consider xml:base
* @param url URL to be resolved * @param url URL to be resolved
*/ */
private static String resolveURI(String baseURI, Parent parent, String url) { private static String resolveURI(final String baseURI, final Parent parent, String url) {
if (isRelativeURI(url)) { if (isRelativeURI(url)) {
url = (!".".equals(url) && !"./".equals(url)) ? url : ""; url = !".".equals(url) && !"./".equals(url) ? url : "";
// Relative URI with parent // Relative URI with parent
if (parent != null && parent instanceof Element) { if (parent != null && parent instanceof Element) {
// Do we have an xml:base? // Do we have an xml:base?
String xmlbase = ((Element)parent).getAttributeValue( String xmlbase = ((Element) parent).getAttributeValue("base", Namespace.XML_NAMESPACE);
"base", Namespace.XML_NAMESPACE);
if (xmlbase != null && xmlbase.trim().length() > 0) { if (xmlbase != null && xmlbase.trim().length() > 0) {
if (isAbsoluteURI(xmlbase)) { if (isAbsoluteURI(xmlbase)) {
// Absolute xml:base, so form URI right now // Absolute xml:base, so form URI right now
if (url.startsWith("/")) { if (url.startsWith("/")) {
// Host relative URI // Host relative URI
int slashslash = xmlbase.indexOf("//"); final int slashslash = xmlbase.indexOf("//");
int nextslash = xmlbase.indexOf("/", slashslash + 2); final int nextslash = xmlbase.indexOf("/", slashslash + 2);
if (nextslash != -1) xmlbase = xmlbase.substring(0, nextslash); if (nextslash != -1) {
xmlbase = xmlbase.substring(0, nextslash);
}
return formURI(xmlbase, url); return formURI(xmlbase, url);
} }
if (!xmlbase.endsWith("/")) { if (!xmlbase.endsWith("/")) {
@ -205,14 +202,13 @@ public class Utilities {
return formURI(xmlbase, url); return formURI(xmlbase, url);
} else { } else {
// Relative xml:base, so walk up tree // Relative xml:base, so walk up tree
return resolveURI(baseURI, parent.getParent(), return resolveURI(baseURI, parent.getParent(), stripTrailingSlash(xmlbase) + "/" + stripStartingSlash(url));
stripTrailingSlash(xmlbase) + "/"+ stripStartingSlash(url));
} }
} }
// No xml:base so walk up tree // No xml:base so walk up tree
return resolveURI(baseURI, parent.getParent(), url); return resolveURI(baseURI, parent.getParent(), url);
// Relative URI with no parent (i.e. top of tree), so form URI right now // Relative URI with no parent (i.e. top of tree), so form URI right now
} else if (parent == null || parent instanceof Document) { } else if (parent == null || parent instanceof Document) {
return formURI(baseURI, url); return formURI(baseURI, url);
} }
@ -221,25 +217,26 @@ public class Utilities {
} }
/** /**
* Form URI by combining base with append portion and giving * Form URI by combining base with append portion and giving special consideration to append portions that begin with ".."
* special consideration to append portions that begin with ".." *
* @param base Base of URI, may end with trailing slash * @param base Base of URI, may end with trailing slash
* @param append String to append, may begin with slash or ".." * @param append String to append, may begin with slash or ".."
*/ */
private static String formURI(String base, String append) { private static String formURI(String base, String append) {
base = stripTrailingSlash(base); base = stripTrailingSlash(base);
append = stripStartingSlash(append); append = stripStartingSlash(append);
if (append.startsWith("..")) { if (append.startsWith("..")) {
String ret = null; final String ret = null;
String[] parts = append.split("/"); final String[] parts = append.split("/");
for (int i=0; i<parts.length; i++) { for (final String part : parts) {
if ("..".equals(parts[i])) { if ("..".equals(part)) {
int last = base.lastIndexOf("/"); final int last = base.lastIndexOf("/");
if (last != -1) { if (last != -1) {
base = base.substring(0, last); base = base.substring(0, last);
append = append.substring(3, append.length()); append = append.substring(3, append.length());
} else {
break;
} }
else break;
} }
} }
} }

View file

@ -15,35 +15,30 @@
*/ */
package org.rometools.propono.atom.client; package org.rometools.propono.atom.client;
import org.rometools.propono.atom.client.BasicAuthStrategy;
import org.rometools.propono.atom.client.ClientWorkspace;
import org.rometools.propono.atom.client.ClientAtomService;
import org.rometools.propono.atom.client.ClientCollection;
import org.rometools.propono.atom.client.AtomClientFactory;
import org.rometools.propono.atom.client.ClientEntry;
import org.rometools.propono.atom.client.ClientMediaEntry;
import com.sun.syndication.feed.atom.Category;
import com.sun.syndication.feed.atom.Content;
import org.rometools.propono.utils.ProponoException;
import org.rometools.propono.atom.common.Categories;
import org.rometools.propono.atom.common.Collection;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import junit.framework.Test; import junit.framework.Test;
import junit.framework.TestCase; import junit.framework.TestCase;
import junit.framework.TestSuite; import junit.framework.TestSuite;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.rometools.propono.atom.common.Categories;
import org.rometools.propono.atom.common.Collection;
import org.rometools.propono.utils.ProponoException;
import com.sun.syndication.feed.atom.Category;
import com.sun.syndication.feed.atom.Content;
/** /**
* Simple APP test designed to run against a live Atom server. * Simple APP test designed to run against a live Atom server.
*/ */
public class AtomClientTest extends TestCase { public class AtomClientTest extends TestCase {
private static Log log = private static Log log = LogFactory.getFactory().getInstance(AtomClientTest.class);
LogFactory.getFactory().getInstance(AtomClientTest.class);
private static ClientAtomService service = null; private static ClientAtomService service = null;
@ -53,56 +48,32 @@ public class AtomClientTest extends TestCase {
private static String password = "admin"; private static String password = "admin";
static { static {
try { try {
service = AtomClientFactory.getAtomService(endpoint, service = AtomClientFactory.getAtomService(endpoint, new BasicAuthStrategy(username, password));
new BasicAuthStrategy(username, password)); } catch (final Exception e) {
} catch (Exception e) {
log.error("ERROR creating service", e); log.error("ERROR creating service", e);
} }
} }
/* /*
// Roller OAuth example * // Roller OAuth example private static String endpoint = "http://macsnoopdave:8080/roller-services/app"; private static String consumerKey =
private static String endpoint = "http://macsnoopdave:8080/roller-services/app"; * "55132608a2fb68816bcd3d1caeafc933"; private static String consumerSecret = "bb420783-fdea-4270-ab83-36445c18c307"; private static String requestUri =
private static String consumerKey = "55132608a2fb68816bcd3d1caeafc933"; * "http://macsnoopdave:8080/roller-services/oauth/requestToken"; private static String authorizeUri =
private static String consumerSecret = "bb420783-fdea-4270-ab83-36445c18c307"; * "http://macsnoopdave:8080/roller-services/oauth/authorize?userId=roller&oauth_callback=none"; private static String accessUri =
private static String requestUri = "http://macsnoopdave:8080/roller-services/oauth/requestToken"; * "http://macsnoopdave:8080/roller-services/oauth/accessToken"; private static String username = "roller"; private static String password = "n/a"; static {
private static String authorizeUri = "http://macsnoopdave:8080/roller-services/oauth/authorize?userId=roller&oauth_callback=none"; * try { service = AtomClientFactory.getAtomService(endpoint, new OAuthStrategy( username, consumerKey, consumerSecret, "HMAC-SHA1", requestUri,
private static String accessUri = "http://macsnoopdave:8080/roller-services/oauth/accessToken"; * authorizeUri, accessUri)); } catch (Exception e) { log.error("ERROR creating service", e); } }
private static String username = "roller"; */
private static String password = "n/a";
static {
try {
service = AtomClientFactory.getAtomService(endpoint,
new OAuthStrategy(
username, consumerKey, consumerSecret, "HMAC-SHA1",
requestUri, authorizeUri, accessUri));
} catch (Exception e) {
log.error("ERROR creating service", e);
}
}
*/
// GData Blogger API // GData Blogger API
/* /*
private static String endpoint = "http://www.blogger.com/feeds/default/blogs?alt=atom-service"; * private static String endpoint = "http://www.blogger.com/feeds/default/blogs?alt=atom-service"; private static String email = "EMAIL"; private static
private static String email = "EMAIL"; * String password = "PASSWORD"; private static String serviceName = "blogger"; static { try { service = AtomClientFactory.getAtomService(endpoint, new
private static String password = "PASSWORD"; * GDataAuthStrategy(email, password, serviceName)); } catch (Exception e) { log.error("ERROR creating service", e); } }
private static String serviceName = "blogger"; */
static {
try {
service = AtomClientFactory.getAtomService(endpoint,
new GDataAuthStrategy(email, password, serviceName));
} catch (Exception e) {
log.error("ERROR creating service", e);
}
}
*/
private final int maxPagingEntries = 10;
private int maxPagingEntries = 10; public AtomClientTest(final String testName) {
public AtomClientTest(String testName) {
super(testName); super(testName);
} }
@ -118,14 +89,16 @@ public class AtomClientTest extends TestCase {
return password; return password;
} }
@Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
} }
@Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
} }
public static Test suite() { public static Test suite() {
TestSuite suite = new TestSuite(AtomClientTest.class); final TestSuite suite = new TestSuite(AtomClientTest.class);
return suite; return suite;
} }
@ -135,12 +108,12 @@ public class AtomClientTest extends TestCase {
public void testGetAtomService() throws Exception { public void testGetAtomService() throws Exception {
assertNotNull(service); assertNotNull(service);
assertTrue(service.getWorkspaces().size() > 0); assertTrue(service.getWorkspaces().size() > 0);
for (Iterator it = service.getWorkspaces().iterator(); it.hasNext();) { for (final Iterator it = service.getWorkspaces().iterator(); it.hasNext();) {
ClientWorkspace space = (ClientWorkspace) it.next(); final ClientWorkspace space = (ClientWorkspace) it.next();
assertNotNull(space.getTitle()); assertNotNull(space.getTitle());
log.debug("Workspace: " + space.getTitle()); log.debug("Workspace: " + space.getTitle());
for (Iterator colit = space.getCollections().iterator(); colit.hasNext();) { for (final Iterator colit = space.getCollections().iterator(); colit.hasNext();) {
ClientCollection col = (ClientCollection) colit.next(); final ClientCollection col = (ClientCollection) colit.next();
log.debug(" Collection: " + col.getTitle() + " Accepts: " + col.getAccepts()); log.debug(" Collection: " + col.getTitle() + " Accepts: " + col.getAccepts());
log.debug(" href: " + col.getHrefResolved()); log.debug(" href: " + col.getHrefResolved());
assertNotNull(col.getTitle()); assertNotNull(col.getTitle());
@ -149,25 +122,24 @@ public class AtomClientTest extends TestCase {
} }
/** /**
* Tests that entries can be posted and removed in all collections that * Tests that entries can be posted and removed in all collections that accept entries. Fails if no collections found that accept entries.
* accept entries. Fails if no collections found that accept entries.
*/ */
public void testSimpleEntryPostAndRemove() throws Exception { public void testSimpleEntryPostAndRemove() throws Exception {
assertNotNull(service); assertNotNull(service);
assertTrue(service.getWorkspaces().size() > 0); assertTrue(service.getWorkspaces().size() > 0);
int count = 0; int count = 0;
for (Iterator it = service.getWorkspaces().iterator(); it.hasNext();) { for (final Iterator it = service.getWorkspaces().iterator(); it.hasNext();) {
ClientWorkspace space = (ClientWorkspace) it.next(); final ClientWorkspace space = (ClientWorkspace) it.next();
assertNotNull(space.getTitle()); assertNotNull(space.getTitle());
for (Iterator colit = space.getCollections().iterator(); colit.hasNext();) { for (final Iterator colit = space.getCollections().iterator(); colit.hasNext();) {
ClientCollection col = (ClientCollection) colit.next(); final ClientCollection col = (ClientCollection) colit.next();
if (col.accepts(Collection.ENTRY_TYPE)) { if (col.accepts(Collection.ENTRY_TYPE)) {
// we found a collection that accepts entries, so post one // we found a collection that accepts entries, so post one
ClientEntry m1 = col.createEntry(); final ClientEntry m1 = col.createEntry();
m1.setTitle("Test post"); m1.setTitle("Test post");
Content c = new Content(); final Content c = new Content();
c.setValue("This is a test post"); c.setValue("This is a test post");
c.setType("html"); c.setType("html");
m1.setContent(c); m1.setContent(c);
@ -175,7 +147,7 @@ public class AtomClientTest extends TestCase {
col.addEntry(m1); col.addEntry(m1);
// entry should now exist on server // entry should now exist on server
ClientEntry m2 = col.getEntry(m1.getEditURI()); final ClientEntry m2 = col.getEntry(m1.getEditURI());
assertNotNull(m2); assertNotNull(m2);
// remove entry // remove entry
@ -185,7 +157,7 @@ public class AtomClientTest extends TestCase {
boolean failed = false; boolean failed = false;
try { try {
col.getEntry(m1.getEditURI()); col.getEntry(m1.getEditURI());
} catch (ProponoException e) { } catch (final ProponoException e) {
failed = true; failed = true;
} }
assertTrue(failed); assertTrue(failed);
@ -197,25 +169,24 @@ public class AtomClientTest extends TestCase {
} }
/** /**
* Tests that entries can be posted, updated and removed in all collections that * Tests that entries can be posted, updated and removed in all collections that accept entries. Fails if no collections found that accept entries.
* accept entries. Fails if no collections found that accept entries.
*/ */
public void testSimpleEntryPostUpdateAndRemove() throws Exception { public void testSimpleEntryPostUpdateAndRemove() throws Exception {
assertNotNull(service); assertNotNull(service);
assertTrue(service.getWorkspaces().size() > 0); assertTrue(service.getWorkspaces().size() > 0);
int count = 0; int count = 0;
for (Iterator it = service.getWorkspaces().iterator(); it.hasNext();) { for (final Iterator it = service.getWorkspaces().iterator(); it.hasNext();) {
ClientWorkspace space = (ClientWorkspace) it.next(); final ClientWorkspace space = (ClientWorkspace) it.next();
assertNotNull(space.getTitle()); assertNotNull(space.getTitle());
for (Iterator colit = space.getCollections().iterator(); colit.hasNext();) { for (final Iterator colit = space.getCollections().iterator(); colit.hasNext();) {
ClientCollection col = (ClientCollection) colit.next(); final ClientCollection col = (ClientCollection) colit.next();
if (col.accepts(Collection.ENTRY_TYPE)) { if (col.accepts(Collection.ENTRY_TYPE)) {
// we found a collection that accepts entries, so post one // we found a collection that accepts entries, so post one
ClientEntry m1 = col.createEntry(); final ClientEntry m1 = col.createEntry();
m1.setTitle(col.getTitle() + ": Test post"); m1.setTitle(col.getTitle() + ": Test post");
Content c = new Content(); final Content c = new Content();
c.setValue("This is a test post"); c.setValue("This is a test post");
c.setType("html"); c.setType("html");
m1.setContent(c); m1.setContent(c);
@ -223,14 +194,14 @@ public class AtomClientTest extends TestCase {
col.addEntry(m1); col.addEntry(m1);
// entry should now exist on server // entry should now exist on server
ClientEntry m2 = (ClientEntry)col.getEntry(m1.getEditURI()); final ClientEntry m2 = col.getEntry(m1.getEditURI());
assertNotNull(m2); assertNotNull(m2);
m2.setTitle(col.getTitle() + ": Updated title"); m2.setTitle(col.getTitle() + ": Updated title");
m2.update(); m2.update();
// entry should now be updated on server // entry should now be updated on server
ClientEntry m3 = (ClientEntry)col.getEntry(m1.getEditURI()); final ClientEntry m3 = col.getEntry(m1.getEditURI());
assertEquals(col.getTitle() + ": Updated title", m3.getTitle()); assertEquals(col.getTitle() + ": Updated title", m3.getTitle());
// remove entry // remove entry
@ -240,7 +211,7 @@ public class AtomClientTest extends TestCase {
boolean failed = false; boolean failed = false;
try { try {
col.getEntry(m1.getEditURI()); col.getEntry(m1.getEditURI());
} catch (ProponoException e) { } catch (final ProponoException e) {
failed = true; failed = true;
} }
assertTrue(failed); assertTrue(failed);
@ -253,16 +224,16 @@ public class AtomClientTest extends TestCase {
public void testFindWorkspace() throws Exception { public void testFindWorkspace() throws Exception {
assertNotNull(service); assertNotNull(service);
ClientWorkspace ws = (ClientWorkspace)service.findWorkspace("adminblog"); final ClientWorkspace ws = (ClientWorkspace) service.findWorkspace("adminblog");
if (ws != null) { if (ws != null) {
ClientCollection col = (ClientCollection)ws.findCollection(null, "entry"); final ClientCollection col = (ClientCollection) ws.findCollection(null, "entry");
ClientEntry entry = col.createEntry(); final ClientEntry entry = col.createEntry();
entry.setTitle("NPE on submitting order query"); entry.setTitle("NPE on submitting order query");
entry.setContent("This is a <b>bad</b> one!", Content.HTML); entry.setContent("This is a <b>bad</b> one!", Content.HTML);
col.addEntry(entry); col.addEntry(entry);
// entry should now exist on server // entry should now exist on server
ClientEntry saved = (ClientEntry)col.getEntry(entry.getEditURI()); final ClientEntry saved = col.getEntry(entry.getEditURI());
assertNotNull(saved); assertNotNull(saved);
// remove entry // remove entry
@ -272,7 +243,7 @@ public class AtomClientTest extends TestCase {
boolean failed = false; boolean failed = false;
try { try {
col.getEntry(saved.getEditURI()); col.getEntry(saved.getEditURI());
} catch (ProponoException e) { } catch (final ProponoException e) {
failed = true; failed = true;
} }
assertTrue(failed); assertTrue(failed);
@ -280,25 +251,24 @@ public class AtomClientTest extends TestCase {
} }
/** /**
* Test posting an entry to every available collection with a fixed and * Test posting an entry to every available collection with a fixed and an unfixed category if server support allows, then cleanup.
* an unfixed category if server support allows, then cleanup.
*/ */
public void testEntryPostWithCategories() throws Exception { public void testEntryPostWithCategories() throws Exception {
assertNotNull(service); assertNotNull(service);
assertTrue(service.getWorkspaces().size() > 0); assertTrue(service.getWorkspaces().size() > 0);
int count = 0; int count = 0;
for (Iterator it = service.getWorkspaces().iterator(); it.hasNext();) { for (final Iterator it = service.getWorkspaces().iterator(); it.hasNext();) {
ClientWorkspace space = (ClientWorkspace) it.next(); final ClientWorkspace space = (ClientWorkspace) it.next();
assertNotNull(space.getTitle()); assertNotNull(space.getTitle());
for (Iterator colit = space.getCollections().iterator(); colit.hasNext();) { for (final Iterator colit = space.getCollections().iterator(); colit.hasNext();) {
ClientCollection col = (ClientCollection) colit.next(); final ClientCollection col = (ClientCollection) colit.next();
if (col.accepts(Collection.ENTRY_TYPE)) { if (col.accepts(Collection.ENTRY_TYPE)) {
// we found a collection that accepts GIF, so post one // we found a collection that accepts GIF, so post one
ClientEntry m1 = col.createEntry(); final ClientEntry m1 = col.createEntry();
m1.setTitle("Test post"); m1.setTitle("Test post");
Content c = new Content(); final Content c = new Content();
c.setValue("This is a test post"); c.setValue("This is a test post");
c.setType("html"); c.setType("html");
m1.setContent(c); m1.setContent(c);
@ -306,16 +276,18 @@ public class AtomClientTest extends TestCase {
// if possible, pick one fixed an un unfixed category // if possible, pick one fixed an un unfixed category
Category fixedCat = null; Category fixedCat = null;
Category unfixedCat = null; Category unfixedCat = null;
List entryCats = new ArrayList(); final List entryCats = new ArrayList();
for (int i=0; i<col.getCategories().size(); i++) { for (int i = 0; i < col.getCategories().size(); i++) {
Categories cats = (Categories)col.getCategories().get(i); final Categories cats = (Categories) col.getCategories().get(i);
if (cats.isFixed() && fixedCat == null) { if (cats.isFixed() && fixedCat == null) {
String scheme = cats.getScheme(); final String scheme = cats.getScheme();
fixedCat = (Category)cats.getCategories().get(0); fixedCat = (Category) cats.getCategories().get(0);
if (fixedCat.getScheme() == null) fixedCat.setScheme(scheme); if (fixedCat.getScheme() == null) {
fixedCat.setScheme(scheme);
}
entryCats.add(fixedCat); entryCats.add(fixedCat);
} else if (!cats.isFixed() && unfixedCat == null) { } else if (!cats.isFixed() && unfixedCat == null) {
String scheme = cats.getScheme(); final String scheme = cats.getScheme();
unfixedCat = new Category(); unfixedCat = new Category();
unfixedCat.setScheme(scheme); unfixedCat.setScheme(scheme);
unfixedCat.setTerm("tagster"); unfixedCat.setTerm("tagster");
@ -326,15 +298,15 @@ public class AtomClientTest extends TestCase {
col.addEntry(m1); col.addEntry(m1);
// entry should now exist on server // entry should now exist on server
ClientEntry m2 = (ClientEntry)col.getEntry(m1.getEditURI()); final ClientEntry m2 = col.getEntry(m1.getEditURI());
assertNotNull(m2); assertNotNull(m2);
if (fixedCat != null) { if (fixedCat != null) {
// we added a fixed category, let's make sure it's there // we added a fixed category, let's make sure it's there
boolean foundCat = false; boolean foundCat = false;
for (Iterator catit = m2.getCategories().iterator(); catit.hasNext();) { for (final Object element : m2.getCategories()) {
Category cat = (Category) catit.next(); final Category cat = (Category) element;
if ( cat.getTerm().equals( fixedCat.getTerm())) { if (cat.getTerm().equals(fixedCat.getTerm())) {
foundCat = true; foundCat = true;
} }
} }
@ -344,9 +316,9 @@ public class AtomClientTest extends TestCase {
if (unfixedCat != null) { if (unfixedCat != null) {
// we added an unfixed category, let's make sure it's there // we added an unfixed category, let's make sure it's there
boolean foundCat = false; boolean foundCat = false;
for (Iterator catit = m2.getCategories().iterator(); catit.hasNext();) { for (final Object element : m2.getCategories()) {
Category cat = (Category) catit.next(); final Category cat = (Category) element;
if (cat.getTerm().equals( unfixedCat.getTerm())) { if (cat.getTerm().equals(unfixedCat.getTerm())) {
foundCat = true; foundCat = true;
} }
} }
@ -360,7 +332,7 @@ public class AtomClientTest extends TestCase {
boolean failed = false; boolean failed = false;
try { try {
col.getEntry(m1.getEditURI()); col.getEntry(m1.getEditURI());
} catch (ProponoException e) { } catch (final ProponoException e) {
failed = true; failed = true;
} }
assertTrue(failed); assertTrue(failed);
@ -378,21 +350,21 @@ public class AtomClientTest extends TestCase {
assertNotNull(service); assertNotNull(service);
assertTrue(service.getWorkspaces().size() > 0); assertTrue(service.getWorkspaces().size() > 0);
int count = 0; int count = 0;
for (Iterator it = service.getWorkspaces().iterator(); it.hasNext();) { for (final Iterator it = service.getWorkspaces().iterator(); it.hasNext();) {
ClientWorkspace space = (ClientWorkspace) it.next(); final ClientWorkspace space = (ClientWorkspace) it.next();
assertNotNull(space.getTitle()); assertNotNull(space.getTitle());
for (Iterator colit = space.getCollections().iterator(); colit.hasNext();) { for (final Iterator colit = space.getCollections().iterator(); colit.hasNext();) {
ClientCollection col = (ClientCollection) colit.next(); final ClientCollection col = (ClientCollection) colit.next();
if (col.accepts("image/gif")) { if (col.accepts("image/gif")) {
// we found a collection that accepts GIF, so post one // we found a collection that accepts GIF, so post one
ClientMediaEntry m1 = col.createMediaEntry("duke"+count, "duke"+count, "image/gif", final ClientMediaEntry m1 = col.createMediaEntry("duke" + count, "duke" + count, "image/gif", new FileInputStream(
new FileInputStream("test/testdata/duke-wave-shadow.gif")); "test/testdata/duke-wave-shadow.gif"));
col.addEntry(m1); col.addEntry(m1);
// entry should now exist on server // entry should now exist on server
ClientMediaEntry m2 = (ClientMediaEntry)col.getEntry(m1.getEditURI()); final ClientMediaEntry m2 = (ClientMediaEntry) col.getEntry(m1.getEditURI());
assertNotNull(m2); assertNotNull(m2);
// remove entry // remove entry
@ -402,7 +374,7 @@ public class AtomClientTest extends TestCase {
boolean failed = false; boolean failed = false;
try { try {
col.getEntry(m1.getEditURI()); col.getEntry(m1.getEditURI());
} catch (ProponoException e) { } catch (final ProponoException e) {
failed = true; failed = true;
} }
assertTrue(failed); assertTrue(failed);
@ -416,44 +388,17 @@ public class AtomClientTest extends TestCase {
/** /**
* Post X media entries each media collection found, test paging, then cleanup. * Post X media entries each media collection found, test paging, then cleanup.
* *
public void testMediaPaging() throws Exception { * public void testMediaPaging() throws Exception { ClientAtomService service = getClientAtomService(); assertNotNull(service);
ClientAtomService service = getClientAtomService(); * assertTrue(service.getWorkspaces().size() > 0); int count = 0; for (Iterator it = service.getWorkspaces().iterator(); it.hasNext();) { ClientWorkspace
assertNotNull(service); * space = (ClientWorkspace) it.next(); assertNotNull(space.getTitle());
assertTrue(service.getWorkspaces().size() > 0); *
int count = 0; * for (Iterator colit = space.getCollections().iterator(); colit.hasNext();) { ClientCollection col = (ClientCollection) colit.next(); if
for (Iterator it = service.getWorkspaces().iterator(); it.hasNext();) { * (col.accepts("image/gif")) {
ClientWorkspace space = (ClientWorkspace) it.next(); *
assertNotNull(space.getTitle()); * // we found a collection that accepts GIF, so post 100 of them List posted = new ArrayList(); for (int i=0; i<maxPagingEntries; i++) { ClientMediaEntry
* m1 = col.createMediaEntry("duke"+count, "duke"+count, "image/gif", new FileInputStream("test/testdata/duke-wave-shadow.gif")); col.addEntry(m1);
for (Iterator colit = space.getCollections().iterator(); colit.hasNext();) { * posted.add(m1); } int entryCount = 0; for (Iterator iter = col.getEntries(); iter.hasNext();) { ClientMediaEntry entry = (ClientMediaEntry) iter.next();
ClientCollection col = (ClientCollection) colit.next(); * entryCount++; } for (Iterator delit = posted.iterator(); delit.hasNext();) { ClientEntry entry = (ClientEntry) delit.next(); entry.remove(); }
if (col.accepts("image/gif")) { * assertTrue(entryCount >= maxPagingEntries); count++; break; } } } assertTrue(count > 0); }
*/
// we found a collection that accepts GIF, so post 100 of them
List posted = new ArrayList();
for (int i=0; i<maxPagingEntries; i++) {
ClientMediaEntry m1 = col.createMediaEntry("duke"+count, "duke"+count, "image/gif",
new FileInputStream("test/testdata/duke-wave-shadow.gif"));
col.addEntry(m1);
posted.add(m1);
}
int entryCount = 0;
for (Iterator iter = col.getEntries(); iter.hasNext();) {
ClientMediaEntry entry = (ClientMediaEntry) iter.next();
entryCount++;
}
for (Iterator delit = posted.iterator(); delit.hasNext();) {
ClientEntry entry = (ClientEntry) delit.next();
entry.remove();
}
assertTrue(entryCount >= maxPagingEntries);
count++;
break;
}
}
}
assertTrue(count > 0);
}*/
} }

View file

@ -15,39 +15,38 @@
*/ */
package org.rometools.propono.atom.client; package org.rometools.propono.atom.client;
import org.rometools.propono.atom.client.ClientCollection;
import org.rometools.propono.atom.client.ClientAtomService;
import org.rometools.propono.atom.client.AtomClientFactory;
import org.rometools.propono.atom.client.GDataAuthStrategy;
import org.rometools.propono.atom.client.ClientEntry;
import com.sun.syndication.feed.atom.Content;
import java.util.Iterator; import java.util.Iterator;
import junit.framework.Test; import junit.framework.Test;
import junit.framework.TestCase; import junit.framework.TestCase;
import junit.framework.TestSuite; import junit.framework.TestSuite;
import com.sun.syndication.feed.atom.Content;
/** /**
* Simple APP test designed to run against Blogger.com. * Simple APP test designed to run against Blogger.com.
*/ */
public class BloggerDotComTest extends TestCase { public class BloggerDotComTest extends TestCase {
private String collectionURI = "http://www.blogger.com/feeds/BLOGID/posts/default"; private final String collectionURI = "http://www.blogger.com/feeds/BLOGID/posts/default";
private String atomServiceURI= "http://www.blogger.com/feeds/default/blogs?alt=atom-service"; private final String atomServiceURI = "http://www.blogger.com/feeds/default/blogs?alt=atom-service";
private String email = "EMAIL"; private final String email = "EMAIL";
private String password = "PASSWORD"; private final String password = "PASSWORD";
public BloggerDotComTest(String testName) { public BloggerDotComTest(final String testName) {
super(testName); super(testName);
} }
@Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
} }
@Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
} }
public static Test suite() { public static Test suite() {
TestSuite suite = new TestSuite(BloggerDotComTest.class); final TestSuite suite = new TestSuite(BloggerDotComTest.class);
return suite; return suite;
} }
@ -57,35 +56,29 @@ public class BloggerDotComTest extends TestCase {
public void testGetEntries() throws Exception { public void testGetEntries() throws Exception {
// no auth necessary for iterating through entries // no auth necessary for iterating through entries
ClientCollection col = AtomClientFactory.getCollection(collectionURI, ClientCollection col = AtomClientFactory.getCollection(collectionURI, new GDataAuthStrategy(email, password, "blogger"));
new GDataAuthStrategy(email, password, "blogger"));
assertNotNull(col); assertNotNull(col);
int count = 0; int count = 0;
for (Iterator it = col.getEntries(); it.hasNext();) { for (final Iterator it = col.getEntries(); it.hasNext();) {
ClientEntry entry = (ClientEntry) it.next(); final ClientEntry entry = (ClientEntry) it.next();
assertNotNull(entry); assertNotNull(entry);
count++; count++;
} }
assertTrue(count > 0); assertTrue(count > 0);
col = AtomClientFactory.getCollection(collectionURI, col = AtomClientFactory.getCollection(collectionURI, new GDataAuthStrategy(email, password, "blogger"));
new GDataAuthStrategy(email, password, "blogger")); final ClientEntry p1 = col.createEntry();
ClientEntry p1 = col.createEntry();
p1.setTitle("Propono post"); p1.setTitle("Propono post");
Content c = new Content(); final Content c = new Content();
c.setValue("This is content from ROME Propono"); c.setValue("This is content from ROME Propono");
p1.setContent(c); p1.setContent(c);
col.addEntry(p1); col.addEntry(p1);
ClientEntry p2 = col.getEntry(p1.getEditURI()); final ClientEntry p2 = col.getEntry(p1.getEditURI());
assertNotNull(p2); assertNotNull(p2);
final ClientAtomService atomService = AtomClientFactory.getAtomService(collectionURI, new GDataAuthStrategy(email, password, "blogger"));
ClientAtomService atomService = AtomClientFactory.getAtomService(
collectionURI, new GDataAuthStrategy(email, password, "blogger"));
assertNotNull(atomService); assertNotNull(atomService);
} }
} }

View file

@ -15,35 +15,38 @@
*/ */
package org.rometools.propono.atom.common; package org.rometools.propono.atom.common;
import org.rometools.propono.atom.common.Workspace;
import org.rometools.propono.atom.common.AtomService;
import org.rometools.propono.atom.common.Categories;
import org.rometools.propono.atom.common.Collection;
import com.sun.syndication.feed.atom.Category;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.util.Iterator; import java.util.Iterator;
import junit.framework.*;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.jdom2.Document; import org.jdom2.Document;
import org.jdom2.Element; import org.jdom2.Element;
import org.jdom2.input.SAXBuilder; import org.jdom2.input.SAXBuilder;
import com.sun.syndication.feed.atom.Category;
/** /**
* Tests reading and writing of service document, no server needed. * Tests reading and writing of service document, no server needed.
*/ */
public class AtomServiceTest extends TestCase { public class AtomServiceTest extends TestCase {
public AtomServiceTest(String testName) { public AtomServiceTest(final String testName) {
super(testName); super(testName);
} }
@Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
} }
@Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
} }
public static Test suite() { public static Test suite() {
TestSuite suite = new TestSuite(AtomServiceTest.class); final TestSuite suite = new TestSuite(AtomServiceTest.class);
return suite; return suite;
} }
@ -54,31 +57,31 @@ public class AtomServiceTest extends TestCase {
public void testDocumentToService() { public void testDocumentToService() {
try { try {
// Load service document from disk // Load service document from disk
SAXBuilder builder = new SAXBuilder(); final SAXBuilder builder = new SAXBuilder();
Document document = builder.build(new FileInputStream("test/testdata/servicedoc1.xml")); final Document document = builder.build(new FileInputStream("test/testdata/servicedoc1.xml"));
assertNotNull(document); assertNotNull(document);
AtomService service = AtomService.documentToService(document); final AtomService service = AtomService.documentToService(document);
int workspaceCount = 0; int workspaceCount = 0;
// Verify that service contains expected workspaces, collections and categories // Verify that service contains expected workspaces, collections and categories
for (Iterator it = service.getWorkspaces().iterator(); it.hasNext();) { for (final Iterator it = service.getWorkspaces().iterator(); it.hasNext();) {
Workspace space = (Workspace)it.next(); final Workspace space = (Workspace) it.next();
assertNotNull(space.getTitle()); assertNotNull(space.getTitle());
workspaceCount++; workspaceCount++;
int collectionCount = 0; int collectionCount = 0;
for (Iterator colit = space.getCollections().iterator(); colit.hasNext();) { for (final Iterator colit = space.getCollections().iterator(); colit.hasNext();) {
Collection col = (Collection)colit.next(); final Collection col = (Collection) colit.next();
assertNotNull(col.getTitle()); assertNotNull(col.getTitle());
assertNotNull(col.getHrefResolved()); assertNotNull(col.getHrefResolved());
collectionCount++; collectionCount++;
int catCount = 0; int catCount = 0;
if (col.getCategories().size() > 0) { if (col.getCategories().size() > 0) {
for (Iterator catsit = col.getCategories().iterator(); catsit.hasNext();) { for (final Iterator catsit = col.getCategories().iterator(); catsit.hasNext();) {
Categories cats = (Categories) catsit.next(); final Categories cats = (Categories) catsit.next();
for (Iterator catit = cats.getCategories().iterator(); catit.hasNext();) { for (final Iterator catit = cats.getCategories().iterator(); catit.hasNext();) {
Category cat = (Category) catit.next(); final Category cat = (Category) catit.next();
catCount++; catCount++;
} }
assertTrue(catCount > 0); assertTrue(catCount > 0);
@ -89,7 +92,7 @@ public class AtomServiceTest extends TestCase {
assertTrue(workspaceCount > 0); assertTrue(workspaceCount > 0);
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
fail(); fail();
} }
@ -101,47 +104,43 @@ public class AtomServiceTest extends TestCase {
public void testServiceToDocument() { public void testServiceToDocument() {
try { try {
// Create service with workspace and collections // Create service with workspace and collections
AtomService service = new AtomService(); final AtomService service = new AtomService();
Workspace workspace1 = new Workspace("workspace1", null); final Workspace workspace1 = new Workspace("workspace1", null);
Workspace workspace2 = new Workspace("workspace1", null); final Workspace workspace2 = new Workspace("workspace1", null);
service.addWorkspace(workspace1); service.addWorkspace(workspace1);
service.addWorkspace(workspace2); service.addWorkspace(workspace2);
Collection collection11 = final Collection collection11 = new Collection("collection11", null, "http://example.com/app/col11");
new Collection("collection11", null, "http://example.com/app/col11"); final Collection collection12 = new Collection("collection12", null, "http://example.com/app/col12");
Collection collection12 =
new Collection("collection12", null, "http://example.com/app/col12");
workspace1.addCollection(collection11); workspace1.addCollection(collection11);
workspace1.addCollection(collection12); workspace1.addCollection(collection12);
Collection collection21 = final Collection collection21 = new Collection("collection21", null, "http://example.com/app/col21");
new Collection("collection21", null, "http://example.com/app/col21"); final Collection collection22 = new Collection("collection22", null, "http://example.com/app/col22");
Collection collection22 =
new Collection("collection22", null, "http://example.com/app/col22");
workspace2.addCollection(collection21); workspace2.addCollection(collection21);
workspace2.addCollection(collection22); workspace2.addCollection(collection22);
// TODO: add categories at collection level // TODO: add categories at collection level
// Convert to JDOM document // Convert to JDOM document
Document document = service.serviceToDocument(); final Document document = service.serviceToDocument();
// verify that JDOM document contains service, workspace and collection // verify that JDOM document contains service, workspace and collection
assertEquals("service", document.getRootElement().getName()); assertEquals("service", document.getRootElement().getName());
int workspaceCount = 0; int workspaceCount = 0;
for (Iterator spaceit = document.getRootElement().getChildren().iterator(); spaceit.hasNext();) { for (final Object element : document.getRootElement().getChildren()) {
Element elem = (Element) spaceit.next(); final Element elem = (Element) element;
if ("workspace".equals(elem.getName())) { if ("workspace".equals(elem.getName())) {
workspaceCount++; workspaceCount++;
} }
boolean workspaceTitle = false; boolean workspaceTitle = false;
int collectionCount = 0; int collectionCount = 0;
for (Iterator colit = elem.getChildren().iterator(); colit.hasNext();) { for (final Object element2 : elem.getChildren()) {
Element colelem = (Element) colit.next(); final Element colelem = (Element) element2;
if ("title".equals(colelem.getName())) { if ("title".equals(colelem.getName())) {
workspaceTitle = true; workspaceTitle = true;
} else if ("collection".equals(colelem.getName())){ } else if ("collection".equals(colelem.getName())) {
collectionCount++; collectionCount++;
} }
@ -152,7 +151,7 @@ public class AtomServiceTest extends TestCase {
} }
assertTrue(workspaceCount > 0); assertTrue(workspaceCount > 0);
} catch (Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
fail(); fail();
} }

View file

@ -15,24 +15,26 @@
*/ */
package org.rometools.propono.atom.common; package org.rometools.propono.atom.common;
import org.rometools.propono.atom.common.Collection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import junit.framework.*;
import junit.framework.TestCase;
/** /**
* Tests Collection class, no server needed. * Tests Collection class, no server needed.
*/ */
public class CollectionTest extends TestCase { public class CollectionTest extends TestCase {
public CollectionTest(String testName) { public CollectionTest(final String testName) {
super(testName); super(testName);
} }
@Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
} }
@Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
} }
@ -41,8 +43,7 @@ public class CollectionTest extends TestCase {
*/ */
public void testAccepts() { public void testAccepts() {
Collection col = final Collection col = new Collection("dummy_title", "dummy_titletype", "dummy_href");
new Collection("dummy_title","dummy_titletype","dummy_href");
col.setAccepts(Collections.singletonList("image/*")); col.setAccepts(Collections.singletonList("image/*"));
assertTrue(col.accepts("image/gif")); assertTrue(col.accepts("image/gif"));
@ -50,7 +51,7 @@ public class CollectionTest extends TestCase {
assertTrue(col.accepts("image/png")); assertTrue(col.accepts("image/png"));
assertFalse(col.accepts("test/html")); assertFalse(col.accepts("test/html"));
List accepts = new ArrayList(); final List accepts = new ArrayList();
accepts.add("image/*"); accepts.add("image/*");
accepts.add("text/*"); accepts.add("text/*");
col.setAccepts(accepts); col.setAccepts(accepts);

View file

@ -19,18 +19,17 @@ package org.rometools.propono.atom.server;
import java.util.logging.ConsoleHandler; import java.util.logging.ConsoleHandler;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import junit.framework.Test; import junit.framework.Test;
import junit.framework.TestSuite; import junit.framework.TestSuite;
import org.mortbay.http.HttpContext; import org.mortbay.http.HttpContext;
import org.mortbay.http.HttpServer; import org.mortbay.http.HttpServer;
import org.mortbay.http.SocketListener; import org.mortbay.http.SocketListener;
import org.mortbay.jetty.servlet.ServletHandler; import org.mortbay.jetty.servlet.ServletHandler;
/** /**
* Test Propono Atom Client against Atom Server via Jetty. Extends * Test Propono Atom Client against Atom Server via Jetty. Extends <code>AtomClientTest</code> to start Jetty server, run tests and then stop the Jetty server.
* <code>AtomClientTest</code> to start Jetty server, run tests and then stop
* the Jetty server.
*/ */
public class AtomClientServerTest { // extends AtomClientTest { public class AtomClientServerTest { // extends AtomClientTest {
@ -40,8 +39,8 @@ public class AtomClientServerTest { // extends AtomClientTest {
public static final String USERNAME = "admin"; public static final String USERNAME = "admin";
public static final String PASSWORD = "admin"; public static final String PASSWORD = "admin";
public AtomClientServerTest(String s) { public AtomClientServerTest(final String s) {
//super(s); // super(s);
} }
public String getEndpoint() { public String getEndpoint() {
@ -57,7 +56,7 @@ public class AtomClientServerTest { // extends AtomClientTest {
} }
public static Test suite() { public static Test suite() {
TestSuite suite = new TestSuite(AtomClientServerTest.class); final TestSuite suite = new TestSuite(AtomClientServerTest.class);
return suite; return suite;
} }
@ -66,14 +65,14 @@ public class AtomClientServerTest { // extends AtomClientTest {
} }
protected void setUp() throws Exception { protected void setUp() throws Exception {
ConsoleHandler handler = new ConsoleHandler(); final ConsoleHandler handler = new ConsoleHandler();
Logger logger = Logger.getLogger("com.sun.syndication.propono"); final Logger logger = Logger.getLogger("com.sun.syndication.propono");
logger.setLevel(Level.FINEST); logger.setLevel(Level.FINEST);
logger.addHandler(handler); logger.addHandler(handler);
setupServer(); setupServer();
HttpContext context = createContext(); final HttpContext context = createContext();
ServletHandler servlets = createServletHandler(); final ServletHandler servlets = createServletHandler();
context.addHandler(servlets); context.addHandler(servlets);
server.addContext(context); server.addContext(context);
server.start(); server.start();
@ -88,24 +87,20 @@ public class AtomClientServerTest { // extends AtomClientTest {
server = new HttpServer(); server = new HttpServer();
// Create a port listener // Create a port listener
SocketListener listener = new SocketListener(); final SocketListener listener = new SocketListener();
listener.setPort(TESTPORT); listener.setPort(TESTPORT);
server.addListener(listener); server.addListener(listener);
} }
private ServletHandler createServletHandler() { private ServletHandler createServletHandler() {
System.setProperty( System.setProperty("com.sun.syndication.propono.atom.server.AtomHandlerFactory", "com.sun.syndication.propono.atom.server.TestAtomHandlerFactory");
"com.sun.syndication.propono.atom.server.AtomHandlerFactory", final ServletHandler servlets = new ServletHandler();
"com.sun.syndication.propono.atom.server.TestAtomHandlerFactory"); servlets.addServlet("app", "/app/*", "com.sun.syndication.propono.atom.server.AtomServlet");
ServletHandler servlets = new ServletHandler();
servlets.addServlet(
"app", "/app/*",
"com.sun.syndication.propono.atom.server.AtomServlet");
return servlets; return servlets;
} }
private HttpContext createContext() { private HttpContext createContext() {
HttpContext context = new HttpContext(); final HttpContext context = new HttpContext();
context.setContextPath("/rome/*"); context.setContextPath("/rome/*");
return context; return context;
} }
@ -118,5 +113,3 @@ public class AtomClientServerTest { // extends AtomClientTest {
} }
} }
} }

View file

@ -16,14 +16,13 @@
*/ */
package org.rometools.propono.atom.server; package org.rometools.propono.atom.server;
import org.rometools.propono.atom.server.AtomHandlerFactory;
import org.rometools.propono.atom.server.AtomHandler;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
public class TestAtomHandlerFactory extends AtomHandlerFactory { public class TestAtomHandlerFactory extends AtomHandlerFactory {
public AtomHandler newAtomHandler(HttpServletRequest req, HttpServletResponse res) { @Override
public AtomHandler newAtomHandler(final HttpServletRequest req, final HttpServletResponse res) {
return new TestAtomHandlerImpl(req, "build/testuploaddir"); return new TestAtomHandlerImpl(req, "build/testuploaddir");
} }
} }

View file

@ -16,16 +16,18 @@
*/ */
package org.rometools.propono.atom.server; package org.rometools.propono.atom.server;
import org.rometools.propono.atom.server.impl.FileBasedAtomHandler;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.rometools.propono.atom.server.impl.FileBasedAtomHandler;
public class TestAtomHandlerImpl extends FileBasedAtomHandler { public class TestAtomHandlerImpl extends FileBasedAtomHandler {
public TestAtomHandlerImpl(HttpServletRequest req, String uploaddir) { public TestAtomHandlerImpl(final HttpServletRequest req, final String uploaddir) {
super(req, uploaddir); super(req, uploaddir);
} }
public boolean validateUser( String loginId, String password ) {
return AtomClientServerTest.USERNAME.equals(loginId) @Override
&& AtomClientServerTest.PASSWORD.equals(password); public boolean validateUser(final String loginId, final String password) {
return AtomClientServerTest.USERNAME.equals(loginId) && AtomClientServerTest.PASSWORD.equals(password);
} }
} }

View file

@ -15,42 +15,39 @@
*/ */
package org.rometools.propono.blogclient; package org.rometools.propono.blogclient;
import org.rometools.propono.blogclient.BlogConnection;
import org.rometools.propono.blogclient.BlogResource;
import org.rometools.propono.blogclient.Blog;
import org.rometools.propono.blogclient.BlogConnectionFactory;
import org.rometools.propono.blogclient.BlogEntry;
import com.sun.syndication.io.impl.Atom10Parser;
import org.rometools.propono.utils.Utilities;
import java.io.File; import java.io.File;
import java.util.Iterator; import java.util.Iterator;
import junit.framework.Test; import junit.framework.Test;
import junit.framework.TestCase; import junit.framework.TestCase;
import junit.framework.TestSuite; import junit.framework.TestSuite;
import org.rometools.propono.utils.Utilities;
import com.sun.syndication.io.impl.Atom10Parser;
/** /**
* Tests Atom and MetaWeblog API CRUD via BlogClient. * Tests Atom and MetaWeblog API CRUD via BlogClient. Exclude this from automated tests because it requires a live blog server.
* Exclude this from automated tests because it requires a live blog server.
*/ */
public class SimpleBlogClientTest extends TestCase { public class SimpleBlogClientTest extends TestCase {
private String metaweblogEndpoint = "http://localhost:8080/roller/roller-services/xmlrpc"; private final String metaweblogEndpoint = "http://localhost:8080/roller/roller-services/xmlrpc";
//private String atomEndpoint = "http://localhost:8080/roller/roller-services/app"; // private String atomEndpoint = "http://localhost:8080/roller/roller-services/app";
private String atomEndpoint = "http://localhost:8080/sample-atomserver/app"; private final String atomEndpoint = "http://localhost:8080/sample-atomserver/app";
private String endpoint = "http://localhost:8080/atom-fileserver/app"; private final String endpoint = "http://localhost:8080/atom-fileserver/app";
private String username = "admin"; private final String username = "admin";
private String password = "admin"; private final String password = "admin";
public SimpleBlogClientTest(String testName) { public SimpleBlogClientTest(final String testName) {
super(testName); super(testName);
} }
@Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
} }
@Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
} }
@ -58,17 +55,16 @@ public class SimpleBlogClientTest extends TestCase {
testBlogClient("atom", atomEndpoint); testBlogClient("atom", atomEndpoint);
} }
public void testBlogClientMetaWeblog() throws Exception{ public void testBlogClientMetaWeblog() throws Exception {
testBlogClient("metaweblog", metaweblogEndpoint); testBlogClient("metaweblog", metaweblogEndpoint);
} }
public void testBlogClient(String type, String endpoint) throws Exception { public void testBlogClient(final String type, final String endpoint) throws Exception {
BlogConnection conn = BlogConnectionFactory final BlogConnection conn = BlogConnectionFactory.getBlogConnection(type, endpoint, username, password);
.getBlogConnection(type, endpoint, username, password);
int blogCount = 0; int blogCount = 0;
for (Iterator it = conn.getBlogs().iterator(); it.hasNext();) { for (final Iterator it = conn.getBlogs().iterator(); it.hasNext();) {
Blog blog = (Blog) it.next(); final Blog blog = (Blog) it.next();
System.out.println(blog.getName()); System.out.println(blog.getName());
blogCount++; blogCount++;
} }
@ -91,20 +87,19 @@ public class SimpleBlogClientTest extends TestCase {
testMediaPost("metaweblog", metaweblogEndpoint); testMediaPost("metaweblog", metaweblogEndpoint);
} }
public void testPostAndDelete(String type, String endpoint) throws Exception { public void testPostAndDelete(final String type, final String endpoint) throws Exception {
BlogConnection conn = BlogConnectionFactory final BlogConnection conn = BlogConnectionFactory.getBlogConnection(type, endpoint, username, password);
.getBlogConnection(type, endpoint, username, password);
assertNotNull(conn); assertNotNull(conn);
String title1 = "Test content"; final String title1 = "Test content";
String content1 = "Test content"; final String content1 = "Test content";
Blog blog = (Blog)conn.getBlogs().get(0); final Blog blog = (Blog) conn.getBlogs().get(0);
BlogEntry entry = blog.newEntry(); BlogEntry entry = blog.newEntry();
entry.setTitle(title1); entry.setTitle(title1);
entry.setContent(new BlogEntry.Content(content1)); entry.setContent(new BlogEntry.Content(content1));
entry.save(); entry.save();
String token = entry.getToken(); final String token = entry.getToken();
assertNotNull(token); assertNotNull(token);
entry = blog.getEntry(token); entry = blog.getEntry(token);
@ -119,7 +114,7 @@ public class SimpleBlogClientTest extends TestCase {
boolean notFound = false; boolean notFound = false;
try { try {
entry = blog.getEntry(token); entry = blog.getEntry(token);
} catch (Exception e) { } catch (final Exception e) {
notFound = true; notFound = true;
} }
assertTrue(notFound); assertTrue(notFound);
@ -128,30 +123,29 @@ public class SimpleBlogClientTest extends TestCase {
/** /**
* Post media entry to every media colletion avialable on server, then cleanup. * Post media entry to every media colletion avialable on server, then cleanup.
*/ */
public void testMediaPost(String type, String endpoint) throws Exception { public void testMediaPost(final String type, final String endpoint) throws Exception {
BlogConnection conn = BlogConnectionFactory final BlogConnection conn = BlogConnectionFactory.getBlogConnection(type, endpoint, username, password);
.getBlogConnection(type, endpoint, username, password);
assertNotNull(conn); assertNotNull(conn);
assertTrue(conn.getBlogs().size() > 0); assertTrue(conn.getBlogs().size() > 0);
int count = 0; int count = 0;
for (Iterator it = conn.getBlogs().iterator(); it.hasNext();) { for (final Iterator it = conn.getBlogs().iterator(); it.hasNext();) {
Blog blog = (Blog) it.next(); final Blog blog = (Blog) it.next();
assertNotNull(blog.getName()); assertNotNull(blog.getName());
for (Iterator colit = blog.getCollections().iterator(); colit.hasNext();) { for (final Iterator colit = blog.getCollections().iterator(); colit.hasNext();) {
Blog.Collection col = (Blog.Collection) colit.next(); final Blog.Collection col = (Blog.Collection) colit.next();
if (col.accepts("image/gif")) { if (col.accepts("image/gif")) {
// we found a collection that accepts GIF, so post one // we found a collection that accepts GIF, so post one
BlogResource m1 = col.newResource("duke"+count, "image/gif", final BlogResource m1 = col.newResource("duke" + count, "image/gif",
Utilities.getBytesFromFile(new File("test/testdata/duke-wave-shadow.gif"))); Utilities.getBytesFromFile(new File("test/testdata/duke-wave-shadow.gif")));
col.saveResource(m1); col.saveResource(m1);
if ("atom".equals(type)) { // additional tests for Atom if ("atom".equals(type)) { // additional tests for Atom
// entry should now exist on server // entry should now exist on server
BlogResource m2 = (BlogResource)blog.getEntry(m1.getToken()); final BlogResource m2 = (BlogResource) blog.getEntry(m1.getToken());
assertNotNull(m2); assertNotNull(m2);
// remove entry // remove entry
@ -161,7 +155,7 @@ public class SimpleBlogClientTest extends TestCase {
boolean failed = false; boolean failed = false;
try { try {
blog.getEntry(m1.getToken()); blog.getEntry(m1.getToken());
} catch (Exception e) { } catch (final Exception e) {
failed = true; failed = true;
} }
assertTrue(failed); assertTrue(failed);
@ -173,7 +167,6 @@ public class SimpleBlogClientTest extends TestCase {
assertTrue(count > 0); assertTrue(count > 0);
} }
public void testEntryIterationAtom() throws Exception { public void testEntryIterationAtom() throws Exception {
testEntryIteration("atom", atomEndpoint); testEntryIteration("atom", atomEndpoint);
} }
@ -182,39 +175,34 @@ public class SimpleBlogClientTest extends TestCase {
testEntryIteration("metaweblog", metaweblogEndpoint); testEntryIteration("metaweblog", metaweblogEndpoint);
} }
public void testEntryIteration(String type, String endpoint) throws Exception { public void testEntryIteration(final String type, final String endpoint) throws Exception {
BlogConnection conn = BlogConnectionFactory final BlogConnection conn = BlogConnectionFactory.getBlogConnection(type, endpoint, username, password);
.getBlogConnection(type, endpoint, username, password);
assertNotNull(conn); assertNotNull(conn);
String title1 = "Test content"; final String title1 = "Test content";
String content1 = "Test content"; final String content1 = "Test content";
Blog blog = (Blog)conn.getBlogs().get(0); final Blog blog = (Blog) conn.getBlogs().get(0);
for (int i=0; i<10; i++) { for (int i = 0; i < 10; i++) {
BlogEntry entry = blog.newEntry(); final BlogEntry entry = blog.newEntry();
entry.setTitle(title1); entry.setTitle(title1);
entry.setContent(new BlogEntry.Content(content1)); entry.setContent(new BlogEntry.Content(content1));
entry.save(); entry.save();
String token = entry.getToken(); final String token = entry.getToken();
assertTrue(Atom10Parser.isAbsoluteURI(token)); assertTrue(Atom10Parser.isAbsoluteURI(token));
assertNotNull(token); assertNotNull(token);
} }
for (Iterator it = blog.getEntries(); it.hasNext();) { for (final Iterator it = blog.getEntries(); it.hasNext();) {
BlogEntry blogEntry = (BlogEntry)it.next(); final BlogEntry blogEntry = (BlogEntry) it.next();
assertTrue(Atom10Parser.isAbsoluteURI(blogEntry.getToken())); assertTrue(Atom10Parser.isAbsoluteURI(blogEntry.getToken()));
blogEntry.delete(); blogEntry.delete();
} }
} }
public static Test suite() { public static Test suite() {
TestSuite suite = new TestSuite(SimpleBlogClientTest.class); final TestSuite suite = new TestSuite(SimpleBlogClientTest.class);
return suite; return suite;
} }
} }