commit e96e9ddf13bdc28f82556a27e72c9ca52fd0e873 Author: Christian P. MOMON Date: Thu Jun 20 02:57:31 2013 +0200 First commit from split with devinsy-utils. diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..1899083 --- /dev/null +++ b/.classpath @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c80c6e0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/dist +/bin diff --git a/.project b/.project new file mode 100644 index 0000000..c9ea52e --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + kiss4web + + + + + + 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..c328801 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,291 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=next_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=next_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=next_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=next_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=next_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=next_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=next_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=next_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=next_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_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=false +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=80 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=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=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=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=tab +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 0000000..90b0130 --- /dev/null +++ b/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +formatter_profile=_Devinsy +formatter_settings_version=12 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/build.num b/build.num new file mode 100644 index 0000000..515c446 --- /dev/null +++ b/build.num @@ -0,0 +1,3 @@ +#Build Number for ANT. Do not edit! +#Thu Jun 20 02:51:05 CEST 2013 +build.number=5 diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..2637adc --- /dev/null +++ b/build.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/commons-codec-1.4.jar b/lib/commons-codec-1.4.jar new file mode 100644 index 0000000..458d432 Binary files /dev/null and b/lib/commons-codec-1.4.jar differ diff --git a/lib/commons-fileupload-1.2.1.jar b/lib/commons-fileupload-1.2.1.jar new file mode 100644 index 0000000..aa209b3 Binary files /dev/null and b/lib/commons-fileupload-1.2.1.jar differ diff --git a/lib/commons-io-1.4.jar b/lib/commons-io-1.4.jar new file mode 100644 index 0000000..133dc6c Binary files /dev/null and b/lib/commons-io-1.4.jar differ diff --git a/lib/devinsy-utils-0.1.4.jar b/lib/devinsy-utils-0.1.4.jar new file mode 100644 index 0000000..e50cdea Binary files /dev/null and b/lib/devinsy-utils-0.1.4.jar differ diff --git a/lib/log4j-1.2.14.jar b/lib/log4j-1.2.14.jar new file mode 100644 index 0000000..6251307 Binary files /dev/null and b/lib/log4j-1.2.14.jar differ diff --git a/lib/servlet-api.jar b/lib/servlet-api.jar new file mode 100644 index 0000000..dd326d3 Binary files /dev/null and b/lib/servlet-api.jar differ diff --git a/src/fr/devinsy/kiss4web/CookieHelper.java b/src/fr/devinsy/kiss4web/CookieHelper.java new file mode 100644 index 0000000..49328bb --- /dev/null +++ b/src/fr/devinsy/kiss4web/CookieHelper.java @@ -0,0 +1,176 @@ +package fr.devinsy.kiss4web; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + +/** + * + */ +public class CookieHelper +{ + static protected org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (CookieHelper.class); + + /** + * + */ + static public Cookie buildCookie (String name, String value, int duration, boolean isSecure) + { + Cookie result; + + result = new Cookie (name, value); + result.setMaxAge (duration); + result.setPath ("/"); + result.setSecure (isSecure); + + // + return (result); + } + + + /** + * + */ + static public Cookie buildCookie (String name, String value, int duration) + { + Cookie result; + + result = buildCookie(name, value, duration, false); + + // + return (result); + } + + + /** + * + */ + static public Cookie getCookie (Cookie[] cookies, String key) + { + Cookie result = null; + + if (cookies == null) + { + result = null; + } + else + { + boolean ended = false; + int cookieCounter = 0; + while (!ended) + { + if (cookieCounter < cookies.length) + { + if (key.equals (cookies[cookieCounter].getName ())) + { + ended = true; + result = cookies[cookieCounter]; + } + else + { + cookieCounter += 1; + } + } + else + { + ended = true; + result = null; + } + } + } + + // + return (result); + } + + + /** + * + */ + static public Cookie getCookie (HttpServletRequest request, String key) + { + Cookie result = null; + + result = getCookie(request.getCookies (), key); + + // + return(result); + } + + + /** + * + */ + static public Object getCookieValue (Cookie[] cookies, String key) + { + Object result; + + Cookie cookie = getCookie(cookies, key); + + if (cookie == null) + { + result = null; + } + else + { + result = cookie.getValue(); + } + + // + return(result); + } + + + /** + * + */ + static public Object getCookieValue (HttpServletRequest request, String key) + { + Object result; + + result = getCookieValue (request.getCookies (), key); + + // + return(result); + } + + + /** + * + */ + static public boolean exists(HttpServletRequest request, String key) + { + boolean result; + + if (getCookieValue(request, key) == null) + { + result = false; + } + else + { + result = true; + } + + // + return(result); + } + + + /** + * + */ + static public void set (HttpServletResponse response, String name, String value, int duration) + { + response.addCookie (buildCookie(name, value, duration)); + } + + + /** + * + */ + static public void reset (HttpServletResponse response, String key) + { + response.addCookie(buildCookie(key, "", 0)); + } +} \ No newline at end of file diff --git a/src/fr/devinsy/kiss4web/Page.java b/src/fr/devinsy/kiss4web/Page.java new file mode 100644 index 0000000..528b1a8 --- /dev/null +++ b/src/fr/devinsy/kiss4web/Page.java @@ -0,0 +1,18 @@ +package fr.devinsy.kiss4web; +import java.io.*; +import javax.servlet.*; +import javax.servlet.http.*; + + + +/** + * + */ +public interface Page +{ + /** + * + */ + public void doIt (HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException; +} diff --git a/src/fr/devinsy/kiss4web/PageManager.java b/src/fr/devinsy/kiss4web/PageManager.java new file mode 100644 index 0000000..6824fd4 --- /dev/null +++ b/src/fr/devinsy/kiss4web/PageManager.java @@ -0,0 +1,399 @@ +package fr.devinsy.kiss4web; + +import java.io.*; +import javax.servlet.*; +import javax.servlet.http.*; +import fr.devinsy.kiss4web.security.*; + +/** + * + */ +public class PageManager extends HttpServlet +{ + private static final long serialVersionUID = 1983715791417570578L; + private static PageManager instance = null; + protected SecurityAgent securityAgent; + + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (PageManager.class); + + /** + * + */ + public void init () throws ServletException + { + // + instance = this; + + try + { + this.securityAgent = new SecurityAgent (getInitParameter ("securityDataPath")); + } + catch (Exception exception) + { + throw new ServletException("SecurityAgent initialization failed.", exception); + } + } + + /** + * + */ + public static PageManager instance () + { + return instance; + } + + /** + * + */ + static public String buildClassName (String pathInfo) + { + String result; + result = null; + + if ( pathInfo.equals ("/")) + { + result = "Accueil"; + } + else + { + String[] tokens = pathInfo.split ("/"); + StringBuffer name = new StringBuffer (); + + for (int tokenCounter = 1; tokenCounter < tokens.length - 1; tokenCounter++) + { + name.append (tokens[tokenCounter]); + name.append ('.'); + } + + if (pathInfo.endsWith ("/")) + { + name.append (tokens[tokens.length - 1]); + name.append ('.'); + } + + logger.info ("==>[" + tokens[tokens.length - 1] + "]"); + name.append (formatClassName (tokens[tokens.length - 1])); + + result = name.toString (); + } + + // + return (result); + } + + /** + * + */ + static public String buildClassName2 (String pathInfo) + { + String result; + + if (pathInfo.endsWith (".xhtml")) + { + char[] source = pathInfo.toCharArray (); + + StringBuffer out = new StringBuffer (); + for (char c : source) + { + out.append ("[" + c + "]"); + } + logger.debug (out.toString ()); + + char[] target = new char[source.length - 7]; + int lastStartToken = 0; + for (int nChar = 1; nChar < source.length - 5; nChar++) + { + char charSource = source[nChar]; + switch (charSource) + { + case '/': + target[nChar - 1] = '.'; + lastStartToken = nChar; + break; + + case '.': + target[lastStartToken] = Character.toUpperCase (target[lastStartToken]); + break; + + default: + target[nChar - 1] = source[nChar]; + } + } + + out = new StringBuffer (); + for (char c : target) + { + out.append ("[" + c + "]"); + } + logger.debug (out.toString ()); + + result = new String (target); + } + else if (pathInfo.equals ("/")) + { + result = "Accueil"; + } + else if (pathInfo.endsWith ("/")) + { + char[] source = pathInfo.toCharArray (); + + StringBuffer out = new StringBuffer (); + for (char c : source) + { + out.append ("[" + c + "]"); + } + logger.debug (out.toString ()); + + char[] target = new char[source.length - 2]; + int lastStartToken = 0; + for (int nChar = 1; nChar < source.length - 1; nChar++) + { + char charSource = source[nChar]; + switch (charSource) + { + case '/': + target[nChar - 1] = '.'; + lastStartToken = nChar + 1; + break; + + default: + target[nChar - 1] = source[nChar]; + } + } + + char[] targetPlus = new char [source.length - lastStartToken]; + targetPlus[0] = '.'; + targetPlus[1] = Character.toUpperCase (source[lastStartToken]); + int index = 2; + for (int nChar = lastStartToken + 1; nChar < source.length - 1; nChar++) + { + targetPlus[index] = source[nChar]; + index += 1; + } + + out = new StringBuffer (); + for (char c : target) + { + out.append ("[" + c + "]"); + } + logger.debug (out.toString ()); + out = new StringBuffer (); + for (char c : targetPlus) + { + out.append ("[" + c + "]"); + } + logger.debug (out.toString ()); + + result = new String (target) + new String (targetPlus); + } + else + { + logger.debug ("unknow case"); + result = null; + } + + // + return (result); + } + + + /** + */ + public Page instanciatePage (String className) + { + Page result; + + Class pageClass = null; + try + { + pageClass = (Class) Class.forName (className); + } + catch (java.lang.ClassNotFoundException exception) + { + result = null; + } + + logger.info ("class=" + pageClass); + + if (pageClass == null) + { + result = null; + logger.error ("Unknow page: (" + className + ")"); + } + else + { + try + { + result = pageClass.newInstance (); + } + catch (java.lang.InstantiationException exception) + { + logger.error ("Can't instanciate page (" + className + ")"); + result = null; + } + catch (java.lang.IllegalAccessException exception) + { + logger.error ("(2) Can't instanciate page (" + className + ")"); + result = null; + } + } + + // + return (result); + } + + /** + * + */ + public void doGet (HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException + { + logger.info ("=================================================="); + logger.info ("getContextPath=[" + request.getContextPath () + "]"); + logger.info ("getPathInfo=[" + request.getPathInfo () + "]"); + logger.info ("getPathTranslated=[" + request.getPathTranslated () + "]"); + logger.info ("getQueryString=[" + request.getQueryString () + "]"); + logger.info ("getRequestURI=[" + request.getRequestURI () + "]"); + logger.info ("getRequestURL=[" + request.getRequestURL () + "]"); + logger.info ("getServletPath=[" + request.getServletPath () + "]"); + + String className = buildClassName (request.getPathInfo ()); + logger.info ("className=" + className); + + Page page = this.instanciatePage ("site." + className); + + if (page == null) + { + response.setContentType ("text/html"); + PrintWriter out = response.getWriter(); + + out.println ("Unknow page."); + } + else + { + HttpSession session = request.getSession (false); + String login; + if (session == null) + { + login = null; + } + else + { + login = (String) session.getAttribute ("login"); + } + + if (this.securityAgent.checkPermission (request.getPathInfo (), login)) + { + page.doIt (request, response); + logger.info ("securityAgent say 'permission OK': (" + login + ", " + request.getPathInfo () + ")"); + } + else + { + logger.info ("securityAgent say 'permission KO': (" + login + ", " + request.getPathInfo () + ")"); + + if (login == null) + { + response.sendRedirect ("/gestion/login.xhtml"); + } + else + { + response.setContentType ("text/html"); + PrintWriter out = response.getWriter(); + + out.println (""); + out.println ("Permission denied."); + out.println ("
"); + out.println (" "); + out.println ("
"); + out.println (""); + } + } + } + } + + + /** + * + */ + public void doPost (HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException + { + doGet (request, response); + } + + + /** + * + */ + static public String formatClassName (String name) + { + String result; + + result = null; + + String[] splittedLastToken = name.split ("\\."); + String last = splittedLastToken[0]; + //logger.info ("last=" + last); + + String[] tokens = last.split ("_"); + StringBuffer all = new StringBuffer (); + for (String token : tokens) + { + //logger.info ("tok=" + token); + + all.append (Character.toUpperCase (token.charAt (0))); + all.append (token.substring (1)); + } + + result = all.toString (); + + // + return (result); + } + + + /** + * + */ + public SecurityAgent securityAgent () + { + SecurityAgent result; + + result = this.securityAgent; + + // + return (result); + } + + + /** + * + */ + static public User getUserFromSession (HttpServletRequest request) + { + User result; + + if (request == null) + { + result = null; + } + else + { + HttpSession session = request.getSession (false); + + String login; + if (session == null) + { + result = null; + } + else + { + login = (String) session.getAttribute ("login"); + result = PageManager.instance ().securityAgent ().users ().getByLogin (login); + } + } + + // + return (result); + } +} diff --git a/src/fr/devinsy/kiss4web/ServletDispatcher.java b/src/fr/devinsy/kiss4web/ServletDispatcher.java new file mode 100755 index 0000000..8bb54fa --- /dev/null +++ b/src/fr/devinsy/kiss4web/ServletDispatcher.java @@ -0,0 +1,71 @@ +/** + * @author Christian Momon, June 2008. + * This file is free software under the terms of the GNU Library General Public License + * as published by the Free Software Foundation version 2 or any later version. + */ + +package fr.devinsy.kiss4web; + +import java.io.*; +import javax.servlet.*; +import javax.servlet.http.*; + + + +/** + * + */ +public class ServletDispatcher extends SimpleServletDispatcher +{ + private static final long serialVersionUID = -3471226305721330069L; + protected org.apache.log4j.Logger logger; + //protected Servlets servlets; + + + /** + * + */ + public void init () throws ServletException + { + super.init(); + this.logger = org.apache.log4j.Logger.getLogger (this.getClass()); + //this.servlets = new Servlets(); + } + + + /** + * + */ + public void doIt (HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + logger.info ("=================================================="); + logger.info ("getContextPath=[" + request.getContextPath () + "]"); + logger.info ("getPathInfo=[" + request.getPathInfo () + "]"); + logger.info ("getPathTranslated=[" + request.getPathTranslated () + "]"); + logger.info ("getQueryString=[" + request.getQueryString () + "]"); + logger.info ("getRequestURI=[" + request.getRequestURI () + "]"); + logger.info ("getRequestURL=[" + request.getRequestURL () + "]"); + logger.info ("getServletPath=[" + request.getServletPath () + "]"); + + String className = pathInfoToClassName (request.getPathInfo ()); + logger.info ("className=" + className); + + HttpServlet servlet = instanciateServlet (className); + + if (servlet == null) + { + response.setContentType ("text/html"); + PrintWriter out = response.getWriter(); + + out.println (""); + out.println ("Unknow page."); + out.println (""); + + out.close(); + } + else + { + servlet.service(request, response); + } + } +} diff --git a/src/fr/devinsy/kiss4web/SimpleServletDispatcher.java b/src/fr/devinsy/kiss4web/SimpleServletDispatcher.java new file mode 100755 index 0000000..c32eb48 --- /dev/null +++ b/src/fr/devinsy/kiss4web/SimpleServletDispatcher.java @@ -0,0 +1,666 @@ +/** + * @author Christian Momon, June 2008. This file is free software under the + * terms of the GNU Library General Public License as published by the + * Free Software Foundation version 2 or any later version. + */ + +package fr.devinsy.kiss4web; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import fr.devinsy.util.StringList; + +/** + * + */ +public class SimpleServletDispatcher extends HttpServlet +{ + private static final long serialVersionUID = -3471226305721330069L; + static protected org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(ServletDispatcher.class); + + static final protected Pattern SHORT_REWRITED_URL_CLASS = Pattern.compile("^([^-]+)-.+\\.xhtml$"); + static final protected Pattern SHORT_REWRITED_URL_PARAMETERS = Pattern.compile("^[^-]+-(.+)\\.xhtml$"); + static final protected Pattern LONG_REWRITED_URL_CLASS = Pattern.compile("^([^-]+)-/.*$"); + // static final protected Pattern LONG_REWRITED_URL_PARAMETERS = + // Pattern.compile("^.+-/(.)+*$"); + static final protected Pattern REWRITE_PARAMETER = Pattern.compile("[^%\\w\\d]"); + + protected String webclassesRootPath; + + /** + * "Code can be shortest, speedest and memory smallest, but not the three in same time, only two" + * , unknow citation. + * + * Note: characters array avalaible here + * http://fr.wikipedia.org/wiki/Table_des_caract + * %C3%A8res_Unicode_%280000-0FFF%29 + */ + static protected char NONE = (char) 0; + + static protected int[] rewritingParameterMapping = { + /* 00 */NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + /* 10 */NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + /* 20 */'-', NONE, NONE, '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', + /* 30 */'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '-', '-', '-', '-', '-', + /* 40 */'\u0040', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + /* 50 */'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '-', '-', '-', '-', '-', + /* 60 */'-', '\u0061', '\u0062', '\u0063', '\u0064', '\u0065', '\u0066', '\u0067', '\u0068', '\u0069', '\u006A', '\u006B', '\u006C', '\u006D', '\u006E', + '\u006F', + /* 70 */'\u0070', '\u0071', '\u0072', '\u0073', '\u0074', '\u0075', '\u0076', '\u0077', '\u0078', '\u0079', '\u007A', '\u007B', '\u007C', '\u007D', + '-', '-', + /* 80 */NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + /* 90 */NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + /* A0 */'\u00A0', '\u00A1', '\u00A2', '\u00A3', '\u00A4', '\u00A5', '\u00A6', '\u00A7', '\u00A8', '\u00A9', '\u00AA', '\u00AB', '\u00AC', '\u00AD', + '\u00AE', '\u00AF', + /* B0 */'-', '\u00B1', '\u00B2', '\u00B3', '\u00B4', '\u00B5', '\u00B6', '\u00B7', '\u00B8', '\u00B9', '\u00BA', '\u00BB', '\u00BC', '\u00BD', + '\u00BE', '\u00BF', + /* C0 */'a', 'a', 'a', 'a', 'a', 'a', 'a', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', + /* D0 */'\u00D0', '\u00D1', 'o', 'o', 'o', 'o', 'o', 'o', '\u00D8', 'u', 'u', 'u', 'u', 'y', '\u00DE', '\u00DF', + /* E0 */'a', 'a', 'a', 'a', 'a', 'a', 'a', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', + /* F0 */'o', 'n', 'o', 'o', 'o', 'o', 'o', '\u00F7', '-', 'u', 'u', 'u', 'u', 'y', '-', 'y' }; + + /** + * + */ + @Override + public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException + { + doIt(request, response); + } + + /** + * + * + */ + public void doIt(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException + { + logger.info("=================================================="); + logger.info("getContextPath=[" + request.getContextPath() + "]"); + logger.info("getPathInfo=[" + request.getPathInfo() + "]"); + logger.info("getPathTranslated=[" + request.getPathTranslated() + "]"); + logger.info("getQueryString=[" + request.getQueryString() + "]"); + logger.info("getRequestURI=[" + request.getRequestURI() + "]"); + logger.info("getRequestURL=[" + request.getRequestURL() + "]"); + logger.info("getServletPath=[" + request.getServletPath() + "]"); + + // + /* + * In past, possibility to use the servlet path was enable. It is too + * complexe, not kiss mind. String path; if (request.getPathInfo() == + * null) { // web.xml url-pattern= *.xhtml path = + * request.getServletPath(); } else { // web.xml url-pattern = /* path = + * request.getPathInfo(); } + */ + // String path = request.getRequestURI(); + String path = request.getPathInfo(); + + if ((!path.endsWith("/")) && (!path.endsWith(".xhtml")) && (!path.contains("-/"))) + { + // path = getServletContext().getRealPath("/") + + // request.getRequestURI(); + path = getServletContext().getRealPath("/") + request.getPathInfo(); + + returnInlineFile(response, new File(path), getServletContext().getMimeType(path)); + logger.info("File returned directly [" + path + "] with mimetype [" + getServletContext().getMimeType(path) + "]."); + } + else + { + String className = pathInfoToClassName(path, this.webclassesRootPath); + logger.info("className=[" + className + "]"); + + HttpServlet servlet = instanciateServlet(className); + + // servlet.getServletContext().setAttribute(arg0, arg1); + + if (servlet == null) + { + response.setContentType("text/html"); + PrintWriter out = response.getWriter(); + + out.println(""); + out.println("Unknow page."); + out.println(""); + + out.close(); + } + else if (isAuthorized(request, response)) + { + servlet.init(this.getServletConfig()); + servlet.service(request, response); + } + else + { + /* + * TODO // response.setContentType ("text/html"); PrintWriter + * out = response.getWriter(); + * + * out.println (""); out.println + * ("Not authorized page."); out.println (""); + */ + } + } + } + + /** + * + */ + @Override + public void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException + { + doIt(request, response); + } + + /** + * + */ + @Override + public void init() throws ServletException + { + super.init(); + this.webclassesRootPath = getInitParameter("webClassesRootPath"); + + // Set logger. + String logFilepathname = getInitParameter("log4j-init-file"); + if (logFilepathname != null) + { + try + { + System.out.println("Log configuration found (" + logFilepathname + "), will use it."); + org.apache.log4j.PropertyConfigurator.configure(getServletContext().getRealPath("/") + logFilepathname); + } + catch (Exception exception) + { + System.out.println("Log configuration FILE NOT FOUND (" + logFilepathname + "), use of the basic configurator."); + org.apache.log4j.BasicConfigurator.configure(); + } + + logger = org.apache.log4j.Logger.getLogger(this.getClass()); + logger.info("Log initialization done."); + } + } + + /** + * + */ + public boolean isAuthorized(final HttpServletRequest request, final HttpServletResponse response) + { + boolean result; + + result = true; + + // + return (result); + } + + /** + * + */ + static public HttpServlet instanciateServlet(final String className) + { + HttpServlet result; + + Class servletClass = null; + try + { + servletClass = (Class) Class.forName(className); + } + catch (java.lang.ClassNotFoundException exception) + { + result = null; + } + + logger.info("class=" + servletClass); + + if (servletClass == null) + { + result = null; + logger.error("Unknow page: (" + className + ")"); + } + else + { + try + { + result = servletClass.newInstance(); + } + catch (java.lang.InstantiationException exception) + { + logger.error("Can't instanciate servlet (" + className + ")"); + result = null; + } + catch (java.lang.IllegalAccessException exception) + { + logger.error("(2) Can't instanciate servlet (" + className + ")"); + result = null; + } + } + + // + return (result); + } + + /** + * Extract values from a path. Example: "/article-/123/doors/open.xhtml" => + * "123", "doors" and "open". + */ + static public String[] longRewritedUrlParameters(final String path) + { + String[] result; + + result = path.substring(path.indexOf("-/") + 2).split("/"); + + // + return (result); + } + + /** + * Convert a path in a class name, using easy conventions. + * + * "/" => "Index_xhtml" "/good/" => "good.Good_xhtml" "/good/morning.xhtml" + * => "good.Morning_xhtml" "/good/morning_girl.xhtml" => + * "good.Morning_girl_xhtml" "/good/morning-123.xhtml" => + * "good.Morning_xhtml" ('123' is detected as a parameter, it will be + * decoded in the class called later). "/good/morning-/12/toto.jpg" => + * "good.Morning" ('12' and 'toto.jpg" are detected as a parameter, they + * will be decoded in the class called later). + */ + static public String pathInfoToClassName(final String pathInfo) + { + String result; + + if ((pathInfo == null) || (pathInfo.length() == 0)) + { + result = null; + } + else + { + if (pathInfo.equals("/")) + { + result = "Index_xhtml"; + } + else + { + int keywordIndex = pathInfo.lastIndexOf("-/"); + + if (keywordIndex != -1) + { + // Long rewrited URL case. + String[] tokens = pathInfo.substring(0, keywordIndex).split("/"); + + StringList name = new StringList(); + // Note: as pathInfo starts always with a '/', the first + // good token index is 1. + for (int tokenCounter = 1; tokenCounter < (tokens.length - 1); tokenCounter++) + { + name.append(tokens[tokenCounter]); + name.append('.'); + } + + String lastToken = tokens[tokens.length - 1]; + name.append(lastToken.substring(0, 1).toUpperCase()).append(lastToken.substring(1).replace('.', '_')); + result = name.toString(); + } + else + { + String[] tokens = pathInfo.split("/"); + + StringList name = new StringList(); + // Note: as pathInfo starts always with a '/', the first + // good token index is 1. + for (int tokenCounter = 1; tokenCounter < (tokens.length - 1); tokenCounter++) + { + name.append(tokens[tokenCounter]); + name.append('.'); + } + + String lastToken = tokens[tokens.length - 1]; + if (pathInfo.endsWith("/")) + { + name.append(lastToken).append(".").append(lastToken.substring(0, 1).toUpperCase()).append(lastToken.substring(1)).append("_xhtml"); + } + else + { + Matcher matcher = SHORT_REWRITED_URL_CLASS.matcher(lastToken); + if (matcher.matches()) + { + // Short rewrited URL case. + // logger.debug("group 1=[" + matcher.group(1) + + // "]"); + lastToken = matcher.group(1) + ".xhtml"; + } + + name.append(lastToken.substring(0, 1).toUpperCase()).append(lastToken.substring(1).replace('.', '_')); + } + + result = name.toString(); + logger.debug("==>[" + tokens[tokens.length - 1] + "]"); + } + } + } + + logger.info("[" + pathInfo + "] => [" + result + "]"); + + // + return (result); + } + + /** + * + */ + static public String pathInfoToClassName(final String pathInfo, final String prefix) + { + String result; + + String className = pathInfoToClassName(pathInfo); + + if (prefix == null) + { + result = className; + } + else if (prefix.endsWith(".")) + { + result = prefix + className; + } + else + { + result = prefix + "." + className; + } + + // + return (result); + } + + /** + * + */ + static public void returnAttachmentFile(final HttpServletResponse response, final File file, final String mimeType) throws IOException + { + returnFile(response, file, mimeType, true); + } + + /** + * + */ + static public void returnFile(final HttpServletResponse response, final File file, final String mimeType, final boolean isAttachment) throws IOException + { + + if ((file == null) || (!file.exists())) + { + response.sendError(HttpServletResponse.SC_NOT_FOUND); + } + else + { + /* + * response.setContentType("application/" + extension); + * response.setContentLength((int) data.length); + * response.setHeader("Content-Disposition" + * ,"attachment; filename=\"" + filename + "\""); + * response.flushBuffer(); + */ + response.reset(); + response.setContentType(mimeType); + response.setContentLength((int) file.length()); + response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\""); + response.flushBuffer(); + + ServletOutputStream out = response.getOutputStream(); + + FileInputStream in = null; + try + // Only for the in. + { + byte[] buffer = new byte[64 * 1024]; + + in = new FileInputStream(file); + boolean ended = false; + while (!ended) + { + int count = in.read(buffer); + + if (count == -1) + { + ended = true; + } + else + { + out.write(buffer, 0, count); + } + } + out.flush(); + out.close(); + } + catch (IOException exception) + { + response.sendError(HttpServletResponse.SC_PARTIAL_CONTENT); + } + finally + { + if (in != null) + { + in.close(); + } + } + } + } + + /** + * + */ + static public void returnInlineFile(final HttpServletResponse response, final File file, final String mimeType) throws IOException + { + returnFile(response, file, mimeType, false); + } + + /** + * + */ + static public String[] rewritedUrlParameters(final HttpServletRequest request) + { + String[] result; + + result = longRewritedUrlParameters(request.getRequestURI()); + + // + return (result); + } + + /** + * This method gives a way for a long rewriting URL format. Long as in REST. + * + * Sometimes, URL has to be rewrited because we need to put parameter in the + * page name. + * + * Example: "/good/give_file?id=123&filename=foo.jpg" => + * rewriteShorturl("/good/give_file", "123", "foo.jpg"); => + * "/good/give_file-/123/foo.jpg" + * + * Note: "-/" is used to indicate the start of parameters. + * + */ + static public String rewriteLongUrl(final String uri, final String... parameters) + { + String result; + + StringList string = new StringList(); + + string.append(uri).append("-"); + if ((parameters == null) || (parameters.length == 0)) + { + string.append("/"); + } + else + { + for (String parameter : parameters) + { + string.append("/").append(parameter); + } + } + + result = string.toString(); + + // + return (result); + } + + /** + * + * + * @param parameter + * @return + */ + static String rewriteParameter(final String parameter) + { + String result; + + StringBuffer buffer = new StringBuffer(parameter.length()); + + char previousCar = NONE; + for (int charIndex = 0; charIndex < parameter.length(); charIndex++) + { + // logger.info("" + charIndex + " " + parameter.charAt(charIndex) + + // " " + (char) tab[parameter.charAt(charIndex)]); + char car = (char) rewritingParameterMapping[parameter.charAt(charIndex)]; + if (car != NONE) + { + if ((car != '-') || ((car == '-') && (previousCar != '-'))) + { + buffer.append(car); + previousCar = car; + } + } + } + + if (buffer.charAt(buffer.length() - 1) == '-') + { + buffer.setLength(buffer.length() - 1); + } + + result = buffer.toString(); + logger.info("[" + parameter + "] -> [" + result + "]"); + // + return (result); + } + + /** + * This method gives a way for a short rewriting URL format. + * + * Sometimes, URL has to be rewrited because we need to put parameter in the + * page name. + * + * Example: "/good/article.xhtm?id=123&class=today&title=story's about me" + * => rewriteShorturl("/good/article", "xhtml", "123", "Story's aboute me"); + * => "/good/article-123-today-story-s-about-me.xhtml" + */ + static public String rewriteShortUrl(final String uri, final String extension, final String... parameters) + { + String result; + + StringList string = new StringList(); + + string.append(uri); + + for (String parameter : parameters) + { + // Not use of String.replaceAll() method in goal to optimize Pattern + // compile action. + // string.append("-").append(REWRITE_PARAMETER.matcher(parameter.toLowerCase()).replaceAll("-")); + string.append("-").append(rewriteParameter(parameter)); + } + + if ((extension != null) && (extension.length() != 0)) + { + string.append(".").append(extension); + } + + result = string.toString(); + + // + return (result); + } + + /** + * + */ + static public String shortRewritedUrlParameter(final HttpServletRequest request) + { + String result; + + result = shortRewritedUrlParameter(request.getRequestURI()); + + // + return (result); + } + + /** + * Return value of the first parameter. + */ + static public String shortRewritedUrlParameter(final String path) + { + String result; + + String[] results = shortRewritedUrlParameters(path); + + if ((results == null) || (results.length == 0)) + { + result = null; + } + else + { + result = results[0]; + } + + // + return (result); + } + + /** + * + */ + static public String[] shortRewritedUrlParameters(final HttpServletRequest request) + { + String[] result; + + result = shortRewritedUrlParameters(request.getRequestURI()); + + // + return (result); + } + + /** + * Extract value from a path. Example: "/article-123.xhtml" => "123". + */ + static public String[] shortRewritedUrlParameters(final String path) + { + String[] result; + + Matcher matcher = SHORT_REWRITED_URL_PARAMETERS.matcher(path); + if (matcher.matches()) + { + if (matcher.groupCount() != 1) + { + result = null; + } + else + { + result = matcher.group(1).split("-"); + } + } + else + { + result = null; + } + + // + return (result); + } +} diff --git a/src/fr/devinsy/kiss4web/security/Group.java b/src/fr/devinsy/kiss4web/security/Group.java new file mode 100644 index 0000000..59749e0 --- /dev/null +++ b/src/fr/devinsy/kiss4web/security/Group.java @@ -0,0 +1,105 @@ +package fr.devinsy.kiss4web.security; + + +import java.util.*; + +/** + * + */ +public class Group +{ + protected String name; + protected Vector members; + + + /** + * + */ + public Group () + { + this.name = null; + this.members = new Vector (); + } + + + /** + * + */ + public void addMember (String login) + { + if ((login != null) && (login.length () != 0)) + { + this.members.add (login); + } + } + + + /** + * + */ + public boolean contains (String name) + { + boolean result = false; + + result = this.members.contains (name); + + // + return (result); + } + + + /** + * + */ + public Vector members () + { + Vector result; + + result = this.members; + + // + return (result); + } + + + /** + * + */ + public String name () + { + String result; + + result = this.name; + + // + return (result); + } + + + /** + * + */ + public Group setName (String name) + { + this.name = name; + + // + return (this); + } + + + /** + * + */ + public String toString () + { + String result; + + result = "|" + this.name + "|" + this.members + "|"; + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// diff --git a/src/fr/devinsy/kiss4web/security/Groups.java b/src/fr/devinsy/kiss4web/security/Groups.java new file mode 100644 index 0000000..1cfdfd1 --- /dev/null +++ b/src/fr/devinsy/kiss4web/security/Groups.java @@ -0,0 +1,163 @@ +package fr.devinsy.kiss4web.security; + + +import java.util.*; + +/** + * + */ +public class Groups extends Vector +{ + private static final long serialVersionUID = 6238581648850758903L; + + /** + * + */ + public Groups () + { + super (); + } + + + /** + * + */ + public Group get (String name) + { + Group result; + + if (name == null) + { + result = null; + } + else + { + result = null; + boolean ended = false; + Iterator iterator = this.iterator (); + while (!ended) + { + if (iterator.hasNext ()) + { + Group group = iterator.next (); + if (group.name ().equals (name)) + { + ended = true; + result = group; + } + } + else + { + ended = true; + result = null; + } + } + } + + // + return (result); + } + + + /* + * + */ + public boolean contains (String name) + { + boolean result; + + if (get (name) == null) + { + result = false; + } + else + { + result = true; + } + + // + return (result); + } + + + /** + * + */ + public Vector getLoginGroups (String login) + { + Vector result; + + result = new Vector (); + Iterator iterator = this.iterator (); + + while (iterator.hasNext ()) + { + Group group = iterator.next (); + + if (group.members ().contains (login)) + { + result.add (group.name ()); + } + } + + // + return (result); + } + + + /** + * + */ + public String getLoginGroupsString (String login) + { + String result; + + Vector groups = getLoginGroups (login); + + StringBuffer string = new StringBuffer (); + + for (String group : groups) + { + if (string.length () == 0) + { + string.append (group); + } + else + { + string.append (","); + string.append (group); + } + } + + result = string.toString (); + + // + return (result); + } + + + /** + * + */ + public String toString () + { + String result; + + StringBuffer out; + out = new StringBuffer (); + + Iterator iterator = this.iterator (); + + while (iterator.hasNext ()) + { + out.append (iterator.next ().toString () + "\n"); + } + + result = out.toString (); + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// diff --git a/src/fr/devinsy/kiss4web/security/GroupsFileReader.java b/src/fr/devinsy/kiss4web/security/GroupsFileReader.java new file mode 100644 index 0000000..ab44853 --- /dev/null +++ b/src/fr/devinsy/kiss4web/security/GroupsFileReader.java @@ -0,0 +1,55 @@ +package fr.devinsy.kiss4web.security; + +import java.io.*; +import java.util.*; + + +/** + * + */ +public class GroupsFileReader +{ + /** + * + */ + static public Groups load (String fileName) throws Exception + { + Groups result; + + result = new Groups (); + + Properties properties = new Properties(); + try + { + properties.load (new FileInputStream(fileName)); + + Iterator iterator = properties.keySet ().iterator (); + while (iterator.hasNext ()) + { + String key = (String) iterator.next (); + String valueLine = (String) properties.get (key); + + // + String[] values = valueLine.split (","); + + Group group = new Group (); + group.setName (key); + for (String value : values) + { + group.addMember (value.trim ()); + } + + result.add (group); + } + } + catch (Exception exception) + { + throw new Exception ("can't load (" + fileName + ")", exception); + } + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// diff --git a/src/fr/devinsy/kiss4web/security/SecurityAgent.java b/src/fr/devinsy/kiss4web/security/SecurityAgent.java new file mode 100644 index 0000000..72a926b --- /dev/null +++ b/src/fr/devinsy/kiss4web/security/SecurityAgent.java @@ -0,0 +1,151 @@ +package fr.devinsy.kiss4web.security; + + +import java.util.*; + + + +/** + * + */ +public class SecurityAgent +{ + protected Users users; + protected Groups groups; + protected Groups permissions; + + + /** + * + */ + public SecurityAgent (String path) throws Exception + { + this.users = UsersFileReader.load (path + "users.conf"); + this.groups = GroupsFileReader.load (path + "groups.conf"); + this.permissions = GroupsFileReader.load (path + "permissions.conf"); + } + + + /** + * + */ + public Groups groups () + { + Groups result; + + result = this.groups; + + // + return (result); + } + + /** + * + */ + public Groups permissions () + { + Groups result; + + result = this.permissions; + + // + return (result); + } + + /** + * + */ + public Users users () + { + Users result; + + result = this.users; + + // + return (result); + } + + /** + * + */ + public boolean authenticate (String login, String password) + { + boolean result; + + User user = this.users.getByLogin (login); + + if (user == null) + { + result = false; + } + else if (user.password ().equals (password)) + { + result = true; + } + else + { + result = false; + } + + // + return (result); + } + + /** + * + */ + public boolean checkPermission (String url, String login) + { + boolean result = false; + + Group permitGroups = this.permissions.get (url); + + if (permitGroups == null) + { + result = false; + } + else + { + // + boolean ended = false; + Iterator iterator = permitGroups.members ().iterator (); + while (!ended) + { + if (!iterator.hasNext ()) + { + ended = true; + result = false; + } + else + { + String groupName = iterator.next (); + if (groupName.equals ("*")) + { + result = true; + ended = true; + } + else + { + Group members = this.groups.get (groupName); + + if (members == null) + { + result = false; + } + else + { + if (members.contains (login)) + { + ended = true; + result = true; + } + } + } + } + } + } + + // + return (result); + } +} diff --git a/src/fr/devinsy/kiss4web/security/User.java b/src/fr/devinsy/kiss4web/security/User.java new file mode 100644 index 0000000..0054a75 --- /dev/null +++ b/src/fr/devinsy/kiss4web/security/User.java @@ -0,0 +1,139 @@ +package fr.devinsy.kiss4web.security; + + + + +/** + * + */ +public class User +{ + protected String login; + protected String password; + protected String realName; + protected String email; + + + /** + * + */ + public User () + { + this.login = null; + this.password = null; + this.realName = null; + this.email = null; + } + + + /** + * + */ + public String email () + { + String result; + + result = this.email; + + // + return (result); + } + + /** + * + */ + public String login () + { + String result; + + result = this.login; + + // + return (result); + } + + /** + * + */ + public String password () + { + String result; + + result = this.password; + + // + return (result); + } + + /** + * + */ + public String realName () + { + String result; + + result = this.realName; + + // + return (result); + } + + + /** + * + */ + public User setEmail (String email) + { + this.email = email; + + // + return (this); + } + + /** + * + */ + public User setLogin (String login) + { + this.login = login; + + // + return (this); + } + + /** + * + */ + public User setPassword (String password) + { + this.password = password; + + // + return (this); + } + + /** + * + */ + public User setRealName (String realName) + { + this.realName = realName; + + // + return (this); + } + + /** + * + */ + public String toString () + { + String result; + + result = "|" + this.login + "|" + this.password + "|" + this.realName + "|"; + + // + return (result); + } +} + diff --git a/src/fr/devinsy/kiss4web/security/Users.java b/src/fr/devinsy/kiss4web/security/Users.java new file mode 100644 index 0000000..479852b --- /dev/null +++ b/src/fr/devinsy/kiss4web/security/Users.java @@ -0,0 +1,109 @@ +package fr.devinsy.kiss4web.security; + + +import java.util.*; + + +/** + * + */ +public class Users extends Vector +{ + private static final long serialVersionUID = 6140538630004281217L; + + + /** + * + */ + public Users () + { + super (); + } + + + /** + * + */ + public User getByLogin (String login) + { + User result; + + if (login == null) + { + result = null; + } + else + { + result = null; + boolean ended = false; + Iterator iterator = this.iterator (); + while (!ended) + { + if (iterator.hasNext ()) + { + User user = iterator.next (); + if (user.login ().equals (login)) + { + ended = true; + result = user; + } + } + else + { + ended = true; + result = null; + } + } + } + + // + return (result); + } + + + /* + * + */ + public boolean contains (String login) + { + boolean result; + + if (getByLogin (login) == null) + { + result = false; + } + else + { + result = true; + } + + // + return (result); + } + + + /** + * + */ + public String toString () + { + String result; + + StringBuffer out; + out = new StringBuffer (); + + Iterator iterator = this.iterator (); + + while (iterator.hasNext ()) + { + out.append (iterator.next ().toString () + "\n"); + } + + result = out.toString (); + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// diff --git a/src/fr/devinsy/kiss4web/security/UsersFileReader.java b/src/fr/devinsy/kiss4web/security/UsersFileReader.java new file mode 100644 index 0000000..eb07585 --- /dev/null +++ b/src/fr/devinsy/kiss4web/security/UsersFileReader.java @@ -0,0 +1,56 @@ +package fr.devinsy.kiss4web.security; + +import java.io.*; +import java.util.*; + + +/** + * + */ +public class UsersFileReader +{ + /** + * + */ + static public Users load (String fileName) throws Exception + { + Users result; + + result = new Users (); + + Properties properties = new Properties(); + try + { + properties.load (new FileInputStream(fileName)); + + Iterator iterator = properties.keySet ().iterator (); + while (iterator.hasNext ()) + { + String key = (String) iterator.next (); + String valueLine = (String) properties.get (key); + + // + String[] values = valueLine.split (","); + + User user = new User (); + user.setLogin (key); + user.setPassword (values[0]); + user.setRealName (values[1]); + user.setEmail (values[2]); + + result.add (user); + // + } + } + catch (Exception exception) + { + throw new Exception ("can't load (" + fileName + ")", exception); + } + + + // + return (result); + } +} + +// //////////////////////////////////////////////////////////////////////// diff --git a/src/fr/devinsy/util/web/FileItemHelper.java b/src/fr/devinsy/util/web/FileItemHelper.java new file mode 100644 index 0000000..67a520a --- /dev/null +++ b/src/fr/devinsy/util/web/FileItemHelper.java @@ -0,0 +1,83 @@ +package fr.devinsy.util.web; + +import java.util.List; + +import org.apache.commons.fileupload.FileItem; + + +/** + * + */ +public class FileItemHelper +{ + //static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (FileItemHelper.class); + + /** + * List FileItem + */ + static public String getItemValue (List items, String name) + { + String result; + + FileItem item = getItem(items, name); + + if (item == null) + { + result = null; + } + else + { + result = item.getString(); + } + + // + return(result); + } + + + /** + * List FileItem + */ + static public FileItem getItem (List items, String name) + { + FileItem result; + + if (name == null) + { + result = null; + } + else + { + result = null; + boolean ended = false; + int itemIndex = 0; + while (!ended) + { + if (itemIndex < items.size()) + { + FileItem item = (FileItem) items.get(itemIndex); + + if (name.equals(item.getFieldName())) + { + ended = true; + result = item; + } + else + { + itemIndex += 1; + } + } + else + { + ended = true; + result = null; + } + } + } + + // + return(result); + } +} + +// //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/web/Redirector.java b/src/fr/devinsy/util/web/Redirector.java new file mode 100644 index 0000000..2d10f70 --- /dev/null +++ b/src/fr/devinsy/util/web/Redirector.java @@ -0,0 +1,26 @@ +package fr.devinsy.util.web; + +import javax.servlet.http.HttpServletResponse; + + + +/** + * + */ +public class Redirector +{ + static private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (Redirector.class); + + /** + * + */ + static public void redirect (HttpServletResponse response, String destination) + { + logger.info ("Redirect to <" + destination + ">"); + + response.setHeader ("Location", destination); + response.setStatus (HttpServletResponse.SC_MOVED_TEMPORARILY); + } +} + +// //////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/fr/devinsy/util/web/SimpleSecurityAgent.java b/src/fr/devinsy/util/web/SimpleSecurityAgent.java new file mode 100644 index 0000000..59dc55e --- /dev/null +++ b/src/fr/devinsy/util/web/SimpleSecurityAgent.java @@ -0,0 +1,168 @@ +package fr.devinsy.util.web; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import fr.devinsy.kiss4web.CookieHelper; + + +/** + * + */ +public class SimpleSecurityAgent +{ + static protected org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger (SimpleSecurityAgent.class); + final static public String USERID_LABEL = "securityAgent.userId"; + final static public String ACCOUNTID_LABEL = "securityAgent.accountId"; + final static public String AUTH_LABEL = "securityAgent.auth"; + protected String userIdLabel; + protected String accountIdLabel; + protected String authLabel; + protected String secretKey; + + + + /** + * + */ + public SimpleSecurityAgent(String prefix, String secretKey) + { + this.userIdLabel = prefix + "." + USERID_LABEL; + this.accountIdLabel = prefix + "." + ACCOUNTID_LABEL; + this.authLabel= prefix + "." + AUTH_LABEL; + this.secretKey = secretKey; + } + + + /** + * + */ + static String md5sum(String source) + { + String result; + + result = org.apache.commons.codec.digest.DigestUtils.md5Hex(source); + + + // + return(result); + } + + + /** + * + */ + public String userId(HttpServletRequest request) + { + String result; + + result = (String) CookieHelper.getCookieValue(request, this.userIdLabel); + + // + return(result); + } + + + /** + * + */ + public String accountId(HttpServletRequest request) + { + String result; + + result = (String) CookieHelper.getCookieValue(request, this.accountIdLabel); + + // + return(result); + } + + + + /** + * + */ + public String auth(HttpServletRequest request) + { + String result; + + result = (String) CookieHelper.getCookieValue(request, this.authLabel); + + // + return(result); + } + + + /** + * Check authentication and refresh it (reset countdown). + */ + public boolean isAuthenticated (HttpServletRequest request, HttpServletResponse response) + { + boolean result; + + String accountId = accountId(request); + String userId = userId(request); + String auth = auth(request); + logger.info("cook=[" + auth + "]"); + + if (auth == null) + { + result = false; + } + else if (auth.equals(computeAuth(accountId, userId, request.getRemoteAddr(), this.secretKey))) + { + result = true; + + // Refresh cookies. + setAuthenticated(request, response, accountId, userId); + } + else + { + result = false; + } + + // + return (result); + } + + + /** + * + */ + static public String computeAuth(String key1, String key2, String key3, String key4) + { + String result; + + result = md5sum(key1 + key2 + key3+ key4); + + // + return(result); + } + + /** + * + */ + public void setAuthenticated (HttpServletRequest request, HttpServletResponse response, String accountId, String userId) + { + // Refresh cookie. + int duration = 60*60; + String auth = computeAuth(String.valueOf(accountId), userId, request.getRemoteAddr(), this.secretKey); + + response.addCookie (CookieHelper.buildCookie(this.authLabel, auth, duration)); + response.addCookie (CookieHelper.buildCookie(this.accountIdLabel, accountId, duration)); + response.addCookie (CookieHelper.buildCookie(this.userIdLabel, userId, duration)); + + logger.info("set [" + auth + "," + accountId + "," + userId + "," + request.getRemoteAddr() + ")"); + } + + + /** + * + */ + public void reset(HttpServletRequest request, HttpServletResponse response) + { + CookieHelper.reset(response, this.authLabel); + CookieHelper.reset(response, this.accountIdLabel); + CookieHelper.reset(response, this.userIdLabel); + } +} \ No newline at end of file diff --git a/tests/FooTester.java b/tests/FooTester.java new file mode 100644 index 0000000..d9ade54 --- /dev/null +++ b/tests/FooTester.java @@ -0,0 +1,90 @@ +/** + * Kiss4Web tests. + */ + +import fr.devinsy.kiss4web.*; + + +/** + * + */ +class FooTester +{ + static private org.apache.log4j.Logger logger; + + static + { + // Initialize logger. + org.apache.log4j.Logger logger = null; + + org.apache.log4j.BasicConfigurator.configure (); + + + logger = org.apache.log4j.Logger.getRootLogger (); + //logger.setLevel (org.apache.log4j.Level.INFO); + logger.setLevel (org.apache.log4j.Level.INFO); + + logger.info ("Enter"); + + // + logger.info ("Set the log file format..."); + + + // log = org.apache.log4j.Category.getInstance(Application.class.getName()); + logger.info ("... done."); + + logger.debug ("Exit"); + logger = org.apache.log4j.Logger.getLogger (FooTester.class.getName ()); + } + + + + /** + * + */ + public static String check (String title, StringBuffer source, String model) + { + String result; + + if (source.indexOf (model) == -1) + { + result = String.format ("%-40s -> KO <-", title) + "\nGet:\n" + source + "\nWaiting:\n" + model; + + } + else + { + result = String.format ("%-40s [ OK ] ", title); + } + + + // + return (result); + } + + + /** + * + */ + public static String testCaller (String pathInfo, String prefix) + { + String result; + + result = "[" + pathInfo + "]=>[" + ServletDispatcher.pathInfoToClassName(pathInfo, prefix) + "]"; + + // + return(result); + } + + /** + * + */ + public static void main(String[] args) + { + System.out.println ("----------------------------"); + System.out.println(testCaller("/", "fr.devinsy.website")); + System.out.println(testCaller("/good/", "fr.devinsy.website")); + System.out.println(testCaller("/good/morning", "fr.devinsy.website")); + System.out.println(testCaller("/good/day_day", "fr.devinsy.website")); + System.out.println(testCaller("/good/day.xhtml", "fr.devinsy.website")); + } +}