diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..d5e94bc --- /dev/null +++ b/.classpath @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..4e9d92b --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + InformationCollector + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..21a9ec6 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,258 @@ +#Wed Aug 12 09:49:59 EDT 2009 +eclipse.preferences.version=1 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=true +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=100 +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=200 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=mixed +org.eclipse.jdt.core.formatter.tabulation.size=8 +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 0000000..28ba8a8 --- /dev/null +++ b/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,4 @@ +#Wed Aug 12 09:49:59 EDT 2009 +eclipse.preferences.version=1 +formatter_profile=_D4SConventions +formatter_settings_version=11 diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..98d224c --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,8 @@ + +v. 2.0.0 (30-08-2009) + * portTypes reorganization + * internal refactoring + * hot and cold backups + +v. 1.0.0 (10-01-2009) + * gCore refactoring diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..630ba97 --- /dev/null +++ b/LICENSE @@ -0,0 +1,6 @@ +gCube System - License +------------------------------------------------------------ + +The gCube/gCore software is licensed as Free Open Source software conveying to the EUPL (http://ec.europa.eu/idabc/eupl). +The software and documentation is provided by its authors/distributors "as is" and no expressed or +implied warranty is given for its use, quality or fitness for a particular case. diff --git a/MAINTAINERS b/MAINTAINERS new file mode 100644 index 0000000..b6b41a3 --- /dev/null +++ b/MAINTAINERS @@ -0,0 +1,3 @@ + +* Manuele Simi (manuele.simi@isti.cnr.it), CNR Pisa, + Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo". \ No newline at end of file diff --git a/README b/README new file mode 100755 index 0000000..c1abd5e --- /dev/null +++ b/README @@ -0,0 +1,54 @@ +The gCube System - ISRegistry +------------------------------------------------------------ + +This work is partially funded by the European Commission in the +context of the D4Science project (www.d4science.eu), under the 1st +call of FP7 IST priority. + + + +Authors +------- + +* Manuele Simi (manuele.simi@isti.cnr.it), CNR Pisa, + Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo". + + +Version and Release Date +------------------------ +v. 2.0.0 (30-08-2009) + +Description +----------- + + + Download information +-------------------- + +Source code is available from SVN: +http://svn.d4science.research-infrastructures.eu/gcube/trunk/ + +Binaries can be downloaded from: +http://software.d4science.research-infrastructures.eu/ + + +Documentation +------------- +Documentation is available on-line from the Projects Documentation Wiki: + +https://technical.wiki.d4science.research-infrastructures.eu/documentation/index.php/ + +Licensing +--------- + +This software is licensed under the terms you may find in the file named "LICENSE" in this directory. + + +Third Party Software License Notice +------------------------------------ + +This product includes software developed by: +* The Apache Software Foundation (http://www.apache.org/). +* eXist XML Database: released to the public under the terms of the GNU LGPL license (http://www.gnu.org/copyleft/lesser.html). + + diff --git a/build.xml b/build.xml new file mode 100755 index 0000000..d3ab722 --- /dev/null +++ b/build.xml @@ -0,0 +1,554 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/design/D4S-InformationCollector.vpp b/design/D4S-InformationCollector.vpp new file mode 100644 index 0000000..2ee29de Binary files /dev/null and b/design/D4S-InformationCollector.vpp differ diff --git a/design/IC skeleton.png b/design/IC skeleton.png new file mode 100644 index 0000000..ff79acd Binary files /dev/null and b/design/IC skeleton.png differ diff --git a/design/StorageAndDocSchema.txt b/design/StorageAndDocSchema.txt new file mode 100755 index 0000000..e31ace2 --- /dev/null +++ b/design/StorageAndDocSchema.txt @@ -0,0 +1,172 @@ + +1) DB COLLECTIONS organization: + + +/db (root collection) +| +|-Properties +| +|-Profiles + | + |-RunningInstance + |-GHN + |-Service + |-ExternalRunningInstance + |-CS + |-CSInstance + |-Collection + |-MetadataCollection + |-GenericResource + + +2) DOCUMENT STRUCTURE + + + + internal document identifier + EPR of the RI + info di gestione + info di gestione + expire date from the epoc + human readable version + last update time from the peco + human readable version + + (the list of ws-resourceproperties + or + the profile) + + + gCube Provider properties + + + +Example: + + + 247246288042653 + http://node6.d.d4science.research-infrastructures.eu:8080/wsrf/services/gcube/informationsystem/registry/RegistryFactory + RegistryResource + + RegistryResource + + 8042653 + 24724628 + 1250529645842 + Mon Aug 17 18:20:45 GMT+01:00 2009 + 1250529525976 + Mon Aug 17 18:18:45 GMT+01:00 2009 + + + 537ff150-8b4d-11de-a789-cac4f8c904e3 + create + 2009-08-17T16:45:10.945Z + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1ab13550-8aad-11de-a0b8-daa6294f6796 + update + 2009-08-17T17:18:35.079Z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2009-08-17T17:18:46.068Z + 1ab13550-8aad-11de-a0b8-daa6294f6796 + 1d1eb2e0-8aad-11de-a0ba-daa6294f6796 + InformationSystem + /CNRPrivate + 1d1d5350-8aad-11de-a0ba-daa6294f6796 + IS-Registry + + + +3) QUERIES: + + +the resultset has the following structure: + + + + ... + + + ... + + + ... + + + +XQuery samples: + +for $name in //Document/Data/[ServiceName &= 'ISRegistry'] +return + + ..... + + + +for $name in collection("/db/Properties")//Document/Data/[ServiceName &= 'ISRegistry'] +return + + ..... + + + diff --git a/etc/build.properties b/etc/build.properties new file mode 100755 index 0000000..cd6807e --- /dev/null +++ b/etc/build.properties @@ -0,0 +1,13 @@ + +package = org.gcube.informationsystem.collector +lib.dir = Dependencies/ISIC +wsdl.1 = XMLCollectionAccess +wsdl.2 = Sink_service +wsdl.3 = SinkEntry_service +namespace.1=http://gcube-system.org/namespaces/informationsystem/collector +namespace.2=http://gcube-system.org/namespaces/informationsystem/collector/Sink +namespace.3=http://mds.globus.org/index/2004/07/12 +namespace.4=http://gcube-system.org/namespaces/informationsystem/collector/XMLCollectionAccess +namespace.5=http://gcube-system.org/namespaces/informationsystem/collector/XQueryAccess +namespace.6=http://gcube-system.org/namespaces/informationsystem/collector/XMLStorageAccess + diff --git a/etc/deploy-jndi-config.xml b/etc/deploy-jndi-config.xml new file mode 100755 index 0000000..357f59d --- /dev/null +++ b/etc/deploy-jndi-config.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + factory + + + org.globus.wsrf.jndi.BeanFactory + + + + + entrySweeperInterval + + + 480000 + + + + + entryRemovedCallback + + + org.gcube.informationsystem.collector.impl.state.ICAggregatorRemoveCallback + + + + aggregatorSources + org.globus.mds.aggregator.impl.QueryAggregatorSource + org.globus.mds.aggregator.impl.SubscriptionAggregatorSource + org.globus.mds.aggregator.impl.ExecutionAggregatorSource + + + + + + + + + + + + + + + + + + + + + + factory + + + org.globus.wsrf.jndi.BeanFactory + + + + resourceClass + org.gcube.informationsystem.collector.impl.state.AggregatorRegisteredResource + + + + + + + + + + + + + + + + factory + + + org.globus.wsrf.jndi.BeanFactory + + + + + + + + + diff --git a/etc/deploy-server.wsdd b/etc/deploy-server.wsdd new file mode 100755 index 0000000..ac5a4b7 --- /dev/null +++ b/etc/deploy-server.wsdd @@ -0,0 +1,63 @@ + + + + + + + + + + + + share/schema/org.gcube.informationsystem.collector/XMLCollectionAccess_service.wsdl + + + + + + + + + + + + share/schema/org.gcube.informationsystem.collector/SinkEntry_service.wsdl + + + + + + + + + + + share/schema/org.gcube.informationsystem.collector/Sink_service.wsdl + + + + diff --git a/etc/profile.xml b/etc/profile.xml new file mode 100644 index 0000000..7210b62 --- /dev/null +++ b/etc/profile.xml @@ -0,0 +1,69 @@ + + + + Service + + Information Collector service: collect and made available information related to the actual state of a gCube infrastructure and/or of an assigned subset of it + InformationSystem + IS-Collector + 1.0.0 + + +
+ Information Collector service: it acts at an aggregator + sink by collecting and exposing the information published by the + registered gCube services + IS-Collector-service + 2.0.0 + + + + InformationSystem + IS-Collector + 1.0.0 + + IS-Collector-stubs + [2.0.0] + + false + + + org.gcube.informationsystem.collector.gar + + + gcube/informationsystem/collector/Sink + + + + + gcube/informationsystem/collector/SinkEntry + + + + + gcube/informationsystem/collector/XMLCollectionAccess + + + +
+ + InformationCollector Stubs + IS-Collector-stubs + 2.0.0 + + + + library + + org.gcube.informationsystem.collector.stubs.jar + + +
+
+
diff --git a/etc/scripts/install.sh b/etc/scripts/install.sh new file mode 100755 index 0000000..a7b1511 --- /dev/null +++ b/etc/scripts/install.sh @@ -0,0 +1,24 @@ +#! /bin/sh + +#wget --no-check-certificate https://elibrary.isti.cnr.it/svn_public/diligent_GAR/ExternalDependencies/eXist/eXist-1.0rc2.jar + +java -jar ./eXist-1.0rc2.jar -p ~/exist + +export EXIST_HOME=~/exist + +export GLOBUS_OPTIONS="-Dexist.home=$EXIST_HOME $GLOBUS_OPTIONS" + +ln -s $EXIST_HOME/exist.jar $GLOBUS_LOCATION/lib/ + +ln -s $EXIST_HOME/lib/core/xmldb.jar $GLOBUS_LOCATION/lib/ + +ln -s $EXIST_HOME/lib/core/commons-pool-1.2.jar $GLOBUS_LOCATION/lib/ + +ln -s $EXIST_HOME/lib/core/xmlrpc-1.2-patched.jar $GLOBUS_LOCATION/lib/ + +ln -s $EXIST_HOME/lib/core/antlr.jar $GLOBUS_LOCATION/lib/ + +. ${GLOBUS_LOCATION}/etc/globus-devel-env.sh + +#rm -rf ./eXist-1.0rc2.jar + diff --git a/etc/scripts/install1.1.sh b/etc/scripts/install1.1.sh new file mode 100755 index 0000000..2036cf2 --- /dev/null +++ b/etc/scripts/install1.1.sh @@ -0,0 +1,27 @@ +#! /bin/sh + +#wget --no-check-certificate http://grids17.eng.it/engrepository/exist/1.1.1/noarch/eXist-1.1.1-newcore-build4311.tar.gz + +tar zxvf eXist-1.1.1-newcore-build4311.tar.gz + + +java -jar ./eXist-1.1.1-newcore-build4311.jar -p ~/exist1.1 + +export EXIST_HOME=~/exist1.1 + +export GLOBUS_OPTIONS="-Dexist.home=$EXIST_HOME $GLOBUS_OPTIONS" + +ln -sf $EXIST_HOME/exist.jar $GLOBUS_LOCATION/lib/ + +ln -sf $EXIST_HOME/lib/core/xmldb.jar $GLOBUS_LOCATION/lib/ + +ln -sf $EXIST_HOME/lib/core/commons-pool-1.2.jar $GLOBUS_LOCATION/lib/ + +ln -sf $EXIST_HOME/lib/core/xmlrpc-1.2-patched.jar $GLOBUS_LOCATION/lib/ + +ln -sf $EXIST_HOME/lib/core/antlr-2.7.6.jar $GLOBUS_LOCATION/lib/ + +. ${GLOBUS_LOCATION}/etc/globus-devel-env.sh + +rm -rf ./eXist-1.1.1-newcore-build4311.jar + diff --git a/etc/scripts/reboot.sh b/etc/scripts/reboot.sh new file mode 100755 index 0000000..f05b7b0 --- /dev/null +++ b/etc/scripts/reboot.sh @@ -0,0 +1,7 @@ +#! /bin/sh + +export EXIST_HOME=~/exist1.1 + +export GLOBUS_OPTIONS="-Dexist.home=$EXIST_HOME $GLOBUS_OPTIONS" + + diff --git a/schema/SinkEntry_service.wsdl b/schema/SinkEntry_service.wsdl new file mode 100755 index 0000000..95e9913 --- /dev/null +++ b/schema/SinkEntry_service.wsdl @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Service Entry + + + + + + diff --git a/schema/Sink_service.wsdl b/schema/Sink_service.wsdl new file mode 100755 index 0000000..579bd36 --- /dev/null +++ b/schema/Sink_service.wsdl @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Information Collector Sink PortType + + + + + + diff --git a/schema/Sink_service_bindings.wsdl b/schema/Sink_service_bindings.wsdl new file mode 100644 index 0000000..82a0e0f --- /dev/null +++ b/schema/Sink_service_bindings.wsdl @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/schema/Sink_service_flattened.wsdl b/schema/Sink_service_flattened.wsdl new file mode 100644 index 0000000..1eb0798 --- /dev/null +++ b/schema/Sink_service_flattened.wsdl @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/schema/XMLCollectionAccess.wsdl b/schema/XMLCollectionAccess.wsdl new file mode 100755 index 0000000..2a7ab2b --- /dev/null +++ b/schema/XMLCollectionAccess.wsdl @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/org/gcube/informationsystem/collector/impl/contexts/ICServiceContext.java b/src/org/gcube/informationsystem/collector/impl/contexts/ICServiceContext.java new file mode 100644 index 0000000..95583a9 --- /dev/null +++ b/src/org/gcube/informationsystem/collector/impl/contexts/ICServiceContext.java @@ -0,0 +1,53 @@ +package org.gcube.informationsystem.collector.impl.contexts; + +import org.gcube.common.core.contexts.GCUBEServiceContext; +import org.gcube.informationsystem.collector.impl.xmlstorage.exist.State; + +/** + * + * Information Collector's service context + * + * @author Manuele Simi (ISTI-CNR) + * + */ +public class ICServiceContext extends GCUBEServiceContext { + + + /** singleton instance of IC context*/ + protected static final ICServiceContext cache = new ICServiceContext(); + + private ICServiceContext() {} + + /** + * @return the service context + */ + public static ICServiceContext getContext() { + return cache; + } + + /** {@inheritDoc} */ + @Override + protected String getJNDIName() { + return "gcube/informationsystem/collector"; + } + + + /** {@inheritDoc} */ + @Override + protected void onInitialisation() throws Exception { + State.initialize(); + } + + /** {@inheritDoc} */ + @Override + protected void onReady() throws Exception { + + } + + /** {@inheritDoc} */ + @Override + protected void onShutdown() throws Exception { + State.dispose(); + } + +} diff --git a/src/org/gcube/informationsystem/collector/impl/persistence/AggregatorPersistentResource.java b/src/org/gcube/informationsystem/collector/impl/persistence/AggregatorPersistentResource.java new file mode 100755 index 0000000..881016b --- /dev/null +++ b/src/org/gcube/informationsystem/collector/impl/persistence/AggregatorPersistentResource.java @@ -0,0 +1,482 @@ +package org.gcube.informationsystem.collector.impl.persistence; + +import org.gcube.common.core.utils.logging.GCUBELog; +import org.gcube.informationsystem.collector.impl.persistence.AggregatorPersistentResource; +import org.gcube.informationsystem.collector.impl.xmlstorage.exist.State; + +import org.xmldb.api.modules.XMLResource; +import org.xmldb.api.base.XMLDBException; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.StringReader; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +import java.lang.Exception; + +import org.w3c.dom.*; + +import org.xml.sax.InputSource; + +import javax.xml.parsers.*; +import javax.xml.xpath.*; + +/** + * AggregatorPersistentResource represents a resource in the XML Storage + * repository + * + * @author Manuele Simi (ISTI-CNR) + * + */ + +public class AggregatorPersistentResource extends PersistentResource { + + private String resourceID = null; + + private String resource_string = null; + + // the resource type states if the resource contains a profile or generic + // WS-ResourceProperties + private RESOURCETYPE type = null; + + // the profile type states which kind of profiles the resource contains + // (RunningInstance, Service, etc.) + private String profile_type = null; + + // the various parts of the resource + private String data, /* service_class, service_id, ri_id, ghn_id, scope, */ + entryKey, groupKey, source, sourceKey = "", completeSourceKey = ""; + + private Calendar terminationTime = null, lastUpdateTime = null; + + private static GCUBELog logger = new GCUBELog( + AggregatorPersistentResource.class); + + // the source XMLResource (if any) + private XMLResource originalSource = null; + + // the XML DOM loaded from the resource string + private Document internalDOM = null; + + // xpath factory to evaluate Xpath expressions + private XPath path = XPathFactory.newInstance().newXPath(); + + /** + * Builds a new empty DISPersinstentresource + * + */ + public AggregatorPersistentResource() { + + // defatult termination time is now + Calendar cal = new GregorianCalendar(); + cal.setTimeZone(TimeZone.getTimeZone("GMT")); + this.setTerminationTime(cal); + + lastUpdateTime = new GregorianCalendar(); + lastUpdateTime.setTimeZone(TimeZone.getTimeZone("GMT")); + } + + /** + * Builds a DISPersinstentresource starting from an eXist resource + * + * @param resource + * the input eXist resource + * @throws Exception + * if the resource is invalid + */ + public AggregatorPersistentResource(XMLResource resource) throws Exception { + try { + this.resourceID = resource.getId(); + this.originalSource = resource; + this.resource_string = resource.getContent().toString(); + this.parseResource(); + } catch (XMLDBException dbe) { + throw new Exception("invalid resource"); + } + } + + /** + * Sets the content of the resource + * + * @param data + * the new content + * + */ + public void setData(String data) { + this.data = data; + } + + /** + * Sets the content of the resource using the content of a file + * + * @param f + * the file to use as content source + * + * @throws IOException + * if the access to the given file fails + * + */ + public void setData(File f) throws IOException { + try { + FileInputStream fin = new FileInputStream(f); + this.data = fin.toString(); + } catch (IOException ioe) { + System.out.print(State.logPrefix + + "unable to set content from file " + f.getAbsolutePath()); + throw ioe; + } + } + + /** + * Accesses the resource content + * + * @return the content + */ + public String getData() { + return this.data; + } + + /** + * + * @return the original XMLResource from which the resource has been + * generated (if any) + */ + public XMLResource getOriginalXMLResource() { + return this.originalSource; + } + + /** + * Accesses the resource ID + * + * @return the ID + */ + public String getID() { + + // create a unique ID unless the resource contains a profile + if (this.resourceID == null) + this.resourceID = this.getGroupKey() + this.getEntryKey(); + + return this.resourceID; + } + + /** + * Accesses the source GroupKey + * + * @return the ID + */ + public String getGroupKey() { + return this.groupKey; + } + + /** + * Sets the source GroupKey + * + * @param groupKey + * the new group key + * + */ + public void setGroupKey(String groupKey) { + this.groupKey = groupKey; + } + + /** + * Accesses the source EntryKey + * + * @return the ID + */ + public String getEntryKey() { + return this.entryKey; + } + + /** + * Sets the source EntryKey + * + * @param entryKey + * the new entry key + */ + public void setEntryKey(String entryKey) { + this.entryKey = entryKey; + } + + /** + * Sets the source address of the RI that publishes resource as reported in + * the servicegroup entry + * + * @param source + * the new source address + */ + public void setSource(String source) { + this.source = source; + } + + /** + * Accesses the source address of the service that published the data + * + * @return the source + */ + public String getSource() { + return this.source; + } + + /** + * Sets the key of the WS-Resource that published the data + * + * @param key + * the new source key + */ + public void setSourceKey(String key) { + this.sourceKey = key; + } + + /** + * Gets the key of the WS-Resource that published the data + * + * @return the key + */ + public String getSourceKey() { + return this.sourceKey; + } + + /** + * Sets the complete source key + * + * @param completeKey + * the new complete key + */ + public void setCompleteSourceKey(String completeKey) { + this.completeSourceKey = completeKey; + } + + /** + * Gets the complete source key + * + * @return the complete source key + */ + public String getCompleteSourceKey() { + return this.completeSourceKey; + } + + /** + * Sets the resource type. The actual implementation supports "Profile" and + * "Properties" as type + * + * @param type + * "Profile" or "Properties" + */ + + public void setType(RESOURCETYPE type) { + this.type = type; + } + + /** + * Accesses the resource type. The actual implementation supports "Profile" + * and "Properties" as type + * + * @return the type + */ + public RESOURCETYPE getType() { + return this.type; + } + + /** + * Updates the resource body + * + * @param data + * the new body + * + */ + public void updateData(String data) { + this.data = data; + } + + /** + * Builds a XML representation of the resource + * + * @return a String in the form of <Document>... <Data> resource + * content </Data> </Document> + */ + private String toXML() { + + String rep = "\n"; + rep += "" + this.getID() + "\n"; + rep += "" + this.getSource() + "\n"; + rep += "" + this.getSourceKey() + "\n"; + rep += "" + this.getCompleteSourceKey() + + "\n"; + rep += "" + this.getEntryKey() + "\n"; + rep += "" + this.getGroupKey() + "\n"; + rep += "" + + this.getTerminationTime().getTimeInMillis() + + "\n"; + rep += "" + + this.getTerminationTime().getTime().toString() + + "\n"; + rep += "" + this.lastUpdateTime.getTimeInMillis() + + "\n"; + rep += "" + this.lastUpdateTime.getTime().toString() + + "\n"; + rep += this.getData() + "\n"; + rep += "\n"; + return rep; + } + + /** + * + * @return a String representation of the resource + */ + public String toString() { + if (this.resource_string == null) + return this.toXML(); + else + return this.resource_string; + } + + /** + * Accesses the type of resource to which the profile is related to (if any) + * + * @return null if the resource does not contain a profile + */ + public String getProfileType() { + if (this.profile_type != null) { + // the profile type has been already extracted + return this.profile_type; + } + + if ((this.type != null) && (type == RESOURCETYPE.Profile)) { + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + StringReader reader = new StringReader(this.toXML()); + InputSource source = new InputSource(reader); + Document internalDOM = builder.parse(source); + // gets the type + XPath path = XPathFactory.newInstance().newXPath(); + this.profile_type = path + .evaluate( + "/Document/Data/child::*[local-name()='Profile']/Resource/Type", + internalDOM); + // uses the DILIGENT ID as resource ID + this.resourceID = path + .evaluate( + "/Document/Data/child::*[local-name()='Profile']/Resource/ID", + internalDOM); + + } catch (Exception e) { + logger + .error(State.logPrefix + + "Unable to extract the profile type from the resource " + + e.getMessage()); + + } + } + return this.profile_type; + } + + /** + * @return the terminationTime of this resource + */ + public Calendar getTerminationTime() { + return terminationTime; + } + + /** + * @param terminationTime + * the terminationTime to set + */ + public void setTerminationTime(Calendar terminationTime) { + this.terminationTime = (Calendar) terminationTime.clone(); + this.terminationTime.setTimeZone(TimeZone.getTimeZone("GMT")); + } + + /** + * Compares two resources + * + * @param o + * the resource to compare + * @return true if the resources have the same ID + */ + public boolean equals(Object o) { + // check the class this object is instance of + if (!(o instanceof AggregatorPersistentResource)) + return false; + // compare the two objects + AggregatorPersistentResource key = (AggregatorPersistentResource) o; + if (key.getID() == this.getID()) + return true; + else + return false; + } + + /** + * @return the lastUpdateTime in milliseconds + * @throws Exception if an error occurs when accessing the LastUpdateMs field + */ + public long getLastUpdateTimeinMills() throws Exception { + + if (lastUpdateTime != null) + return lastUpdateTime.getTimeInMillis(); + + if ((lastUpdateTime == null) && (this.internalDOM != null)) { + String value = ""; + try { + value = path.evaluate("Document/LastUpdateMs", this.internalDOM); + } catch (XPathExpressionException xpee) { + logger.error(State.logPrefix + "" + xpee.getMessage()); + logger.error(State.logPrefix + "" + xpee.getStackTrace()); + throw new Exception("XPath evaluation error"); + } + try { + return Long.parseLong(value); + } catch (NumberFormatException nfe) { + logger.error("Invalid last update time format found in resource " + this.getID()); + logger.error("Parsed string was " + value); + throw new Exception("Unable to retrieve last update time for resource " + this.getID()); + } + + } else + throw new Exception("unable to retrieve last update time for resource " + this.getID()); + + } + + /** + * Loads the XML DOM from the resource string + * + */ + private void parseResource() throws Exception { + logger.debug("Parsing resource: " + this.resource_string); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + StringReader reader = new StringReader(this.resource_string); + InputSource source = new InputSource(reader); + this.internalDOM = builder.parse(source); + + } + + /* + * (non-Javadoc) + * + * @see + * org.gcube.informationsystem.collector.impl.persistence.PersistentResource + * #getPublisher() + */ + @Override + public String getPublisher() { + return null; + } + + + /* + * (non-Javadoc) + * + * @see + * org.gcube.informationsystem.collector.impl.persistence.PersistentResource + * #setPublisher(java.lang.String) + */ + @Override + public void setPublisher(String publisher) { + + } +} diff --git a/src/org/gcube/informationsystem/collector/impl/persistence/PersistentResource.java b/src/org/gcube/informationsystem/collector/impl/persistence/PersistentResource.java new file mode 100644 index 0000000..9a7ab1d --- /dev/null +++ b/src/org/gcube/informationsystem/collector/impl/persistence/PersistentResource.java @@ -0,0 +1,98 @@ +package org.gcube.informationsystem.collector.impl.persistence; + +/** + * A resource handled by the XML repository + * + * @author Manuele Simi (ISTI-CNR) + * + */ +public abstract class PersistentResource { + + public enum RESOURCETYPE { + Profile, Properties + } + + protected String id; + + /** + * Gets the resource ID + * + * @return the ID + */ + public abstract String getID(); + + /** + * @return a String representation of the resource + */ + public abstract String toString(); + + /** + * Gets the resource type. + * + * @return the resource type + */ + public abstract RESOURCETYPE getType(); + + /** + * Gets the resource profile type, if any + * + * @return the resource profile type + * @throws Exception + * if the resource has no profile type (i.e. it is not a + * profile) + */ + public abstract String getProfileType() throws Exception; + + /** + * Gets the publisher of the resource + * + * @return the publisher + */ + public abstract String getPublisher(); + + /** + * Sets the resource's publisher + * + * @param publisher + * the publisher + */ + public abstract void setPublisher(String publisher); + + /** + * @return + * @throws Exception + */ + public abstract long getLastUpdateTimeinMills() throws Exception; + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + PersistentResource other = (PersistentResource) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } + +} diff --git a/src/org/gcube/informationsystem/collector/impl/porttypes/Sink.java b/src/org/gcube/informationsystem/collector/impl/porttypes/Sink.java new file mode 100755 index 0000000..8e8c480 --- /dev/null +++ b/src/org/gcube/informationsystem/collector/impl/porttypes/Sink.java @@ -0,0 +1,84 @@ +package org.gcube.informationsystem.collector.impl.porttypes; + +import java.util.Calendar; + +import org.globus.wsrf.ResourceLifetime; +import org.globus.wsrf.ResourceProperties; +import org.globus.wsrf.ResourceProperty; +import org.globus.wsrf.ResourcePropertySet; +import org.globus.wsrf.impl.ReflectionResourceProperty; +import org.globus.wsrf.impl.SimpleResourcePropertyMetaData; +import org.globus.wsrf.impl.SimpleResourcePropertySet; + +import org.gcube.common.core.utils.logging.GCUBELog; + +/** + * Sink PortType's implementation class. It's the registration PortType + * for all the Aggregator Sources. + * + * @author Manuele Simi (ISTI-CNR) + * + */ +public class Sink implements ResourceLifetime, ResourceProperties { + + // WS-Lifetime Properties + protected Calendar terminationTime, currentTime; + + private final GCUBELog logger = new GCUBELog(Sink.class); + + private ResourcePropertySet propSet; + + /** + * Initializes a new Sink PortType by creating its + * {@link SimpleResourcePropertySet} + * + */ + public Sink() { + this.propSet = new SimpleResourcePropertySet(XMLCollectionAccess.RP_SET); + ResourceProperty prop = null; + try { + // ResourceLifeTime properties + prop = new ReflectionResourceProperty(SimpleResourcePropertyMetaData.TERMINATION_TIME, this); + this.propSet.add(prop); + prop = new ReflectionResourceProperty( SimpleResourcePropertyMetaData.CURRENT_TIME, this); + this.propSet.add(prop); + this.propSet.add(prop); + } catch (Exception e) { + logger.error("An error occurred during the Sink resource creation", e); + } + } + + /** + * + * {@inheritDoc} + */ + public Calendar getCurrentTime() { + return Calendar.getInstance(); + } + + /** + * + * {@inheritDoc} + */ + public Calendar getTerminationTime() { + return this.terminationTime; + } + + /** + * + * {@inheritDoc} + */ + public void setTerminationTime(Calendar time) { + this.terminationTime = time; + + } + + /** + * + * {@inheritDoc} + */ + public ResourcePropertySet getResourcePropertySet() { + return this.propSet; + } + +} diff --git a/src/org/gcube/informationsystem/collector/impl/porttypes/SinkEntry.java b/src/org/gcube/informationsystem/collector/impl/porttypes/SinkEntry.java new file mode 100755 index 0000000..5caa9f1 --- /dev/null +++ b/src/org/gcube/informationsystem/collector/impl/porttypes/SinkEntry.java @@ -0,0 +1,50 @@ + +package org.gcube.informationsystem.collector.impl.porttypes; + +import java.rmi.RemoteException; +import java.util.Calendar; + +import javax.xml.namespace.QName; +import org.oasis.wsrf.properties.ResourceUnknownFaultType; +import org.oasis.wsrf.properties.InvalidResourcePropertyQNameFaultType; +import org.oasis.wsrf.properties.GetResourcePropertyResponse; +import org.oasis.wsrf.servicegroup.ServiceGroupEntry; +import org.globus.wsrf.impl.properties.GetResourcePropertyProvider; + + +/** + * A ServiceGroupEntry implemenation.
+ * It is used as base implementation both of the SinkEntry and of Entry portType. + * + * @author Manuele Simi (ISTI-CNR) + * + */ + +public class SinkEntry implements ServiceGroupEntry { + + private GetResourcePropertyProvider getResourcePropertyProvider = new GetResourcePropertyProvider(); + + + // WS-Lifetime Properties + protected Calendar terminationTime, currentTime; + + + /** + * Gets WS-Resource property by using the {@link GetResourcePropertyProvider} + * + * @param name the full qualified name of the property + * @return the resource property + * @throws RemoteException throws by the GetResourcePropertyProvider + * @throws InvalidResourcePropertyQNameFaultType throws by the GetResourcePropertyProvider + * @throws ResourceUnknownFaultType throws by the GetResourcePropertyProvider + * + */ + public GetResourcePropertyResponse getResourceProperty(QName name) + throws RemoteException, InvalidResourcePropertyQNameFaultType, ResourceUnknownFaultType { + + return getResourcePropertyProvider.getResourceProperty(name); + } + + +} + diff --git a/src/org/gcube/informationsystem/collector/impl/porttypes/XMLCollectionAccess.java b/src/org/gcube/informationsystem/collector/impl/porttypes/XMLCollectionAccess.java new file mode 100755 index 0000000..27c7231 --- /dev/null +++ b/src/org/gcube/informationsystem/collector/impl/porttypes/XMLCollectionAccess.java @@ -0,0 +1,252 @@ +package org.gcube.informationsystem.collector.impl.porttypes; + + +import javax.xml.namespace.QName; + +import org.oasis.wsrf.faults.BaseFaultType; + +import org.gcube.common.core.contexts.GCUBEServiceContext; +import org.gcube.common.core.porttypes.GCUBEPortType; +import org.gcube.common.core.utils.logging.GCUBELog; +import org.gcube.informationsystem.collector.impl.contexts.ICServiceContext; +import org.gcube.informationsystem.collector.impl.xmlstorage.exist.State; +import org.gcube.informationsystem.collector.impl.xmlstorage.exist.Sweeper; +import org.gcube.informationsystem.collector.impl.xmlstorage.exist.XQuery; +import org.gcube.informationsystem.collector.stubs.DeleteProfileParams; + +import org.globus.wsrf.utils.FaultHelper; + +import org.xmldb.api.base.ResourceSet; +import org.xmldb.api.modules.XMLResource; + +/** + * State service implementation class + * + * @author Manuele Simi (ISTI-CNR) + * + */ +public class XMLCollectionAccess extends GCUBEPortType { + + /** + * WS Properties namespace + */ + public static final QName RP_SET = new QName( + "http://gcube-system.org/namespaces/informationsystem/collector/XMLCollectionAccess", + "ICRP"); + + private final GCUBELog logger = new GCUBELog(XMLCollectionAccess.class); + + /** + * Executes the given XQuery on the embedded eXist DB instance + * + * @param xquery + * - a valid XQuery. It must be compliant with the syntax (with + * the exception of XML Schema-related features) as specified in + * W3C's recommendations outlined in the June 2006 candidate + * recommendation + * @return the result set wrapped in a <Resultset> tag. Each record is + * wrapped with a <Recordt> + * @throws BaseFaultType + * if the XQuery is not valid or the connection to eXist is + * broken + */ + public String executeXQuery(String xquery) throws BaseFaultType { + + StringBuilder response = new StringBuilder(); + try { + + logger.debug("executing XQuery: " + xquery); + + XQuery q = new XQuery(xquery); + ResourceSet result = State.query_manager.executeXQuery(q); + logger.debug("number of returned documents: " + result.getSize()); + response.append("\n"); + for (int i = 0; i < (int) result.getSize(); i++) { + XMLResource xmlres = (XMLResource) result.getResource((long) i); + // logger.debug("retrieved resource - " + xmlres.getContent()); + response.append("\n" + xmlres.getContent()+ "\n\n"); + } + response.append(""); + + } catch (Exception e) { + BaseFaultType fault = new BaseFaultType(); + FaultHelper faultHelper = new FaultHelper(fault); + faultHelper.addFaultCause(e); + faultHelper.addDescription("IC service: Exception when executing the requested XQuery"); + throw fault; + } + return response.toString(); + } + + /** + * Removes a profile from the Storage given its DILIGENT Resource ID + * + * @param params + * a stub class including private java.lang.String + * DILIGENTResourceID; the id of the profile to remove private + * java.lang.String profileType; the type of the profile to + * remove (e.g RunningInstance, DHN, Service, etc.); + * @return true if the resource is successfully deleted + * @throws BaseFaultType + * if the type parameter is not valid or an error occurs when + * deleting the profile + */ + + public boolean deleteProfile(DeleteProfileParams params) + throws BaseFaultType { + + boolean response = false; + String id = params.getID(); + String type = params.getProfileType(); + + if ((id == "") || (id == null)) { + logger.warn("invalid id"); + BaseFaultType fault = new BaseFaultType(); + FaultHelper faultHelper = new FaultHelper(fault); + faultHelper.addDescription("invalid id"); + throw fault; + } + + if ((type == "") || (type == null)) { + logger.warn("invalid profile type"); + BaseFaultType fault = new BaseFaultType(); + FaultHelper faultHelper = new FaultHelper(fault); + faultHelper.addDescription("invalid profile type"); + throw fault; + } + + try { + logger.debug("deleting profile " + id + " from collection " + type); + State.storage_manager.retrieveAndDeleteProfileFromID(id, type); + if (type.equalsIgnoreCase("RunningInstance")) + Sweeper.cleanResourceForRI(id); + + } catch (Exception e) { + logger.error("unable to remove resource: " + id, e); + BaseFaultType fault = new BaseFaultType(); + FaultHelper faultHelper = new FaultHelper(fault); + faultHelper.addFaultCause(e); + faultHelper + .addDescription("IC service: Exception when deleting the requested resource"); + throw fault; + } + return response; + } + + /** + * Removes a resource from the Storage given its ID + * + * @param id + * - the id of the resoure to remove + * @return true if the resource is successfully deleted + * @throws BaseFaultType + * if the id parameter is null or an error occurs when deleting + * the profile + */ + public boolean deleteResource(String id) throws BaseFaultType { + + boolean response = false; + + if ((id == "") || (id == null)) { + logger.warn("invalid id"); + BaseFaultType fault = new BaseFaultType(); + FaultHelper faultHelper = new FaultHelper(fault); + faultHelper.addDescription("invalid id"); + throw fault; + } + + try { + logger.debug("deleting resource: " + id); + State.storage_manager.retrieveAndDeleteResourceFromID(id); + } catch (Exception e) { + logger.error("unable to remove resource: " + id, e); + BaseFaultType fault = new BaseFaultType(); + FaultHelper faultHelper = new FaultHelper(fault); + faultHelper.addFaultCause(e); + faultHelper + .addDescription("IC service: Exception when deleting the requested resource"); + throw fault; + } + return response; + } + + /** + * Deletes the entire set of registered RPs from the storage + * + * @throws BaseFaultType + * if an error occurs when deleting the resources + */ + public void deleteAllRPs() throws BaseFaultType { + try { + logger.info("DeleteAllRPs operation invoked"); + Sweeper.cleanRPs(); + logger.info("All RPs have been deleted from the storage"); + } catch (Exception e) { + logger.error("unable to clean RPs collction: ", e); + BaseFaultType fault = new BaseFaultType(); + FaultHelper faultHelper = new FaultHelper(fault); + faultHelper.addFaultCause(e); + faultHelper.addDescription("IC service: Exception when deleting the requested resource"); + throw fault; + } + } + + /** + * Disposes the State service + * + * @throws BaseFaultType + * if the shutdown fails + */ + public void dispose() throws BaseFaultType { + try { + logger.info("Dispose operation invoked"); + logger.info("trying to shutdown the storage instances..."); + try { + State.storage_manager.shutdown(); + State.query_manager.shutdown(); + } catch (NullPointerException se) {/* nothng to do */ + } + State.storage_manager = null; + State.query_manager = null; + // request the interruption of the sweeper thread + State.sweeperT.interrupt(); + logger.info("done"); + } catch (Exception e) { + logger.error("unable to pose the IC with success ", e); + BaseFaultType fault = new BaseFaultType(); + FaultHelper faultHelper = new FaultHelper(fault); + faultHelper.addFaultCause(e); + faultHelper + .addDescription("-IC service: Unable to pose the service"); + throw fault; + } + } + + /** + * Initialized the State service + * + * @throws BaseFaultType + * if the initialization fails + */ + public void initialize() throws BaseFaultType { + + try { + logger.info("Initialize operation invoked"); + State.initialize(); + logger.info("done"); + } catch (Exception e) { + logger.error("Unable to initialize the IC state", e); + BaseFaultType fault = new BaseFaultType(); + FaultHelper faultHelper = new FaultHelper(fault); + faultHelper.addFaultCause(e); + faultHelper.addDescription("-IC service: Unable to initialize the service"); + throw fault; + } + } + + /** {@inheritDoc} */ + @Override + protected GCUBEServiceContext getServiceContext() { + return ICServiceContext.getContext(); + } +} diff --git a/src/org/gcube/informationsystem/collector/impl/porttypes/XMLStorageAccess.java b/src/org/gcube/informationsystem/collector/impl/porttypes/XMLStorageAccess.java new file mode 100644 index 0000000..aa979a2 --- /dev/null +++ b/src/org/gcube/informationsystem/collector/impl/porttypes/XMLStorageAccess.java @@ -0,0 +1,54 @@ +package org.gcube.informationsystem.collector.impl.porttypes; + +import org.globus.wsrf.utils.FaultHelper; +import org.oasis.wsrf.faults.BaseFaultType; + +import org.gcube.common.core.contexts.GCUBEServiceContext; +import org.gcube.common.core.porttypes.GCUBEPortType; +import org.gcube.informationsystem.collector.impl.contexts.ICServiceContext; +import org.gcube.informationsystem.collector.impl.xmlstorage.exist.State; + +/** + * TODO: Manuele, don't forget to add a comment for this new type!! + * + * @author Manuele Simi (ISTI-CNR) + * + */ +public class XMLStorageAccess extends GCUBEPortType { + + /** {@inheritDoc} */ + @Override + protected GCUBEServiceContext getServiceContext() { + return ICServiceContext.getContext(); + } + + /** + * Disposes the XMLStorage + * + * @throws BaseFaultType if the shutdown fails + */ + public void dispose() throws BaseFaultType { + try { + logger.info("Dispose operation invoked"); + logger.info("trying to shutdown the storage instances..."); + try { + State.storage_manager.shutdown(); + State.query_manager.shutdown(); + } catch (NullPointerException se) {/* nothng to do */ + } + State.storage_manager = null; + State.query_manager = null; + // request the interruption of the sweeper thread + State.sweeperT.interrupt(); + logger.info("done"); + } catch (Exception e) { + logger.error("unable to pose the IC with success ", e); + BaseFaultType fault = new BaseFaultType(); + FaultHelper faultHelper = new FaultHelper(fault); + faultHelper.addFaultCause(e); + faultHelper + .addDescription("-IC service: Unable to pose the service"); + throw fault; + } + } +} diff --git a/src/org/gcube/informationsystem/collector/impl/porttypes/XQueryAccess.java b/src/org/gcube/informationsystem/collector/impl/porttypes/XQueryAccess.java new file mode 100644 index 0000000..1dfc630 --- /dev/null +++ b/src/org/gcube/informationsystem/collector/impl/porttypes/XQueryAccess.java @@ -0,0 +1,26 @@ +package org.gcube.informationsystem.collector.impl.porttypes; + +import org.gcube.common.core.contexts.GCUBEServiceContext; +import org.gcube.common.core.porttypes.GCUBEPortType; +import org.gcube.informationsystem.collector.impl.contexts.ICServiceContext; + +/** + * XQueryAccess portType implementation + * + * @author Manuele Simi (ISTI-CNR) + * + */ +public class XQueryAccess extends GCUBEPortType { + + /** {@inheritDoc} */ + @Override + protected GCUBEServiceContext getServiceContext() { + return ICServiceContext.getContext(); + } + /* + public XQueryExecuteResponse XQueryExecute(XQueryExecuteRequest XQueryExecuteRequest) throw XQueryFaultType { + + }*/ + + +} diff --git a/src/org/gcube/informationsystem/collector/impl/state/AggregatorRegisteredResource.java b/src/org/gcube/informationsystem/collector/impl/state/AggregatorRegisteredResource.java new file mode 100755 index 0000000..593a373 --- /dev/null +++ b/src/org/gcube/informationsystem/collector/impl/state/AggregatorRegisteredResource.java @@ -0,0 +1,307 @@ +package org.gcube.informationsystem.collector.impl.state; + +import java.util.Calendar; + +import org.apache.axis.encoding.AnyContentType; +import org.apache.axis.message.MessageElement; +import org.apache.axis.message.addressing.EndpointReferenceType; +import org.apache.axis.message.addressing.ReferencePropertiesType; + +import org.gcube.common.core.utils.logging.GCUBELog; +import org.gcube.informationsystem.collector.impl.persistence.AggregatorPersistentResource; +import org.gcube.informationsystem.collector.impl.persistence.PersistentResource.RESOURCETYPE; +import org.gcube.informationsystem.collector.impl.state.AggregatorRegisteredResource; +import org.gcube.informationsystem.collector.impl.utils.*; +import org.gcube.informationsystem.collector.impl.xmlstorage.exist.State; +import org.gcube.informationsystem.collector.impl.porttypes.XMLCollectionAccess; + +import org.globus.mds.aggregator.impl.AggregatorServiceGroupResource; +import org.globus.mds.aggregator.impl.AggregatorServiceGroupEntryResource; +import org.globus.mds.aggregator.impl.AggregatorSource; +import org.globus.mds.aggregator.impl.AggregatorSink; + +import org.globus.wsrf.ResourceKey; +import org.globus.wsrf.ResourceProperty; +import org.globus.wsrf.ResourcePropertySet; +import org.globus.wsrf.TopicList; +import org.globus.wsrf.impl.ReflectionResourceProperty; +import org.globus.wsrf.impl.SimpleTopicList; +import org.globus.wsrf.impl.SimpleResourcePropertyMetaData; +import org.globus.wsrf.impl.servicegroup.ServiceGroupConstants; +import org.globus.wsrf.impl.servicegroup.EntryResourcePropertyTopic; + +/** + * This class implements an aggregating in-memory service group resource.
+ * For every registered AggregatorSource instance one connected AggregatorRegisteredResource + * instance is created and it is delivered with its data, following the chosen registration mode + * (Push/Pull). + * + * @author Manuele Simi (ISTI-CNR) + * + */ + +public class AggregatorRegisteredResource extends AggregatorServiceGroupResource + implements AggregatorSink, ICRegisteredResource { + + private static GCUBELog logger = new GCUBELog(AggregatorRegisteredResource.class); + + private ResourceKey resourceKey = null; + + // private static I18n i18n = I18n.getI18n(Resources.class.getName()); + + private static final String registryNS = "gcube/informationsystem/registry/Registry"; + + protected Calendar terminationTime, currentTime; + + private ResourcePropertySet propSet; + + private TopicList topicList; + + // private String baseDir; + + /** + * Builds a new resource + */ + public AggregatorRegisteredResource() { + super.init(XMLCollectionAccess.RP_SET); + + // this.baseDir = getBaseDirectory(); + this.propSet = this.getResourcePropertySet(); + this.topicList = new SimpleTopicList(this); + ResourceProperty prop = null; + + EntryResourcePropertyTopic rpTopic = new EntryResourcePropertyTopic(this.propSet.get(ServiceGroupConstants.ENTRY)); + this.propSet.add(rpTopic); + this.topicList.addTopic(rpTopic); + + try { + // ResourceLifeTime properties + prop = new ReflectionResourceProperty(SimpleResourcePropertyMetaData.TERMINATION_TIME, this); + this.propSet.add(prop); + prop = new ReflectionResourceProperty(SimpleResourcePropertyMetaData.CURRENT_TIME, this); + this.propSet.add(prop); + this.propSet.add(prop); + + // initialize aggregator + this.loadCompatibleSources(this); + + } catch (Exception e) { + logger.error(State.logPrefix + "Error during DISICResource creation: ", e); + } + } + + /** + * Used to inform the resource of its key. + * + * @param k the resource key + * + * @throws Exception if the resource key is already set + */ + public void setResourceKey(ResourceKey k) throws Exception { + if (resourceKey == null) + resourceKey = k; + else + throw new Exception("Resource key can only be set once."); + + } + + /** + * + * @return the resource key + */ + public ResourceKey getResourceKey() { + return resourceKey; + } + + // ResourceLifetime methods + + /** + * Sets the termination time + * + * @param time the new termination time + */ + public void setTerminationTime(Calendar time) { + + logger.debug(State.logPrefix + "Set Termination time called: " + time.getTime()); + this.terminationTime = time; + } + + /** + * + * + * {@inheritDoc} + */ + public Calendar getTerminationTime() { + return this.terminationTime; + } + + /** + * {@inheritDoc} + * + */ + public Calendar getCurrentTime() { + return Calendar.getInstance(); + } + + /** + * + * {@inheritDoc} + */ + public TopicList getTopicList() { + return this.topicList; + } + + // AggregatorSink methods + + /** + * Takes delivery of a message from an AggregatorSource.
+ * This is called by an AggregatorSource to + * deliver a message with the assumption that the message data will be aggregated as its native + * type and into whatever data storage format is used by the underlying AggregatorSink class. + * + * @param messageObj the message content + * @param entry the related service group entry + * + */ + public void deliver(AnyContentType messageObj, AggregatorServiceGroupEntryResource entry) { + + logger.info("New delivered resource"); + try { + + /* + * logger.debug(State.logPrefix + "delivered message -> " + + * AnyHelper.toSingleString(messageObj)); + */ + + // get the message content + MsgParser aentry = new MsgParser(messageObj); + String entryType = aentry.getEntryType(); + logger.debug("Entry type " + entryType); + logger.debug("Entry RunningInstance ID " + aentry.getRunningInstanceID()); + logger.debug("Entry Service Name " + aentry.getServiceName()); + logger.debug("Entry Service Class " + aentry.getServiceClass()); + // logger.debug(State.logPrefix + "getEntryAsString " + + // aentry.getEntryAsString()); + + // MessageElement[] message = messageObj.get_any(); + + // extract the entry EPR + EntryEPRParser eprparser = new EntryEPRParser(entry.getEntryEPR()); + + logger.debug("aggregator EntryEPR-> " + entry.getEntryEPR().toString()); + + // extract the member EPR + EndpointReferenceType memberEpr = entry.getMemberEPR(); + logger.debug("aggregator MemberEPR-> " + memberEpr.toString()); + + // get RP set from entry + // ResourcePropertySet rpSet = entry.getResourcePropertySet(); + + // get content RP from entry + /* + * ResourceProperty contentRP = rpSet.get(ServiceGroupConstants.CONTENT); + * + * AggregatorContent content = entry.getContent(); + * + * AggregatorConfig config = content.getAggregatorConfig(); + * + * MessageElement[] any = config.get_any(); + */ + + // Build the new resource to store + logger.debug("Storing the new delivered resource"); + AggregatorPersistentResource res = new AggregatorPersistentResource(); + res.setData(aentry.getEntryAsString()); + res.setEntryKey(eprparser.getEntryKey()); + res.setGroupKey(eprparser.getGroupKey()); + res.setTerminationTime(entry.getTerminationTime()); + // select the resource type + if (memberEpr.getAddress().toString().endsWith(AggregatorRegisteredResource.registryNS)) { + res.setType(RESOURCETYPE.Profile); + } else { + res.setType(RESOURCETYPE.Properties); + } + + // set the EPR and Key of the remote WS-Resource that publish the + // resource + res.setSource(memberEpr.getAddress().toString()); + logger.debug("Source: " + memberEpr.getAddress().toString()); + try { + ReferencePropertiesType prop = memberEpr.getProperties(); + if (prop != null) { + MessageElement[] any = prop.get_any(); + if (any.length > 0) { + res.setSourceKey(any[0].getValue()); + res.setCompleteSourceKey(any[0].toString()); + } + } + } catch (java.lang.NullPointerException npe) { + // nothing to do, the source key does not exist (may be the publisher is a singleton + // or stateless service) + } + + synchronized (State.deletedResources) { + if (State.deletedResources.contains(res)) { + State.deletedResources.remove(res); + throw new Exception("the resource " + res.getID() + " is no longer available"); + } + } + logger.trace("Resource: " + res.toString()); + + // store/update the new resource + State.storage_manager.storeResource(res); + aentry.dispose(); + logger.info("Delivered resource stored with success"); + } catch (Exception e) { + logger.error("When managing aggregator content:" + e.getMessage()); + logger.error("returned exception ", e); + } + } + + /** + * Called to initialize any necessary state. + * + * @param parameters any initialization parameters (not used) + */ + public void initialize(Object parameters) { + // NO OP + } + + /** + * Sets the AggregatorSource connected to this sink + * + * @param source the source + * + */ + public void setSource(AggregatorSource source) { + // NO OP + } + + /** + * Gets the AggregatorSource connected to this sink + * + * @return always null + */ + public AggregatorSource getSource() { + return null; + } + + /** + * Called to free resources used by the sink. + * + */ + public void terminate() { + logger.debug("Resource terminated"); + } + + // RemoveCallback methods + // Notifies that the resource was removed + /** + * Callback method invoked when the resource is removed by the Aggregator Framework + */ + public void remove() { + logger.debug("Resource removed"); + + } + +} diff --git a/src/org/gcube/informationsystem/collector/impl/state/ICAggregatorRemoveCallback.java b/src/org/gcube/informationsystem/collector/impl/state/ICAggregatorRemoveCallback.java new file mode 100755 index 0000000..8956857 --- /dev/null +++ b/src/org/gcube/informationsystem/collector/impl/state/ICAggregatorRemoveCallback.java @@ -0,0 +1,62 @@ +package org.gcube.informationsystem.collector.impl.state; + +import org.gcube.common.core.utils.logging.GCUBELog; +import org.gcube.informationsystem.collector.impl.persistence.AggregatorPersistentResource; +import org.gcube.informationsystem.collector.impl.utils.EntryEPRParser; +import org.gcube.informationsystem.collector.impl.xmlstorage.exist.State; + +import org.globus.mds.aggregator.impl.AggregatorServiceGroupEntryRemovedCallback; +import org.globus.mds.aggregator.impl.AggregatorServiceGroupEntryResource; + +/** + * Whenever a AggregatorServiceGroupEntryResource is removed from an + * AggregatorServiceGroupEntryHome, the corresponding remove method of this class will be invoked + * passing as a parameter the instance of the resource that is about to be removed. + * + * + * @author Manuele Simi (ISTI-CNR) + * + */ +public class ICAggregatorRemoveCallback implements AggregatorServiceGroupEntryRemovedCallback { + + private static GCUBELog logger = new GCUBELog(ICAggregatorRemoveCallback.class); + + /** + * Creates a new Callback object + * + */ + public ICAggregatorRemoveCallback() { + super(); + } + + /** + * Removes from the storage the supplied resource + * + * @param entry the AggregatorServiceGroupEntryResource that is about to be removed + * @throws Exception + * if the delete operation fails + */ + public void remove(AggregatorServiceGroupEntryResource entry) throws Exception { + + logger.debug("ICAggregatorRemoveCallback invoked " + entry.getEntryEPR().toString()); + EntryEPRParser parser = new EntryEPRParser(entry.getEntryEPR()); + + AggregatorPersistentResource res = new AggregatorPersistentResource(); + res.setEntryKey(parser.getEntryKey()); + res.setGroupKey(parser.getGroupKey()); + + // mark the resource as no longer available + synchronized (State.deletedResources) { + State.deletedResources.add(res); + } + + // delete the resource from the database + try { + State.storage_manager.retrieveAndDeleteResourceFromID(res.getID()); + } catch (Exception e) { + logger.error(State.logPrefix + "unable to remove resource: " + res.getID(), e); + } + + } + +} diff --git a/src/org/gcube/informationsystem/collector/impl/state/ICRegisteredResource.java b/src/org/gcube/informationsystem/collector/impl/state/ICRegisteredResource.java new file mode 100755 index 0000000..8de3029 --- /dev/null +++ b/src/org/gcube/informationsystem/collector/impl/state/ICRegisteredResource.java @@ -0,0 +1,15 @@ +package org.gcube.informationsystem.collector.impl.state; + +import org.globus.wsrf.ResourceLifetime; +import org.globus.wsrf.ResourceProperties; +import org.globus.wsrf.TopicListAccessor; + +/** + * Marker interface for IC registered resources + * + * @author Manuele Simi (ISTI-CNR) + * + */ +public interface ICRegisteredResource extends TopicListAccessor, ResourceLifetime, ResourceProperties { + +} diff --git a/src/org/gcube/informationsystem/collector/impl/utils/EntryEPRParser.java b/src/org/gcube/informationsystem/collector/impl/utils/EntryEPRParser.java new file mode 100755 index 0000000..257e6f8 --- /dev/null +++ b/src/org/gcube/informationsystem/collector/impl/utils/EntryEPRParser.java @@ -0,0 +1,104 @@ +package org.gcube.informationsystem.collector.impl.utils; + +import org.gcube.common.core.utils.logging.GCUBELog; +import org.gcube.informationsystem.collector.impl.utils.EntryEPRParser; + +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.apache.axis.message.addressing.EndpointReferenceType; +import org.apache.axis.message.addressing.ReferencePropertiesType; +import org.apache.axis.message.MessageElement; + +import org.w3c.dom.*; + +import org.xml.sax.InputSource; + +import javax.xml.parsers.*; + +import java.io.StringReader; +import java.lang.Exception; + +/** + * + * Parser for EntryEPR of a WS-ServiceGroup resources + * + * + */ + +public class EntryEPRParser { + + private Document internalDOM; + + private Element serviceGroup; + + // xpath factory to evaluate Xpath expressions + private XPath path = XPathFactory.newInstance().newXPath(); + + private static GCUBELog logger = new GCUBELog(EntryEPRParser.class); + + /** + * + * @param e + * the EPR of the service group resource to parse + * @throws Exception + * if the input EPR is no valid + */ + public EntryEPRParser(EndpointReferenceType e) throws Exception { + + ReferencePropertiesType prop = e.getProperties(); + MessageElement[] any = prop.get_any(); + + logger.debug("Aggregator EntryEPR-> " + e.toString()); + + if (any[0].getName().equalsIgnoreCase("ServiceGroupEntryKey")) { + serviceGroup = any[0]; + DocumentBuilderFactory factory = DocumentBuilderFactory + .newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + StringReader reader = new StringReader(serviceGroup.toString()); + InputSource source = new InputSource(reader); + this.internalDOM = builder.parse(source); + } + } + + /** + * + * @return the service group's entry key + * @throws Exception + * if the parsing of the EPR fails + */ + public String getEntryKey() throws Exception { + + String key = null; + try { + key = path.evaluate("ServiceGroupEntryKey/EntryKey", internalDOM); + } catch (XPathExpressionException xpee) { + logger.error(xpee.getMessage()); + logger.error(xpee.getStackTrace()); + throw new Exception("XPath evaluation error"); + } + return key; + } + + /** + * + * @return the service group's group key + * @throws Exception + * if the parsing of the EPR fails + */ + public String getGroupKey() throws Exception { + + String key = null; + try { + key = path.evaluate("ServiceGroupEntryKey/GroupKey", internalDOM); + } catch (XPathExpressionException xpee) { + logger.error(xpee.getMessage()); + logger.error(xpee.getStackTrace()); + throw new Exception("XPath evaluation error"); + } + return key; + } + +} diff --git a/src/org/gcube/informationsystem/collector/impl/utils/MsgParser.java b/src/org/gcube/informationsystem/collector/impl/utils/MsgParser.java new file mode 100755 index 0000000..47ae28c --- /dev/null +++ b/src/org/gcube/informationsystem/collector/impl/utils/MsgParser.java @@ -0,0 +1,283 @@ +package org.gcube.informationsystem.collector.impl.utils; + +import org.apache.axis.encoding.AnyContentType; + +import org.gcube.common.core.utils.logging.GCUBELog; +import org.gcube.informationsystem.collector.impl.utils.MsgParser; +import org.globus.wsrf.utils.AnyHelper; + +import org.w3c.dom.*; + +import org.xml.sax.InputSource; +import org.xml.sax.SAXParseException; + +import javax.xml.parsers.*; +import javax.xml.xpath.*; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; + +import java.io.StringWriter; +import java.io.StringReader; +import java.lang.Exception; + +/** + * + * @author manuele simi + * + * @version 1.0 June 2006 + * + * @link http://www.diligentproject.org + * + */ +public class MsgParser { + + private Document internalDOM; + + private String originalMsgString; + + private String type; // the entry type (profile or generic resource + // properties) + + private XPath path = XPathFactory.newInstance().newXPath(); // object to + // evaluate + // Xpath + // expressions + + private final String rootElement = "Data"; + + private final String typeElement = "Type"; + + private static GCUBELog logger = new GCUBELog(MsgParser.class); + + public MsgParser(AnyContentType deliveredMsg) throws Exception { + + try { + this.originalMsgString = AnyHelper.toSingleString(deliveredMsg); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + StringReader reader = new StringReader("<" + rootElement + ">" + + this.originalMsgString + ""); + InputSource source = new InputSource(reader); + this.internalDOM = builder.parse(source); + // check if the message has been sent in push or pull mode + this.checkMsgType(); + // gets the entry type + this.type = path.evaluate("//" + rootElement + + "/child::*[local-name() = '" + typeElement + "']", internalDOM); + } catch (ParserConfigurationException pce) { + logger.error("", pce); + throw new Exception("Parser configuration error"); + } catch (SAXParseException spe) { + logger.error("", spe); + throw new Exception(" SAX parser error"); + } catch (XPathExpressionException xpee) { + logger.error("", xpee); + throw new Exception("XPath evaluation error"); + } + } + + /** + * Returns the entry type. It can be "Properties" or "Profile" + * + * @return the entry type + */ + public String getEntryType() { + return this.type; + } + + /** + * Returns the entry type if the entry is a profile + * + * @throws Exception + * + * @return the entry type + */ + public String getResourceType() throws Exception { + + if (this.type.equalsIgnoreCase("Profile")) { + logger.warn("The entry does not have a ResourceType"); + throw new Exception("Invalid resource (type = Properties)"); + } + return this.getDILIGENTProperty("DILIGENTResourceType"); + } + + /** + * Returns the VO Name included in the entry + * + * @throws Exception + * + * @return the VO name + */ + public String getVOName() throws Exception { + + return this.getDILIGENTProperty("VO"); + } + + /** + * Returns the Service Name included in the entry + * + * @throws Exception + * + * @return the service name + */ + public String getServiceName() throws Exception { + + return this.getDILIGENTProperty("ServiceName"); + } + + /** + * Returns the Service Class included in the entry + * + * @throws Exception + * + * @return the service class + */ + public String getServiceClass() throws Exception { + + return this.getDILIGENTProperty("ServiceClass"); + } + + /** + * Returns the Running Instance ID included in the entry + * + * @throws Exception + * + * @return the ID + */ + public String getRunningInstanceID() throws Exception { + + return this.getDILIGENTProperty("RunningInstanceID"); + } + + /** + * Returns the Service ID included in the entry + * + * @throws Exception + * + * @return the service ID + */ + public String getServiceID() throws Exception { + + return this.getDILIGENTProperty("ServiceID"); + } + + /** + * Returns the DHN ID included in the entry + * + * @throws Exception + * + * @return the DHN ID + */ + public String getDHNID() throws Exception { + + return this.getDILIGENTProperty("GHN"); + } + + /** + * Extracts a given DILIGENT Property + * + * @throws Exception + * + * @return the property value + */ + private String getDILIGENTProperty(String propName) throws Exception { + + String value = null; + + try { + value = path.evaluate("//" + rootElement + + "/child::*[local-name() = '" + propName + "']", + internalDOM); + } catch (XPathExpressionException xpee) { + logger.error("", xpee); + throw new Exception("XPath evaluation error"); + } + return value; + } + + /** + * Returns a XML representation of the Entry + * + * @return the XML string + */ + public String getEntryAsString() { + return "<" + rootElement + ">\n" + this.originalMsgString + "\n"; + // return XMLUtils.DocumentToString(this.internalDOM); + } + + /** + * Releases the allocated resources + * + */ + + public void dispose() { + // remove the allocated DOM + internalDOM = null; + } + + /** + * Checks if the message has been sent by a WS-Notification In that case, + * the NewValue is extracted by the msg + * + */ + private void checkMsgType() throws Exception { + + Boolean isPush = false; + String notificationXpath = "/child::*[local-name() = 'value']"; + notificationXpath += "/child::*[local-name() = 'ResourcePropertyValueChangeNotification']"; + notificationXpath += "/child::*[local-name() = 'NewValue']"; + + try { + isPush = (Boolean) path.evaluate("//" + rootElement + notificationXpath, this.internalDOM, + XPathConstants.BOOLEAN); + } catch (NullPointerException n) { + logger.trace("The delivered message has been sent using the pull mode"); + return; + } catch (XPathExpressionException xpee) { + logger.error("", xpee); + } + + if (isPush) { + // replace the originalMsgString and the internalDOM with the + // newValue section of the delivered message + logger.trace("The delivered message has been sent using the push mode"); + // String nodeString = (String) path.evaluate(notificationXpath, + // this.internalDOM, XPathConstants.STRING); + + Node node = (Node) path.evaluate("//" + rootElement + + notificationXpath, this.internalDOM, XPathConstants.NODE); + + Transformer serializer = TransformerFactory.newInstance().newTransformer(); + StringWriter sw = new StringWriter(); + + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder domBuilder = factory.newDocumentBuilder(); + + // create the nre data string + NodeList children = node.getChildNodes(); + this.originalMsgString = ""; + if (children != null) { + for (int i = 0; i < children.getLength(); i++) { + serializer.transform(new DOMSource(children.item(i)), + new StreamResult(sw)); + this.originalMsgString += sw.toString(); + } + } + logger.trace("Data string " + this.originalMsgString); + // trim the directive + this.originalMsgString = this.originalMsgString.substring(this.originalMsgString.indexOf("?>", 1) + 1); + logger.trace("Trimmed data string " + this.originalMsgString); + // create the new internalDOM + StringReader reader = new StringReader("<" + rootElement + ">" + + this.originalMsgString + ""); + InputSource source = new InputSource(reader); + this.internalDOM = domBuilder.parse(source); + } else { + logger.info("The delivered message has been sent using the pull mode"); + } + } + +} diff --git a/src/org/gcube/informationsystem/collector/impl/xmlstorage/exist/State.java b/src/org/gcube/informationsystem/collector/impl/xmlstorage/exist/State.java new file mode 100755 index 0000000..60eac35 --- /dev/null +++ b/src/org/gcube/informationsystem/collector/impl/xmlstorage/exist/State.java @@ -0,0 +1,127 @@ +package org.gcube.informationsystem.collector.impl.xmlstorage.exist; + +import org.gcube.informationsystem.collector.impl.contexts.ICServiceContext; +import org.gcube.informationsystem.collector.impl.persistence.AggregatorPersistentResource; + +import org.globus.wsrf.config.ContainerConfig; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Collections; + +/** + * This class groups the data globally scoped in an active RI + * + * @author manuele simi + * + */ +public class State { + + /** + * Connection to eXist used to store data + */ + public static XMLStorageManager storage_manager; + + /** + * Connection to eXist used to query the database + */ + public static XMLStorageManager query_manager; + + /** + * DIS-IC's JNDI resource name as declared in the JNDI file + */ + public static final String JNDIResourceName = "DISICConfiguration"; + + /** + * Prefix to prepend to any log message + */ + public static final String logPrefix = ""; + + /** + * Thread that periodically sweeps the database from expired resources + */ + public static Thread sweeperT; + + /** + * List of recently deleted resources. It is used to avoid the storage of RPs of a deleted + * resource + */ + public static List deletedResources = Collections.synchronizedList(new ArrayList()); + + private static Log logger = LogFactory.getLog(State.class.getName()); + + /** + * Initializes the eXist DB connections using during the service life + * + * @param configuration + * the RI configuration loaded from the JNDI resource + * @throws Exception + * if the intialization fails + */ + public static void initialize() throws Exception { + logger.info("starting IC service initialization..."); + State.initializeStorageManager(); + State.initializeQueryManager(); + if (Boolean.valueOf((String) ICServiceContext.getContext().getProperty("deleteRPsOnStartup", true))) { + // cleanup the RPs collection + logger.info("deleting all RPs..."); + State.storage_manager.deleteAllProperties(); + } else { + logger.info("all RPs previously stored are keept in the storage"); + } + + // start the sweeper to periodically cleanup the storage and some data structures + Sweeper sweeper = new Sweeper(Long.valueOf((String) ICServiceContext.getContext().getProperty("sweeperIntervalinMillis", true)), Long.valueOf((String) ICServiceContext.getContext() + .getProperty("resourceExpirationTimeInMillis", true))); + State.sweeperT = new Thread(sweeper); + State.sweeperT.start(); + + logger.info("IC service initialization completed"); + } + + private static void initializeStorageManager() throws Exception { + // open the connection used to store resources + State.storage_manager = new XMLStorageManager(); + storage_manager.initialize(); + } + + private static void initializeQueryManager() throws Exception { + // open the connection used to query stored resources + State.query_manager = new XMLStorageManager(); + query_manager.initialize(); + } + + /** + * + * @return the container base dir + */ + public static String getBaseDirectory() { + return ContainerConfig.getBaseDirectory(); + } + + /** + * Releases all the State resources + * + * @throws Exception if the shutdown fails + */ + public static void dispose() throws Exception { + logger.info("Disposing IC service's resources..."); + State.storage_manager.shutdown(); + State.query_manager.shutdown(); + } + + /** + * Prints the enviromnet variables + */ + public void printEnv() { + java.util.Properties p = System.getProperties(); + Enumeration keys = p.keys(); + while (keys.hasMoreElements()) { + logger.debug(keys.nextElement()); + } + logger.debug("Exist home: " + System.getProperty("exist.home")); + logger.debug("Class path: " + System.getProperty("java.class.path")); + } +} diff --git a/src/org/gcube/informationsystem/collector/impl/xmlstorage/exist/Sweeper.java b/src/org/gcube/informationsystem/collector/impl/xmlstorage/exist/Sweeper.java new file mode 100755 index 0000000..a524121 --- /dev/null +++ b/src/org/gcube/informationsystem/collector/impl/xmlstorage/exist/Sweeper.java @@ -0,0 +1,157 @@ +/** + * + */ +package org.gcube.informationsystem.collector.impl.xmlstorage.exist; + +import java.lang.InterruptedException; +import java.util.GregorianCalendar; +import java.util.Calendar; +import java.util.TimeZone; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.gcube.informationsystem.collector.impl.persistence.PersistentResource; +import org.gcube.informationsystem.collector.impl.xmlstorage.exist.State; +import org.gcube.informationsystem.collector.impl.xmlstorage.exist.Sweeper; +import org.gcube.informationsystem.collector.impl.xmlstorage.exist.XMLStorageManager; + +/** + * This class provides some cleanup procedures to use to maintain a consistent + * content in the XML storage One of them is a thread, activated at RI startup + * time, that periodically drops the out to date resources from the storage + * + * @author Manuele Simi (ISTI-CNR) + * + */ +public class Sweeper implements Runnable { + + private static long DELAY = 180000; // default value + + private static long resourceExpirationTime = 1800000; // default value + + private static Log logger = LogFactory.getLog(Sweeper.class.getName()); + + private static XMLStorageManager storage = null; + + /** + * Initializes a new Sweeper + * + * @param delay the sweeper delay + * @param resourceExpirationTime the time after that a resource is classified as exipired + * @throws Exception if the eXist connection fails + */ + public Sweeper(long delay, long resourceExpirationTime) throws Exception { + Sweeper.DELAY = delay; + Sweeper.resourceExpirationTime = resourceExpirationTime; + logger.info("Starting sweeper thread with an interval of " + Sweeper.DELAY + " ms"); + Sweeper.storage = new XMLStorageManager(); + Sweeper.storage.initialize(); + } + + /** + * {@inheritDoc} + */ + public void run() { + try { + while (!Thread.interrupted()) { + Thread.sleep(Sweeper.DELAY); + logger.info("Starting IC sweeper..."); + this.cleanDeletedResourcesList(); + this.cleanExpiredResources(); + } + } catch (InterruptedException ie) { + // thread was interrupted + storage.shutdown(); + } + } + + /** + * Deletes from the backend storage the expired resources + * + */ + public void cleanExpiredResources() { + + Calendar now = new GregorianCalendar(); + now.setTimeZone(TimeZone.getTimeZone("GMT")); + + try { + + String[] ids = Sweeper.storage.listAllPropertiesIDs(); + for (String id : ids) { + try { + PersistentResource res = Sweeper.storage + .retrievePropertyResourceFromID(id); + if (now.getTimeInMillis() - res.getLastUpdateTimeinMills() > Sweeper.resourceExpirationTime) + // removes the resources from the database + State.storage_manager + .retrieveAndDeleteResourceFromID(id); + // break; + } catch (Exception e) { + logger.debug(State.logPrefix + + "DIS-IC sweeper - the resource " + id + + " is no longer available in the storage"); + } + } + + } catch (Exception e2) { + logger + .warn( + State.logPrefix + + "DIS-IC sweeper - an exception was rised when trying to cleanup the storage ", + e2); + } + } + + /** + * Removes all the properties documents related to the given Running + * Instance ID + * + * @param id + * the ID of the Running Instance whose properties documents have + * to be removed + */ + public static void cleanResourceForRI(String id) { + // TO DO + } + + /** + * Deletes the Properties collection from the storage + * + */ + public static void cleanRPs() { + // cleanup the RPs collection + State.storage_manager.deleteAllProperties(); + } + + /** + * Deletes the expired resources from the list of deleted resources as + * notified by the AF + * + */ + + public void cleanDeletedResourcesList() { + + Calendar now = new GregorianCalendar(); + now.setTimeZone(TimeZone.getTimeZone("GMT")); + List toRemove = new ArrayList(); + for (PersistentResource res : State.deletedResources) { + try { + if (now.getTimeInMillis() - res.getLastUpdateTimeinMills() > Sweeper.resourceExpirationTime) { + toRemove.add(res); + } + } catch (Exception e) { + logger.error(State.logPrefix, e); + } + }// end loop on deletedResources + synchronized (State.deletedResources) { + for (PersistentResource res : toRemove) { + State.deletedResources.remove(res); + } + }// end synch block + + } + +} diff --git a/src/org/gcube/informationsystem/collector/impl/xmlstorage/exist/XMLStorageManager.java b/src/org/gcube/informationsystem/collector/impl/xmlstorage/exist/XMLStorageManager.java new file mode 100755 index 0000000..e9b7cb1 --- /dev/null +++ b/src/org/gcube/informationsystem/collector/impl/xmlstorage/exist/XMLStorageManager.java @@ -0,0 +1,626 @@ +package org.gcube.informationsystem.collector.impl.xmlstorage.exist; + +import org.xmldb.api.base.XMLDBException; +import org.xmldb.api.base.Collection; +import org.xmldb.api.base.Database; +import org.xmldb.api.base.ResourceSet; + +import org.xmldb.api.DatabaseManager; + +import org.xmldb.api.modules.XMLResource; +import org.xmldb.api.modules.CollectionManagementService; + +import org.exist.xmldb.DatabaseInstanceManager; + +import org.exist.storage.DBBroker; + +import org.gcube.common.core.utils.logging.GCUBELog; +import org.gcube.informationsystem.collector.impl.persistence.AggregatorPersistentResource; +import org.gcube.informationsystem.collector.impl.persistence.PersistentResource; +import org.gcube.informationsystem.collector.impl.persistence.PersistentResource.RESOURCETYPE; +import org.gcube.informationsystem.collector.impl.xmlstorage.exist.XMLStorageManager; +import org.gcube.informationsystem.collector.impl.xmlstorage.exist.XQuery; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +; + +/** + * A thread safe manager to interact with the XML Storage repository. + * + * @author Manuele Simi (ISTI-CNR) + * + */ +public class XMLStorageManager { + + protected static String URI = "xmldb:exist://"; + + protected static String driver = "org.exist.xmldb.DatabaseImpl"; + + private static GCUBELog logger = new GCUBELog(XMLStorageManager.class); + + private Database database; + + // private Collection currentCollection; + + private Collection rootCollection; + + private Collection profilesRootCollection; + + // lock for write operations + private Lock writeLock; + + // flag to warn when the DB is locked + private boolean locked = false; + + private static final String PROPERTIES_COLLECTION_NAME = "Properties"; + + protected static String PROFILES_COLLECTION_NAME = "Profiles"; + + /** + * Creates a new manager + * + */ + public XMLStorageManager() { + logger.debug("Creating a new XMLStorageManager"); + writeLock = new ReentrantLock(); + } + + /** + * Initializes the local XML Storage repository + * + * @throws Exception + * if the connection to eXist or its initialization fail + */ + public void initialize() throws Exception { + try { + logger.info("connecting to eXist DB..."); + // this.printEnv(); + + // lock the instance + writeLock.lock(); + + // register/create the DB instance + Class cl = Class.forName(driver); + this.database = (Database) cl.newInstance(); + database.setProperty("create-database", "true"); + DatabaseManager.registerDatabase(this.database); + + // try to load the collections for props and profiles + logger.debug("Initializing the root collection"); + this.rootCollection = DatabaseManager.getCollection(URI + DBBroker.ROOT_COLLECTION, "admin", "admin"); + if (this.rootCollection == null) { + logger.error("invalid root collection!"); + throw new Exception("unable to load root collection"); + } + logger.debug("Initializing the collection Profiles"); + this.profilesRootCollection = this.rootCollection.getChildCollection(XMLStorageManager.PROFILES_COLLECTION_NAME); + if (this.profilesRootCollection == null) { + logger.debug("Creating Profiles collection"); + this.profilesRootCollection = this.createCollection(this.rootCollection, XMLStorageManager.PROFILES_COLLECTION_NAME); + logger.debug("Profiles collection created"); + } + if (this.profilesRootCollection == null) { + throw new Exception("Unable to load/create Profiles collection"); + } + this.rootCollection.setProperty("pretty", "true"); + this.rootCollection.setProperty("encoding", "UTF-8"); + this.profilesRootCollection.setProperty("pretty", "true"); + this.profilesRootCollection.setProperty("encoding", "UTF-8"); + } catch (XMLDBException edb) { + logger.error("unable to initialize XML storage ", edb); + throw new Exception("unable to initialize XML storage"); + } catch (Exception e) { + logger.debug("unable to initialize XML storage ", e); + throw new Exception("unable to initialize XML storage"); + } catch (java.lang.NoClassDefFoundError ncdfe) { + logger.debug("unable to initialize XML storage", ncdfe); + throw new Exception("unable to initialize XML storage"); + } finally { + writeLock.unlock(); + } + + } + + /** + * Shutdowns the XML Storage repository + * + * @return true if the operation succeed + */ + public boolean shutdown() { + writeLock.lock(); + try { + DatabaseInstanceManager manager = (DatabaseInstanceManager) rootCollection.getService("DatabaseInstanceManager", "1.0"); + manager.shutdown(); + } catch (XMLDBException edb) { + logger.error("Unable to shutdown XML storage"); + logger.error("" + edb.getCause()); + } finally { + writeLock.unlock(); + } + return true; + } + + /** + * Loads a collection. If it does not exist, the collection is created. + * + * @param parentCollection + * the parent collection of the collection to load + * @param collectionName + * name of the collection to load + * @return the collection + */ + private Collection loadCollection(Collection parentCollection, String collectionName) { + // set the current collection + Collection currentCollection = null; + try { + currentCollection = parentCollection.getChildCollection(collectionName); + if (currentCollection == null) { + // the collection does not exist, it is created + logger.info("Creating a new collection " + collectionName + "..."); + currentCollection = this.createCollection(parentCollection, collectionName); + } + currentCollection.setProperty("pretty", "true"); + currentCollection.setProperty("encoding", "UTF-8"); + } catch (XMLDBException edb) { + logger.error("failed to create collection " + collectionName + "!"); + logger.error("" + edb.getCause()); + + } + return currentCollection; + } + + /** + * Discards the current collection + * + */ + private void resetCollection(Collection currentCollection) { + try { + currentCollection.close(); + } catch (XMLDBException edb) { + // Catch any issues with closing the exception. + logger.error("unable to close collection " + edb.getMessage()); + } + currentCollection = null; + } + + /** + * Loads the collection containing the WS-ResourceProperties documents. It must be used when + * quering/storing/updating WS-ResourceProperties documents + * + * @return the Collection + */ + public Collection loadPropertiesCollection() { + logger.debug("Loading collection Properties... "); + return this.loadCollection(this.rootCollection, XMLStorageManager.PROPERTIES_COLLECTION_NAME); + } + + /** + * Loads from the children of the Profile Collection, the collection identified by the given + * name. It must be used when quering/storing/updating a particular kind of profile + * + * @param collectionName + * the child collection of the Profile collection to load + * @return the Collection + */ + public Collection loadProfileCollection(String collectionName) { + logger.debug("Loading collection " + collectionName + "... "); + return this.loadCollection(this.profilesRootCollection, collectionName); + } + + /** + * Loads the parent collection of all collections containing resources profiles. It must be used + * when quering all the profiles at the same time + * + * @return the Collection + */ + public Collection loadAllProfilesCollection() { + logger.debug("Loading all profiles collection... "); + return this.loadCollection(this.rootCollection, XMLStorageManager.PROFILES_COLLECTION_NAME); + } + + /** + * Loads the root collection. It must be used when quering all the information maintained by the + * DB instance at the same time + * + * @return the Collection + */ + public Collection loadAllCollections() { + + Collection currentCollection = null; + logger.debug("Loading all collections... "); + // return this.loadCollection(this.rootCollection, + // XMLStorageManager.PROFILES_COLLECTION_NAME); + try { + currentCollection = DatabaseManager.getCollection(URI + DBBroker.ROOT_COLLECTION, "admin", "admin"); + } catch (XMLDBException edb) { + logger.error("Failed to load all collections!"); + logger.error("", edb); + } + return currentCollection; + } + + /** + * Stores a AggregatorPersistentResource in the current collection. If the resource already + * exists in the storage, it is updated. + * + * @param resource + * the resource to store + * @throws Exception + * if the storing fails + */ + public void storeResource(PersistentResource resource) throws Exception { + + Collection currentCollection = null; + if (resource.getType() == RESOURCETYPE.Profile) { + // the entry contains a gCube resource profile + currentCollection = this.loadProfileCollection(resource.getProfileType()); + } else { + // the entry contains generic properties + currentCollection = this.loadPropertiesCollection(); + } + + if (currentCollection == null) { + logger.error("Unable to open the Collection"); + return; + } + writeLock.lock(); + this.locked = true; + try { + XMLResource document = (XMLResource) currentCollection.createResource(resource.getID(), "XMLResource"); + document.setContent(resource.toString()); + logger.debug("Storing/updating resource " + document.getId() + " in collection " + currentCollection.getName() + "..."); + currentCollection.storeResource(document); + logger.debug("...done"); + } catch (XMLDBException edb) { + logger.error("Failed to store resource " + resource.getID()); + logger.error("" + edb.errorCode + " " + edb.getMessage(), edb); + } catch (Exception e) { + logger.error("" + e.getMessage(), e); + } finally { + this.resetCollection(currentCollection); + writeLock.unlock(); + this.locked = false; + } + } + + /** + * + * @return true if the connection to eXist is locked + */ + public boolean isLocked() { + return this.locked; + } + + /** + * Retrieves a resource from the storage given its ID + * + * @param resourceID + * @return + * @throws Exception + */ + public AggregatorPersistentResource retrieveResourceFromID(String resourceID) throws Exception { + XMLResource res = null; + Collection currentCollection = this.loadAllCollections(); + try { + res = (XMLResource) currentCollection.getResource(resourceID); + if (res == null) + logger.warn("Resource " + resourceID + " not found!"); + } catch (XMLDBException edb) { + logger.error("Failed to retrieve document " + resourceID); + logger.error("" + edb.errorCode + " " + edb.getMessage(), edb); + throw new Exception(); + } + return new AggregatorPersistentResource(res); + } + + /** + * Retrieves a resource from the storage given its ID + * + * @param resourceID + * @return + * @throws Exception + */ + public AggregatorPersistentResource retrievePropertyResourceFromID(String resourceID) throws Exception { + XMLResource res = null; + Collection currentCollection = this.loadPropertiesCollection(); + try { + res = (XMLResource) currentCollection.getResource(resourceID); + if (res == null) + logger.warn("Resource " + resourceID + " not found!"); + } catch (XMLDBException edb) { + logger.error("Failed to retrieve document " + resourceID); + logger.error("" + edb.errorCode + " " + edb.getMessage(), edb); + throw new Exception(); + } + return new AggregatorPersistentResource(res); + } + + /** + * + * @param xpathquery + * @return + */ + public AggregatorPersistentResource executeXPathQuery(String xpathquery) { + + AggregatorPersistentResource res = null; + // ArrayList results = new + // ArrayList(); + /* + * try { // get query-service XPathQueryServiceImpl service = (XPathQueryServiceImpl) + * currentCollection.getService("XPathQueryService", "1.0"); // set pretty-printing on + * service.setProperty(OutputKeys.INDENT, "yes"); service.setProperty(OutputKeys.ENCODING, + * "UTF-8"); ResourceSet set = service.query(xpathquery); logger.debug("number of returned + * documents: " + set.getSize()); ResourceIterator i = set.getIterator(); + * while(i.hasMoreResources()) { res = new AggregatorPersistentResource((XMLResource) + * i.nextResource()); System.out.println("DILIGENT resource " + i + " " + res.toString()); } + * + * for (int i = 0; i < (int) set.getSize(); i++) { res = new + * AggregatorPersistentResource((XMLResource) set.getResource((long) i)); + * System.out.println("DILIGENT resource " + i + " " + res.toString()); } } catch + * (XMLDBException edb) { logger.error("failed to execute Xpath query " + xpathquery); + * edb.printStackTrace(); } catch (Exception e) { logger.error("exception " + xpathquery); + * logger.error(e.getStackTrace()); } + */ + return res; + + } + + /** + * Executes the given query on the current collection or on the root collection if any was + * previously loaded + * + * @param query + * - the query to run + * @return + */ + public ResourceSet executeXQuery(XQuery query) { + + boolean retry = true; + int attempts = 0, max_attempts = 3; + ResourceSet result = null; + Collection currentCollection = null; + currentCollection = this.loadAllCollections(); + + while ((retry) && (attempts < max_attempts)) { + try { + // wait until the DB is unlocked + while (State.storage_manager.isLocked()) + Thread.sleep(1000); + // execute query and get results in ResourceSet + if (currentCollection == null) + result = query.execute(this.rootCollection); + else + result = query.execute(currentCollection); + retry = false; + } catch (XMLDBException edb) { + logger.error("Failed to execute XQuery " + query.toString()); + logger.error("Error details: " + edb.errorCode + " " + edb.getMessage(), edb); + // if the cause is a NullPointer, this can be due to a temporary + // lock on the database instance + if (edb.getCause() instanceof java.lang.NullPointerException) { + retry = true; + attempts++; + logger.warn("Trying a new attempt for query execution"); + } else + retry = false; + + } catch (Exception e) { + logger.error("", e); + // if the cause is a NullPointer, this can be due to a temporary + // lock on the database instance + if (e instanceof java.lang.NullPointerException) { + retry = true; + attempts++; + logger.warn("Trying a new attempt for query execution"); + } else + retry = false; + + } + } + + this.resetCollection(currentCollection); + + return result; + } + + /** + * Deletes a WS-ResourceProperties resource identified by the given ID + */ + synchronized public void retrieveAndDeleteResourceFromID(String resourceID) throws Exception { + + if (resourceID == null) { + logger.warn("Invalid resource ID"); + return; + } + + Collection propCollection = this.loadPropertiesCollection(); + + if (propCollection == null) { + logger.error("Unable to load collection Properties!"); + throw new Exception(); + } + try { + logger.info("Trying to remove resource " + resourceID + " from collection " + propCollection.getName()); + deleteResource(resourceID, propCollection); + } catch (XMLDBException edb) { + logger.error("Failed to remove the resource from the storage! "); + logger.error("", edb); + throw new Exception(); + } finally { + this.resetCollection(propCollection); + } + + } + + /** + * Deletes a Profile resource identified by the given ID + */ + synchronized public void retrieveAndDeleteProfileFromID(String profileID, String profileType) throws Exception { + + if (profileID == null) { + logger.warn("Invalid profile ID"); + return; + } + Collection profileCollection = this.loadProfileCollection(profileType); + + if (profileCollection == null) { + logger.error("Uunable to load collection Profile!"); + throw new Exception("unable to load collection Profile"); + } + try { + logger.info("Trying to remove profile '" + profileID + "' from collection " + profileCollection.getName()); + deleteResource(profileID, profileCollection); + } catch (XMLDBException edb) { + logger.error("Failed to remove the profile from the storage! "); + logger.error("", edb); + throw new Exception(); + } finally { + this.resetCollection(profileCollection); + } + + } + + /** + * Deletes the resource with the given ID from the local storage + * + * @param resourceID + * - the ID of the resource + * @param col + * - the collection from which the resource has to be removed + * @throws Exception + */ + private void deleteResource(String resourceID, Collection col) throws Exception { + + XMLResource res = null; + // lock the instance + this.writeLock.lock(); + this.locked = true; + try { + res = (XMLResource) col.getResource(resourceID); + if (res == null) + logger.warn("Resource " + resourceID + " not found!"); + else { + col.removeResource(res); + logger.info("Resource successfully removed"); + } + } catch (XMLDBException edb) { + logger.error("Failed to retrieve resource " + resourceID); + logger.error("", edb); + throw new Exception(); + } finally { + this.resetCollection(col); + this.writeLock.unlock(); + this.locked = false; + } + } + + /** + * Prints all the IDs of the Resources stored in the DB instance + * + */ + public void printResourcesIDs() { + + String[] ress; + Collection currentCollection = null; + currentCollection = this.loadAllCollections(); + try { + if (currentCollection == null) { + ress = this.rootCollection.listResources(); + } else { + ress = currentCollection.listResources(); + } + for (int i = 0; i < ress.length; i++) { + logger.debug("Resource ID:" + ress[i]); + } + } catch (XMLDBException edb) { + logger.error("Failed to read resource IDs ", edb); + } finally { + this.resetCollection(currentCollection); + } + } + + /** + * Creates a new collection + * + * @param collectionName + * @return the create Collection object + */ + private Collection createCollection(Collection parentCollection, String collectionName) { + + Collection col = null; + this.writeLock.lock(); + try { + CollectionManagementService mgtService = (CollectionManagementService) parentCollection.getService("CollectionManagementService", "1.0"); + col = mgtService.createCollection(collectionName); + } catch (XMLDBException edb) { + logger.error("Failed to create collection " + collectionName, edb); + } finally { + this.writeLock.unlock(); + } + + return col; + } + + /** + * Delete the collection named PROPERTIES_COLLECTION_NAME from the storage + */ + public void deleteAllProperties() { + + this.writeLock.lock(); + try { + logger.info("Trying to delete the collection " + XMLStorageManager.PROPERTIES_COLLECTION_NAME + "..."); + CollectionManagementService mgtService = (CollectionManagementService) rootCollection.getService("CollectionManagementService", "1.0"); + mgtService.removeCollection(XMLStorageManager.PROPERTIES_COLLECTION_NAME); + logger.info("Collection deleted"); + } catch (XMLDBException edb) { + logger.warn("Unable to delete the collection " + XMLStorageManager.PROPERTIES_COLLECTION_NAME + ": " + edb.toString()); + } finally { + this.writeLock.unlock(); + } + } + + public String[] listAllPropertiesIDs() { + return listAllColletionIDs(this.loadPropertiesCollection()); + } + + private String[] listAllColletionIDs(Collection collection) { + String[] ids = null; + String collectionName = ""; + try { + collectionName = collection.getName(); + logger.debug("Retrieving all resource IDs from collection " + collectionName); + ids = new String[collection.getResourceCount()]; + ids = collection.listResources(); + logger.debug("Retrieved " + ids.length + " elements"); + } catch (XMLDBException edb) { + logger.warn("Unable to retrieve ids from collection " + collectionName + " " + edb.toString()); + } + return ids; + } + + /** + * Loads a file content in a String + * + * @param file + * path and name of the file to read + * @return the file content + * @throws IOException + */ + protected static String readFile(String file) throws IOException { + + BufferedReader f = new BufferedReader(new FileReader(file)); + String line; + StringBuffer content = new StringBuffer(); + while ((line = f.readLine()) != null) + content.append(line); + f.close(); + return content.toString(); + } + +} diff --git a/src/org/gcube/informationsystem/collector/impl/xmlstorage/exist/XQuery.java b/src/org/gcube/informationsystem/collector/impl/xmlstorage/exist/XQuery.java new file mode 100755 index 0000000..b4c6c31 --- /dev/null +++ b/src/org/gcube/informationsystem/collector/impl/xmlstorage/exist/XQuery.java @@ -0,0 +1,129 @@ +package org.gcube.informationsystem.collector.impl.xmlstorage.exist; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; + +import javax.xml.transform.OutputKeys; + + +import org.exist.xmldb.XQueryService; + +import org.xmldb.api.base.Collection; +import org.xmldb.api.base.CompiledExpression; +import org.xmldb.api.base.ResourceSet; + +import org.gcube.informationsystem.collector.impl.xmlstorage.exist.State; +import org.gcube.informationsystem.collector.impl.xmlstorage.exist.XQuery; + +import org.globus.wsrf.config.ContainerConfig; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + + + +/** + * Reads an XQuery file or string and executes it. + * + */ +public class XQuery { + + private String query_string = null; + + private static Log logger = LogFactory.getLog(XQuery.class.getName()); + + //testsuite constructor: TO REMOVE + public XQuery() throws IOException { + try { + this.query_string = this.getStaticQuery(); + } catch (Exception e) { + logger.error(State.logPrefix + "Unable to read the XQuery file"); + throw new IOException("Unable to read the XQuery file " + + e.getStackTrace()[0].toString()); + } + } + + public XQuery(String xquery) { + this.query_string = xquery; + } + + public XQuery(FileReader file) throws IOException { + try { + this.query_string = this.readFile(file); + } catch (IOException ioe) { + logger.error(State.logPrefix + "Unable to read the XQuery file"); + throw new IOException("Unable to read the XQuery file " + + ioe.getStackTrace()[0].toString()); + } + } + + /** + * Returns the xquery string + */ + public String toString() { + return this.query_string; + } + + /** + * Executes the query on the given base collection + * + * @param col + */ + public ResourceSet execute(Collection col) throws Exception { + + logger.info(State.logPrefix + "executing query on collection " + col.getName()); + + XQueryService service = (XQueryService) col.getService("XQueryService", "1.0"); + + // set pretty-printing on + service.setProperty(OutputKeys.INDENT, "yes"); + service.setProperty(OutputKeys.ENCODING, "UTF-8"); + + CompiledExpression compiled = service.compile(this.query_string); + + long start = System.currentTimeMillis(); + + // execute query and get results in ResourceSet + ResourceSet result = service.execute(compiled); + + long qtime = System.currentTimeMillis() - start; + start = System.currentTimeMillis(); + + /*Properties outputProperties = new Properties(); + outputProperties.setProperty(OutputKeys.INDENT, "yes"); + SAXSerializer serializer = (SAXSerializer) SerializerPool.getInstance().borrowObject(SAXSerializer.class); + serializer.setOutput(new OutputStreamWriter(System.out), outputProperties); + + SerializerPool.getInstance().returnObject(serializer); */ + //long rtime = System.currentTimeMillis() - start; + logger.info(State.logPrefix + "hits: " + result.getSize()); + logger.info(State.logPrefix + "query time: " + qtime + "ms"); + //logger.info(State.logPrefix + "retrieve time: " + rtime); + + return result; + } + + /** + * Reads the xquery file and return as string. + */ + protected String readFile(FileReader file) throws IOException { + BufferedReader f = new BufferedReader(file); + String line; + StringBuffer xml = new StringBuffer(); + while ((line = f.readLine()) != null) + xml.append(line + " "); + f.close(); + return xml.toString(); + } + /** + * Retrives the query from a local file + * + * @return the query + */ + private String getStaticQuery() throws Exception { + String file = ContainerConfig.getBaseDirectory() + "/etc/org_diligentproject_informationservice_disic/query-example.xq"; + return this.readFile(new FileReader(file)); + } + +} diff --git a/src/org/gcube/informationsystem/collector/testsuite/AFRegistrationSample.xml b/src/org/gcube/informationsystem/collector/testsuite/AFRegistrationSample.xml new file mode 100755 index 0000000..b4388ca --- /dev/null +++ b/src/org/gcube/informationsystem/collector/testsuite/AFRegistrationSample.xml @@ -0,0 +1,31 @@ + + + + + 600 + + + + + + + + 300000 + + + wssg:Entry + + + + + + + + diff --git a/src/org/gcube/informationsystem/collector/testsuite/Client.java b/src/org/gcube/informationsystem/collector/testsuite/Client.java new file mode 100644 index 0000000..02b14eb --- /dev/null +++ b/src/org/gcube/informationsystem/collector/testsuite/Client.java @@ -0,0 +1,105 @@ +/** + * + */ +package org.gcube.informationsystem.collector.testsuite; + + +import java.net.URL; +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; + +import org.gcube.informationsystem.collector.stubs.DeleteProfileParams; +import org.gcube.informationsystem.collector.stubs.XMLCollectionAccessPortType; +import org.gcube.informationsystem.collector.stubs.holders.VoidTypeHolder; +import org.gcube.informationsystem.collector.stubs.service.XMLCollectionAccessServiceAddressingLocator; + +/** + * + * DIS-IC client testsuite class + *
    + *
  1. to compile: javac -classpath MYPATH/org_diligentproject_informationservice_disic_stubs.jar:$CLASSPATH testsuite/Client.java + * + *
  2. to run (make sure that the DIS-IC stub classes are in your CLASSPATH): + *
+ *
    + *
  • DELETE ALL RPs: java -classpath MYPATH//org_diligentproject_informationservice_disic_stubs.jar:$CLASSPATH testsuite/Client deleteAllRPs http://MYHOST:MYPORT/wsrf/services/diligentproject/informationservice/disic/DISICService + * + *
  • DELETE A PROFILE: java -classpath MYPATH//org_diligentproject_informationservice_disic_stubs.jar:$CLASSPATH testsuite/Client deleteprofile http://MYHOST:MYPORT/wsrf/services/diligentproject/informationservice/disic/DISICService + * (allowed type are: "DHN", "RI", "SERVICE", "CS", "CSInstance", "Collection", "gLiteResource" + *
  • DELETE A RESOURCE: java -classpath MYPATH//lib/org_diligentproject_informationservice_disic_stubs.jar:$CLASSPATH testsuite/Client delete http://MYHOST:MYPORT/wsrf/services/diligentproject/informationservice/disic/DISICService + * + *
  • SEND A QUERY: java -classpath ./build/lib/org_diligentproject_informationservice_disic_stubs.jar:$CLASSPATH testsuite/Client query http://MYHOST:MYPORT/wsrf/services/diligentproject/informationservice/disic/DISICService + *
+ * + * @author manuele simi + * + * @version 1.0 July 2006 + * + * @link http://www.diligentproject.com + */ +public class Client { + + public Client() { + + } + + /** + * + * @param file the file that contains the query + * @return a String with the file content + * @throws IOException + */ + protected static String readFile(String file) throws IOException { + BufferedReader f = new BufferedReader(new FileReader(file)); + String line; + StringBuffer xml = new StringBuffer(); + while ((line = f.readLine()) != null) + xml.append(line + " "); + f.close(); + return xml.toString(); + } + + /** + * @param args + * 0 - the URI of an active DIS-IC service 1 - the file that + * contains the query to execute + */ +public static void main(String[] args) { + + XMLCollectionAccessServiceAddressingLocator locator = new XMLCollectionAccessServiceAddressingLocator(); + String uri = args[1]; + try { + + URL dis_ic_url = new URL(uri); + XMLCollectionAccessPortType ic = locator.getXMLCollectionAccessPortTypePort(dis_ic_url); + if (args[0].equalsIgnoreCase("delete")) { + ic.deleteResource(args[2]); + } + if (args[0].equalsIgnoreCase("deleteAllRPs")) { + ic.deleteAllRPs(new VoidTypeHolder()); + } + + if (args[0].equalsIgnoreCase("deleteprofile")) { + DeleteProfileParams prof = new DeleteProfileParams(); + prof.setID(args[2]); + prof.setProfileType(args[3]); + ic.deleteProfile(prof); + } + if (args[0].equalsIgnoreCase("query")) { + String query = Client.readFile(args[2]); + String resp = ic.executeXQuery(query); + System.out.println(resp); + } + if (args[0].equalsIgnoreCase("dispose")) { + ic.dispose(new VoidTypeHolder()); + } + if (args[0].equalsIgnoreCase("initialize")) { + ic.initialize(new VoidTypeHolder()); + } + } catch (Exception e) { + e.printStackTrace(); + } + + }// end main +} diff --git a/src/org/gcube/informationsystem/collector/testsuite/ServiceMap_CNRPrivate.xml b/src/org/gcube/informationsystem/collector/testsuite/ServiceMap_CNRPrivate.xml new file mode 100644 index 0000000..35ff6f5 --- /dev/null +++ b/src/org/gcube/informationsystem/collector/testsuite/ServiceMap_CNRPrivate.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/org/gcube/informationsystem/collector/testsuite/query-example.xq b/src/org/gcube/informationsystem/collector/testsuite/query-example.xq new file mode 100644 index 0000000..18557c0 --- /dev/null +++ b/src/org/gcube/informationsystem/collector/testsuite/query-example.xq @@ -0,0 +1,3 @@ +xquery version "1.0"; + + for $doc in collection("/db/Properties")//Document return $doc \ No newline at end of file