diff --git a/.hgignore b/.hgignore
new file mode 100644
index 0000000..b623f23
--- /dev/null
+++ b/.hgignore
@@ -0,0 +1,6 @@
+syntax: glob
+target
+META-INF/MANIFEST.MF
+bin
+*.ctm
+*.xtm
\ No newline at end of file
diff --git a/jtm-writer/.classpath b/jtm-writer/.classpath
new file mode 100644
index 0000000..5488bdc
--- /dev/null
+++ b/jtm-writer/.classpath
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/jtm-writer/.project b/jtm-writer/.project
new file mode 100644
index 0000000..6cbd468
--- /dev/null
+++ b/jtm-writer/.project
@@ -0,0 +1,23 @@
+
+
+ jtm-writer
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.maven.ide.eclipse.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.maven.ide.eclipse.maven2Nature
+
+
diff --git a/jtm-writer/.settings/org.eclipse.core.resources.prefs b/jtm-writer/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..d71857a
--- /dev/null
+++ b/jtm-writer/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Mon Mar 07 11:53:57 CET 2011
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/jtm-writer/.settings/org.eclipse.jdt.core.prefs b/jtm-writer/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..cd1e394
--- /dev/null
+++ b/jtm-writer/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,274 @@
+#Mon Mar 07 10:41:43 CET 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+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_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=120
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.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_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_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_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.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=120
+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_outer_expressions_when_nested=true
diff --git a/jtm-writer/.settings/org.eclipse.jdt.ui.prefs b/jtm-writer/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..6fa8512
--- /dev/null
+++ b/jtm-writer/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,57 @@
+#Mon Mar 07 10:41:43 CET 2011
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_Eclipse
+formatter_settings_version=11
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=true
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=true
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/jtm-writer/.settings/org.maven.ide.eclipse.prefs b/jtm-writer/.settings/org.maven.ide.eclipse.prefs
new file mode 100644
index 0000000..19630ec
--- /dev/null
+++ b/jtm-writer/.settings/org.maven.ide.eclipse.prefs
@@ -0,0 +1,8 @@
+#Thu Jan 13 14:26:06 CET 2011
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
diff --git a/jtm-writer/pom.xml b/jtm-writer/pom.xml
new file mode 100644
index 0000000..e6dd871
--- /dev/null
+++ b/jtm-writer/pom.xml
@@ -0,0 +1,180 @@
+
+
+ 4.0.0
+
+ de.topicmapslab
+ jtm-writer
+ 1.0.0
+ JTMWriter
+
+
+ 1.0.0.${maven.build.timestamp}
+ yyyyMMddHHmm
+ UTF-8
+
+
+
+
+
+ org.apache.maven.wagon
+ wagon-ssh
+ 1.0-beta-2
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 2.3.2
+
+
+ 1.6
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.3.1
+
+
+ META-INF/MANIFEST.MF
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+ 2.2.0
+
+
+
+ bundle-manifest
+ process-classes
+
+ manifest
+
+
+
+
+
+
+ jar
+
+ META-INF
+
+ ${osgi.version}
+ de.topicmapslab.jtm.writer.*
+
+
+ org.codehaus.jackson;version="[1.6.1,2)",
+ org.codehaus.jackson.map;version="[1.6.1,2)",
+ org.codehaus.jackson.map.annotate;version="[1.6.1,2)",
+ org.tmapi.core;version="[2.0.3,3)"
+
+ de.topicmapslab.jtm.writer
+ JTM Writer
+ lazy
+ JavaSE-1.6
+
+
+
+
+
+
+
+ topicmapslab-public
+ Topic Maps Lab Repositiory
+ scp://atlantis.tm.informatik.uni-leipzig.de/disk/localhome/maven/webdir/maven.topicmapslab.de/public/public
+
+
+
+
+ tmapi
+ http://www.tmapi.org/maven-repository
+
+
+ tmapi-snapshots
+ http://www.tmapi.org/maven-repository/snapshots
+
+
+ tmapix
+ http://repository.semagia.com/snapshots/
+
+
+ tmapix releases
+ http://repository.semagia.com/releases/
+
+
+
+
+
+ org.tmapi
+ tmapi
+ 2.0.3-SNAPSHOT
+
+
+
+ org.codehaus.jackson
+ jackson-mapper-asl
+ 1.6.1
+
+
+
+
+ junit
+ junit
+ 4.8.1
+ test
+
+
+ junit-addons
+ junit-addons
+ 1.4
+ test
+
+
+
+
+ org.slf4j
+ slf4j-api
+ 1.6.1
+ test
+
+
+ org.slf4j
+ slf4j-nop
+ 1.6.1
+ test
+
+
+
+ org.tmapix
+ tmapix-io
+ 1.0.0
+ test
+
+
+ slf4j-jdk14
+ org.slf4j
+
+
+ slf4j-api
+ org.slf4j
+
+
+ org.tmapi
+ tmapi
+
+
+
+
+
+ de.topicmapslab.majortom
+ majortom-inMemory
+ 1.2.0-SNAPSHOT
+ test
+
+
+
\ No newline at end of file
diff --git a/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/AssociationSerializer.java b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/AssociationSerializer.java
new file mode 100644
index 0000000..4c6e3fd
--- /dev/null
+++ b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/AssociationSerializer.java
@@ -0,0 +1,46 @@
+package de.topicmapslab.jtm.writer;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerationException;
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.map.SerializerProvider;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.tmapi.core.Association;
+
+/**
+ * Class to convert an association to JTM
+ *
+ * Author: mhoyer Created: 28.10.2010 01:04
+ */
+public class AssociationSerializer extends ConstructSerializer {
+
+ /**
+ * Jackson Mapper
+ */
+ @JsonSerialize(using = AssociationSerializer.class)
+ public class AssociationMixIn {
+ // VOID
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void serialize(Association value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
+ if (value.getRoles().size() == 0) {
+ throw new JsonGenerationException("JTM 1.0 and 1.1 does not support associations without a role.");
+ }
+
+ writeStart(jgen);
+ {
+ writeId(jgen, value.getId());
+ writeType(jgen, value);
+ writeScope(jgen, value);
+ writeList(jgen, value.getRoles(), IJTMConstants.ROLES);
+ writeReifier(jgen, value);
+ writeLocators(jgen, value.getItemIdentifiers(), IJTMConstants.ITEM_IDENTIFIERS);
+ }
+ jgen.writeEndObject();
+ }
+}
diff --git a/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/ConstructSerializer.java b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/ConstructSerializer.java
new file mode 100644
index 0000000..b0a2a1a
--- /dev/null
+++ b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/ConstructSerializer.java
@@ -0,0 +1,245 @@
+package de.topicmapslab.jtm.writer;
+
+import java.io.IOException;
+import java.lang.reflect.ParameterizedType;
+import java.util.Set;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonStreamContext;
+import org.codehaus.jackson.ObjectCodec;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.tmapi.core.Construct;
+import org.tmapi.core.Locator;
+import org.tmapi.core.Reifiable;
+import org.tmapi.core.Scoped;
+import org.tmapi.core.Topic;
+import org.tmapi.core.Typed;
+
+/**
+ * Author: mhoyer Created: 27.10.2010 22:05:41
+ */
+public abstract class ConstructSerializer extends JsonSerializer {
+
+ private final String itemType;
+
+ /**
+ * constructor
+ */
+ public ConstructSerializer() {
+ /*
+ * extract type information
+ */
+ Class> cla = getClass();
+ while (!(cla.getGenericSuperclass() instanceof ParameterizedType)) {
+ cla = cla.getSuperclass();
+ }
+ itemType = ((Class>) ((ParameterizedType) cla.getGenericSuperclass()).getActualTypeArguments()[0])
+ .getSimpleName();
+ }
+
+ /**
+ * Writes the header of an construct JSON part
+ *
+ * @param jgen
+ * the generator
+ * @throws IOException
+ * thrown if an I/O error occur
+ */
+ public void writeStart(JsonGenerator jgen) throws IOException {
+ JsonStreamContext outputContext = jgen.getOutputContext();
+
+ boolean isRoot = outputContext.inRoot();
+ boolean parentIsRootArray = outputContext.inArray() && outputContext.getParent().inRoot();
+ jgen.writeStartObject();
+
+ /*
+ * isn't the topic map note and not part of an root array
+ */
+ if (!isRoot && !parentIsRootArray) {
+ return;
+ }
+
+ /*
+ * get version
+ */
+ ObjectCodec codec = jgen.getCodec();
+ JTMVersion version = JTMVersion.JTM_1_0;
+ if (codec instanceof JTMMapper) {
+ version = ((JTMMapper) codec).getVersion();
+ }
+ /*
+ * write version part
+ */
+ if (version == JTMVersion.JTM_1_0) {
+ jgen.writeStringField(IJTMConstants.VERSION, IJTMConstants.VERSION_10);
+ } else if (version == JTMVersion.JTM_1_1) {
+ jgen.writeStringField(IJTMConstants.VERSION, IJTMConstants.VERSION_11);
+ }
+
+ jgen.writeStringField(IJTMConstants.ITEM_TYPE, itemType.toLowerCase());
+ }
+
+ /**
+ * Writes the id property
+ *
+ * @param jgen
+ * the JSON generator
+ * @param id
+ * the is
+ * @throws IOException
+ * thrown if an I/O error occur
+ */
+ protected void writeId(JsonGenerator jgen, String id) throws IOException {
+ jgen.writeStringField(IJTMConstants.ID, id);
+ }
+
+ /**
+ * Writes a JSON array of topic references
+ *
+ * @param jgen
+ * the JSON generator
+ * @param values
+ * the topics
+ * @param fieldName
+ * the field name
+ * @throws IOException
+ * thrown if an I/O error occur
+ */
+ protected void writeListOfReferences(JsonGenerator jgen, Set values, String fieldName) throws IOException {
+ if (values.size() == 0) {
+ return;
+ }
+
+ jgen.writeArrayFieldStart(fieldName);
+ for (Topic value : values) {
+ jgen.writeString(createTopicReference(value));
+ }
+
+ jgen.writeEndArray();
+ }
+
+ /**
+ * Writes an list of values as JSON array for the given field name
+ *
+ * @param jgen
+ * the JSON generator
+ * @param values
+ * the values
+ * @param fieldName
+ * the field name
+ * @throws IOException
+ * thrown if an I/O error occur
+ */
+ protected void writeList(JsonGenerator jgen, Set> values, String fieldName) throws IOException {
+ if (values.size() == 0) {
+ return;
+ }
+
+ jgen.writeArrayFieldStart(fieldName);
+ for (Object value : values) {
+ jgen.writeObject(value);
+ }
+
+ jgen.writeEndArray();
+ }
+
+ /**
+ * Writes all locators as JSON array for the given field name
+ *
+ * @param jgen
+ * the JSON generator
+ * @param locators
+ * the locators
+ * @param fieldName
+ * the field name
+ * @throws IOException
+ * thrown if an I/O error occur
+ */
+ protected void writeLocators(JsonGenerator jgen, Set locators, String fieldName) throws IOException {
+ if (locators.size() == 0) {
+ return;
+ }
+
+ jgen.writeArrayFieldStart(fieldName);
+
+ for (Locator locator : locators) {
+ jgen.writeString(locator.getReference());
+ }
+
+ jgen.writeEndArray();
+ }
+
+ /**
+ * Writes the reifier property of the construct, if the reifier is not null
+ *
+ * @param jgen
+ * the JSON generator
+ * @param value
+ * the reified construct
+ * @throws IOException
+ * thrown if an I/O error occur
+ */
+ protected void writeReifier(JsonGenerator jgen, Reifiable value) throws IOException {
+ Topic reifier = value.getReifier();
+ if (reifier == null) {
+ return;
+ }
+ jgen.writeStringField(IJTMConstants.REIFIER, createTopicReference(reifier));
+ }
+
+ /**
+ * Writes the type property of typed constructs
+ *
+ * @param jgen
+ * the JSON generator
+ * @param value
+ * the typed construct
+ * @throws IOException
+ * thrown if an I/O error occur
+ */
+ protected void writeType(JsonGenerator jgen, Typed value) throws IOException {
+ jgen.writeStringField(IJTMConstants.TYPE, createTopicReference(value.getType()));
+ }
+
+ /**
+ * Writes the scope property of scoped construct as an JSON array of all themes.
+ *
+ * @param jgen
+ * the JSON generator
+ * @param value
+ * the scoped construct
+ * @throws IOException
+ * thrown if an I/O error occur
+ */
+ protected void writeScope(JsonGenerator jgen, Scoped value) throws IOException {
+ Set scope = value.getScope();
+ if (scope.size() == 0) {
+ return;
+ }
+
+ jgen.writeArrayFieldStart(IJTMConstants.SCOPE);
+
+ for (Topic theme : scope) {
+ jgen.writeString(createTopicReference(theme));
+ }
+
+ jgen.writeEndArray();
+ }
+
+ /**
+ * Writes a topic reference entry for the given topic
+ *
+ * @param topic
+ * the topic
+ * @return the reference
+ */
+ protected String createTopicReference(Topic topic) {
+ if (topic.getSubjectIdentifiers().size() > 0) {
+ return IJTMConstants.PREFIX_SI + topic.getSubjectIdentifiers().iterator().next().getReference();
+ }
+ if (topic.getSubjectLocators().size() > 0) {
+ return IJTMConstants.PREFIX_SL + topic.getSubjectLocators().iterator().next().getReference();
+ }
+ return IJTMConstants.PREFIX_II + topic.getItemIdentifiers().iterator().next().getReference();
+ }
+}
diff --git a/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/IJTMConstants.java b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/IJTMConstants.java
new file mode 100644
index 0000000..8602f26
--- /dev/null
+++ b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/IJTMConstants.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright: Copyright 2010 Topic Maps Lab, University of Leipzig. http://www.topicmapslab.de/
+ * License: Apache License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.html
+ *
+ * @author Sven Krosse
+ * @email krosse@informatik.uni-leipzig.de
+ *
+ */
+package de.topicmapslab.jtm.writer;
+
+/**
+ * @author Sven Krosse
+ *
+ */
+public interface IJTMConstants {
+
+ /**
+ * the JSON hash key for version data
+ */
+ public static final String VERSION = "version";
+
+ /**
+ * the JSON hash key for version 1.0
+ */
+ public static final String VERSION_10 = "1.0";
+
+ /**
+ * the JSON hash key for version 1.1
+ */
+ public static final String VERSION_11 = "1.1";
+
+ /**
+ * JSON key of construct type
+ */
+ public static final String ITEM_TYPE = "item_type";
+ /**
+ * JSON key of topic
+ */
+ public static final String TOPIC = "topic";
+
+ /**
+ * JSON key of topics
+ */
+ public static final String TOPICS = "topics";
+ /**
+ * JSON key of association
+ */
+ public static final String ASSOCIATION = "association";
+ /**
+ * JSON key of associations
+ */
+ public static final String ASSOCIATIONS = "associations";
+ /**
+ * JSON key of name
+ */
+ public static final String NAME = "name";
+ /**
+ * JSON key of occurrence
+ */
+ public static final String OCCURRENCE = "occurrence";
+ /**
+ * JSON key of role
+ */
+ public static final String ROLE = "role";
+ /**
+ * JSON key of variant
+ */
+ public static final String VARIANT = "variant";
+ /**
+ * JSON key of instance-of
+ */
+ public static final String INSTANCE_OF = "instance_of";
+ /**
+ * JSON key of subject-identifiers
+ */
+ public static final String SUBJECT_IDENTIFIERS = "subject_identifiers";
+ /**
+ * JSON key of subject-locators
+ */
+ public static final String SUBJECT_LOCATORS = "subject_locators";
+ /**
+ * JSON key of item-identifiers
+ */
+ public static final String ITEM_IDENTIFIERS = "item_identifiers";
+ /**
+ * JSON key of type
+ */
+ public static final String TYPE = "type";
+ /**
+ * JSON key of types
+ */
+ public static final String TYPES = "types";
+ /**
+ * JSON key of names
+ */
+ public static final String NAMES = "names";
+ /**
+ * JSON key of occurrences
+ */
+ public static final String OCCURRENCES = "occurrences";
+ /**
+ * JSON key of variants
+ */
+ public static final String VARIANTS = "variants";
+ /**
+ * JSON key of roles
+ */
+ public static final String ROLES = "roles";
+ /**
+ * JSON key of value
+ */
+ public static final String VALUE = "value";
+ /**
+ * JSON key of datatype
+ */
+ public static final String DATATYPE = "datatype";
+ /**
+ * JSON key of reifier
+ */
+ public static final String REIFIER = "reifier";
+ /**
+ * JSON key of scope
+ */
+ public static final String SCOPE = "scope";
+ /**
+ * JSON key of id
+ */
+ public static final String ID = "id";
+ /**
+ * JSON key of player
+ */
+ public static final String PLAYER = "player";
+ /**
+ * JSON prefix of subject-identifier
+ */
+ public static final String PREFIX_SI = "si:";
+ /**
+ * JSON prefix of subject-locator
+ */
+ public static final String PREFIX_SL = "sl:";
+ /**
+ * JSON prefix of item-identifier
+ */
+ public static final String PREFIX_II = "ii:";
+ /**
+ * JSON key of string
+ */
+ public static final String STRING = "string";
+
+}
diff --git a/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/JTMMapper.java b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/JTMMapper.java
new file mode 100644
index 0000000..ca39378
--- /dev/null
+++ b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/JTMMapper.java
@@ -0,0 +1,52 @@
+package de.topicmapslab.jtm.writer;
+
+import org.codehaus.jackson.map.ObjectMapper;
+import org.tmapi.core.Association;
+import org.tmapi.core.Name;
+import org.tmapi.core.Occurrence;
+import org.tmapi.core.Role;
+import org.tmapi.core.Topic;
+import org.tmapi.core.TopicMap;
+import org.tmapi.core.Variant;
+
+/**
+ * Author: mhoyer Created: 03.11.10 13:53
+ */
+public class JTMMapper extends ObjectMapper {
+
+ private JTMVersion version;
+
+ /**
+ * construct
+ */
+ public JTMMapper() {
+ this.version = JTMVersion.JTM_1_0;
+ getSerializationConfig().addMixInAnnotations(Variant.class, VariantSerializer.VariantMixIn.class);
+ getSerializationConfig().addMixInAnnotations(Name.class, NameSerializer.NameMixIn.class);
+ getSerializationConfig().addMixInAnnotations(Occurrence.class, OccurrenceSerializer.OccurrenceMixIn.class);
+ getSerializationConfig().addMixInAnnotations(Topic.class, TopicSerializer.TopicMixIn.class);
+ getSerializationConfig().addMixInAnnotations(Role.class, RoleSerializer.RoleMixIn.class);
+ getSerializationConfig().addMixInAnnotations(Association.class, AssociationSerializer.AssociationMixIn.class);
+ getSerializationConfig().addMixInAnnotations(TopicMap.class, TopicMapSerializer.TopicMapMixIn.class);
+ }
+
+ /**
+ * Modify the version
+ *
+ * @param version
+ * the version to set
+ */
+ public void setVersion(JTMVersion version) {
+ this.version = version;
+ }
+
+ /**
+ * Returns the JTM version
+ *
+ * @return the version
+ */
+ public JTMVersion getVersion() {
+ return version;
+ }
+
+}
diff --git a/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/JTMVersion.java b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/JTMVersion.java
new file mode 100644
index 0000000..514903b
--- /dev/null
+++ b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/JTMVersion.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright: Copyright 2010 Topic Maps Lab, University of Leipzig. http://www.topicmapslab.de/
+ * License: Apache License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.html
+ *
+ * @author Sven Krosse
+ * @email krosse@informatik.uni-leipzig.de
+ *
+ */
+package de.topicmapslab.jtm.writer;
+
+/**
+ * @author Sven Krosse
+ *
+ */
+public enum JTMVersion {
+
+ JTM_1_0,
+
+ JTM_1_1
+
+}
diff --git a/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/JTMWriter.java b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/JTMWriter.java
new file mode 100644
index 0000000..1ff4337
--- /dev/null
+++ b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/JTMWriter.java
@@ -0,0 +1,204 @@
+package de.topicmapslab.jtm.writer;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collection;
+
+import org.tmapi.core.Construct;
+
+/**
+ * Author: mhoyer Created: 27.10.2010 17:25:20
+ */
+public class JTMWriter {
+
+ private final OutputStream out;
+ private final JTMMapper mapper;
+
+ /**
+ * constructor
+ *
+ * @param outputStream
+ * the output stream
+ */
+ public JTMWriter(OutputStream outputStream) {
+ out = outputStream;
+
+ mapper = new JTMMapper();
+ }
+
+ /**
+ * Writes the given construct to JSON
+ *
+ * @param construct
+ * the construct
+ * @throws IOException
+ * thrown if an I/O error occur
+ * @deprecated will be removed use {@link #write(Construct, JTMVersion)}
+ */
+ @Deprecated
+ public JTMWriter write(Construct construct) throws IOException {
+ mapper.writeValue(out, construct);
+
+ return this;
+ }
+
+ /**
+ * Writes the given constructs to JSON
+ *
+ * @param constructs
+ * the constructs
+ * @throws IOException
+ * thrown if an I/O error occur
+ * @deprecated will be removed use {@link #write(Collection, JTMVersion)}
+ */
+ @Deprecated
+ public JTMWriter write(Collection extends Construct> constructs) throws IOException {
+ mapper.writeValue(out, constructs.toArray(new Construct[constructs.size()]));
+
+ return this;
+ }
+
+ /**
+ * Writes the given construct to JSON
+ *
+ * @param construct
+ * the construct
+ * @param version
+ * the JTM version
+ * @throws IOException
+ * thrown if an I/O error occur
+ */
+ public JTMWriter write(Construct construct, JTMVersion version) throws IOException {
+ mapper.setVersion(version);
+ mapper.writeValue(out, construct);
+
+ return this;
+ }
+
+ /**
+ * Writes the given constructs to JSON
+ *
+ * @param constructs
+ * the constructs
+ * @param version
+ * the JTM version
+ * @throws IOException
+ * thrown if an I/O error occur
+ */
+ public JTMWriter write(Collection extends Construct> constructs, JTMVersion version) throws IOException {
+ mapper.setVersion(version);
+ mapper.writeValue(out, constructs.toArray(new Construct[constructs.size()]));
+
+ return this;
+ }
+
+ /**
+ * Flush the internal writer
+ */
+ public JTMWriter flush() {
+ try {
+ out.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return this;
+ }
+
+ /**
+ * Returns the given construct as JSON string
+ *
+ * @param construct
+ * the construct
+ * @return the JSON string
+ * @throws IOException
+ * thrown if an I/O error occur
+ * @deprecated will be removed, use {@link #getJson(Construct, JTMVersion)}
+ */
+ @Deprecated
+ public static String getJson(Construct construct) throws IOException {
+ return getJsonAsStream(construct).toString();
+ }
+
+ /**
+ * Returns the given construct as JSON byte array
+ *
+ * @param construct
+ * the construct
+ * @return the JSON byte array
+ * @throws IOException
+ * thrown if an I/O error occur
+ * @deprecated will be removed, use {@link #getJsonAsByteArray(Construct, JTMVersion)}
+ */
+ @Deprecated
+ public static byte[] getJsonAsByteArray(Construct construct) throws IOException {
+ return getJsonAsStream(construct).toByteArray();
+ }
+
+ /**
+ * Returns the given construct as JSON byte array stream
+ *
+ * @param construct
+ * the construct
+ * @return the JSON byte array stream
+ * @throws IOException
+ * thrown if an I/O error occur
+ * @deprecated will be removed, use {@link #getJsonAsStream(Construct, JTMVersion)}
+ */
+ @Deprecated
+ public static ByteArrayOutputStream getJsonAsStream(Construct construct) throws IOException {
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ new JTMWriter(buffer).write(construct).flush();
+
+ return buffer;
+ }
+
+ /**
+ * Returns the given construct as JSON string
+ *
+ * @param construct
+ * the construct
+ * @param version
+ * the JTM version
+ * @return the JSON string
+ * @throws IOException
+ * thrown if an I/O error occur
+ */
+ public static String getJson(Construct construct, JTMVersion version) throws IOException {
+ return getJsonAsStream(construct, version).toString();
+ }
+
+ /**
+ * Returns the given construct as JSON byte array
+ *
+ * @param construct
+ * the construct
+ * @param version
+ * the JTM version
+ * @return the JSON byte array
+ * @throws IOException
+ * thrown if an I/O error occur
+ */
+ public static byte[] getJsonAsByteArray(Construct construct, JTMVersion version) throws IOException {
+ return getJsonAsStream(construct, version).toByteArray();
+ }
+
+ /**
+ * Returns the given construct as JSON byte array stream
+ *
+ * @param construct
+ * the construct
+ * @param version
+ * the JTM version
+ * @return the JSON byte array stream
+ * @throws IOException
+ * thrown if an I/O error occur
+ */
+ public static ByteArrayOutputStream getJsonAsStream(Construct construct, JTMVersion version) throws IOException {
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ new JTMWriter(buffer).write(construct, version).flush();
+
+ return buffer;
+ }
+}
diff --git a/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/NameSerializer.java b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/NameSerializer.java
new file mode 100644
index 0000000..2df76cf
--- /dev/null
+++ b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/NameSerializer.java
@@ -0,0 +1,43 @@
+package de.topicmapslab.jtm.writer;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.map.SerializerProvider;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.tmapi.core.Name;
+
+/**
+ * Class to convert a topic name to JTM
+ *
+ * Author: mhoyer Created: 27.10.2010 23:25:00
+ */
+public class NameSerializer extends ConstructSerializer {
+
+ /**
+ * Jackson Mapper
+ */
+ @JsonSerialize(using = NameSerializer.class)
+ public class NameMixIn {
+ // VOID
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void serialize(Name value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
+ writeStart(jgen);
+ {
+ writeId(jgen, value.getId());
+ jgen.writeStringField(IJTMConstants.VALUE, value.getValue());
+ writeType(jgen, value);
+ writeScope(jgen, value);
+ writeList(jgen, value.getVariants(), IJTMConstants.VARIANTS);
+
+ writeReifier(jgen, value);
+ writeLocators(jgen, value.getItemIdentifiers(), IJTMConstants.ITEM_IDENTIFIERS);
+ }
+ jgen.writeEndObject();
+ }
+}
diff --git a/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/OccurrenceSerializer.java b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/OccurrenceSerializer.java
new file mode 100644
index 0000000..0264b3f
--- /dev/null
+++ b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/OccurrenceSerializer.java
@@ -0,0 +1,44 @@
+package de.topicmapslab.jtm.writer;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.map.SerializerProvider;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.tmapi.core.Occurrence;
+
+/**
+ * Class to convert an occurrence to JTM
+ *
+ * Author: mhoyer Created: 28.10.2010 00:01:02
+ */
+public class OccurrenceSerializer extends ConstructSerializer {
+ /**
+ * Jackson Mapper
+ */
+ @JsonSerialize(using = OccurrenceSerializer.class)
+ public class OccurrenceMixIn {
+ // VOID
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void serialize(Occurrence value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
+ writeStart(jgen);
+ {
+ writeId(jgen, value.getId());
+ if (!value.getDatatype().getReference().endsWith(IJTMConstants.STRING)) {
+ jgen.writeStringField(IJTMConstants.DATATYPE, value.getDatatype().getReference());
+ }
+
+ writeScope(jgen, value);
+ jgen.writeStringField(IJTMConstants.VALUE, value.getValue());
+ writeType(jgen, value);
+ writeReifier(jgen, value);
+ writeLocators(jgen, value.getItemIdentifiers(), IJTMConstants.ITEM_IDENTIFIERS);
+ }
+ jgen.writeEndObject();
+ }
+}
diff --git a/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/RoleSerializer.java b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/RoleSerializer.java
new file mode 100644
index 0000000..e681936
--- /dev/null
+++ b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/RoleSerializer.java
@@ -0,0 +1,44 @@
+package de.topicmapslab.jtm.writer;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.map.SerializerProvider;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.tmapi.core.Role;
+
+/**
+ * Class to convert a role to JTM
+ *
+ * Author: mhoyer Created: 28.10.2010 00:44
+ */
+public class RoleSerializer extends ConstructSerializer {
+ /**
+ * Jackson Mapper
+ */
+ @JsonSerialize(using = RoleSerializer.class)
+ public class RoleMixIn {
+ // VOID
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void serialize(Role value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
+ writeStart(jgen);
+ {
+ writeId(jgen, value.getId());
+ writePlayer(jgen, value);
+ writeType(jgen, value);
+ writeReifier(jgen, value);
+ writeLocators(jgen, value.getItemIdentifiers(), IJTMConstants.ITEM_IDENTIFIERS);
+ }
+ jgen.writeEndObject();
+ }
+
+ protected void writePlayer(JsonGenerator jgen, Role value) throws IOException {
+ jgen.writeStringField(IJTMConstants.PLAYER, createTopicReference(value.getPlayer()));
+ }
+
+}
diff --git a/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/TopicMapSerializer.java b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/TopicMapSerializer.java
new file mode 100644
index 0000000..9e7ec83
--- /dev/null
+++ b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/TopicMapSerializer.java
@@ -0,0 +1,39 @@
+package de.topicmapslab.jtm.writer;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.map.SerializerProvider;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.tmapi.core.TopicMap;
+
+/**
+ * Class to convert the topic map to JTM
+ *
+ * Author: mhoyer Created: 28.10.2010 01:19
+ */
+public class TopicMapSerializer extends ConstructSerializer {
+ /**
+ * Jackson Mapper
+ */
+ @JsonSerialize(using = TopicMapSerializer.class)
+ public class TopicMapMixIn {
+ // VOID
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void serialize(TopicMap value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
+ writeStart(jgen);
+ {
+ writeList(jgen, value.getTopics(), IJTMConstants.TOPICS);
+ writeList(jgen, value.getAssociations(), IJTMConstants.ASSOCIATIONS);
+ writeLocators(jgen, value.getItemIdentifiers(), IJTMConstants.ITEM_IDENTIFIERS);
+ writeReifier(jgen, value);
+ }
+ jgen.writeEndObject();
+ }
+
+}
diff --git a/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/TopicSerializer.java b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/TopicSerializer.java
new file mode 100644
index 0000000..6399a87
--- /dev/null
+++ b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/TopicSerializer.java
@@ -0,0 +1,56 @@
+package de.topicmapslab.jtm.writer;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.ObjectCodec;
+import org.codehaus.jackson.map.SerializerProvider;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.tmapi.core.Topic;
+
+/**
+ * Class to convert a topic to JTM
+ *
+ * Author: mhoyer Created: 28.10.2010 00:21:53
+ */
+public class TopicSerializer extends ConstructSerializer {
+ /**
+ * Jackson Mapper
+ */
+ @JsonSerialize(using = TopicSerializer.class)
+ public class TopicMixIn {
+ // VOID
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void serialize(Topic value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
+ writeStart(jgen);
+ {
+ writeId(jgen, value.getId());
+ /*
+ * get version
+ */
+ ObjectCodec codec = jgen.getCodec();
+ JTMVersion version = JTMVersion.JTM_1_0;
+ if (codec instanceof JTMMapper) {
+ version = ((JTMMapper) codec).getVersion();
+ }
+ /*
+ * write instance_of field if version is 1.1
+ */
+ if (version == JTMVersion.JTM_1_1) {
+ writeListOfReferences(jgen, value.getTypes(), IJTMConstants.INSTANCE_OF);
+ }
+ writeList(jgen, value.getNames(), IJTMConstants.NAMES);
+ writeList(jgen, value.getOccurrences(), IJTMConstants.OCCURRENCES);
+ writeLocators(jgen, value.getSubjectIdentifiers(), IJTMConstants.SUBJECT_IDENTIFIERS);
+ writeLocators(jgen, value.getSubjectLocators(), IJTMConstants.SUBJECT_LOCATORS);
+ writeLocators(jgen, value.getItemIdentifiers(), IJTMConstants.ITEM_IDENTIFIERS);
+ }
+ jgen.writeEndObject();
+ }
+
+}
diff --git a/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/VariantSerializer.java b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/VariantSerializer.java
new file mode 100644
index 0000000..615db05
--- /dev/null
+++ b/jtm-writer/src/main/java/de/topicmapslab/jtm/writer/VariantSerializer.java
@@ -0,0 +1,43 @@
+package de.topicmapslab.jtm.writer;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.map.SerializerProvider;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.tmapi.core.Variant;
+
+/**
+ * Class to convert a variant to JTM
+ *
+ * Author: mhoyer Created: 27.10.2010 22:05:41
+ */
+public class VariantSerializer extends ConstructSerializer {
+ /**
+ * Jackson Mapper
+ */
+ @JsonSerialize(using = VariantSerializer.class)
+ public class VariantMixIn {
+ // VOID
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void serialize(Variant value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
+ writeStart(jgen);
+ {
+ writeId(jgen, value.getId());
+ if (!value.getDatatype().getReference().endsWith(IJTMConstants.STRING)) {
+ jgen.writeStringField(IJTMConstants.DATATYPE, value.getDatatype().getReference());
+ }
+
+ writeScope(jgen, value);
+ jgen.writeStringField(IJTMConstants.VALUE, value.getValue());
+ writeReifier(jgen, value);
+ writeLocators(jgen, value.getItemIdentifiers(), IJTMConstants.ITEM_IDENTIFIERS);
+ }
+ jgen.writeEndObject();
+ }
+}
diff --git a/jtm-writer/src/test/java/de/topicmapslab/integration/when_converting_ToyTM.java b/jtm-writer/src/test/java/de/topicmapslab/integration/when_converting_ToyTM.java
new file mode 100644
index 0000000..13e9649
--- /dev/null
+++ b/jtm-writer/src/test/java/de/topicmapslab/integration/when_converting_ToyTM.java
@@ -0,0 +1,54 @@
+package de.topicmapslab.integration;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.tmapi.core.TopicMap;
+import org.tmapi.core.TopicMapExistsException;
+import org.tmapix.io.JTMTopicMapWriter;
+import org.tmapix.io.XTMTopicMapReader;
+
+import de.topicmapslab.with_JTMWriter;
+import de.topicmapslab.jtm.writer.JTMVersion;
+
+/**
+ * Author: mhoyer Created: 28.10.2010 01:24:45
+ */
+public class when_converting_ToyTM extends with_JTMWriter {
+ private TopicMap toytm;
+ private JTMTopicMapWriter tmapixJTMWriter;
+ private final int TIMES = 3;
+
+ @Before
+ public void given_imported_ToyTM() throws TopicMapExistsException, IOException, InterruptedException {
+ toytm = tms.createTopicMap("class:" + getClass().getSimpleName());
+ InputStream toytmStream = ClassLoader.getSystemResourceAsStream("toytm.xtm");
+ new XTMTopicMapReader(toytm, toytmStream, "toytm").read();
+ tmapixJTMWriter = new org.tmapix.io.JTMTopicMapWriter(out, "base-iri");
+ }
+
+ @Test
+ public void it_should_convert_all_topics() throws IOException, InterruptedException {
+ for (int i = 0; i < TIMES; i++) {
+ Thread.sleep(50);
+ long start = new Date().getTime();
+ jtmwriter.write(toytm, JTMVersion.JTM_1_0).flush();
+ System.out.println("TMLab Writing took: " + (new Date().getTime() - start) + "ms.");
+ }
+ }
+
+ @Test
+ public void it_should_convert_all_topics_with_tmapix() throws IOException, InterruptedException {
+ for (int i = 0; i < TIMES; i++) {
+ Thread.sleep(50);
+ long start = new Date().getTime();
+ tmapixJTMWriter.write(toytm);
+ out.flush();
+ System.out.println("TMAPIX Writing took: " + (new Date().getTime() - start) + "ms.");
+ }
+ }
+
+}
diff --git a/jtm-writer/src/test/java/de/topicmapslab/when_writing_a_list_of_constructs.java b/jtm-writer/src/test/java/de/topicmapslab/when_writing_a_list_of_constructs.java
new file mode 100644
index 0000000..3e9c55b
--- /dev/null
+++ b/jtm-writer/src/test/java/de/topicmapslab/when_writing_a_list_of_constructs.java
@@ -0,0 +1,44 @@
+package de.topicmapslab;
+
+import org.codehaus.jackson.JsonNode;
+import org.junit.Before;
+import org.junit.Test;
+import org.tmapi.core.Construct;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import static junit.framework.Assert.assertEquals;
+
+/**
+ * Author: mhoyer
+ * Created: 27.10.2010 00:05:04
+ */
+public class when_writing_a_list_of_constructs extends with_JTMWriter {
+ private Collection constructs;
+
+ @Before public void given_a_list_of_constructs() {
+ constructs = new ArrayList();
+ constructs.add(topicMap.createTopic());
+ constructs.add(topicMap.createTopic());
+ constructs.add(createName(getClass().getName()));
+ }
+
+ @Test public void it_should_write_all_entries() throws IOException {
+ JsonNode node = writeAndRead(constructs);
+ assertEquals(constructs.size(), node.size());
+ }
+
+ @Test public void it_should_write_item_type_and_version_for_all_entries() throws IOException {
+ JsonNode node = writeAndRead(constructs);
+
+ int i=0;
+ for(Construct construct : constructs)
+ {
+ assertEquals(1.0, node.get(i).get("version").getValueAsDouble());
+ assertItemType(construct, node.get(i));
+ i++;
+ }
+ }
+}
diff --git a/jtm-writer/src/test/java/de/topicmapslab/when_writing_a_name.java b/jtm-writer/src/test/java/de/topicmapslab/when_writing_a_name.java
new file mode 100644
index 0000000..dd8b731
--- /dev/null
+++ b/jtm-writer/src/test/java/de/topicmapslab/when_writing_a_name.java
@@ -0,0 +1,102 @@
+package de.topicmapslab;
+
+import org.codehaus.jackson.JsonNode;
+import org.junit.Before;
+import org.junit.Test;
+import org.tmapi.core.Name;
+
+import java.io.IOException;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+import static junitx.framework.ComparableAssert.assertGreater;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Author: mhoyer
+ * Created: 27.10.2010 23:39:36
+ */
+public class when_writing_a_name extends with_JTMWriter {
+ private Name name;
+
+ @Before public void given_a_string_name() {
+ name = createName(getClass().getSimpleName());
+ }
+
+ @Test public void it_should_write_the_version_and_item_type() throws IOException {
+ JsonNode node = writeAndRead(name);
+ assertEquals(1.0, node.get("version").getValueAsDouble());
+ assertItemType(name, node);
+ }
+
+ @Test public void it_should_write_value() throws IOException {
+ JsonNode node = writeAndRead(name);
+ assertEquals(name.getValue(), node.get("value").getTextValue());
+ }
+
+ @Test public void it_should_write_type() throws IOException {
+ JsonNode node = writeAndRead(name);
+ assertEquals(
+ "si:"+ name.getType().getSubjectIdentifiers().iterator().next().getReference(),
+ node.get("type").getTextValue());
+ }
+
+ @Test public void it_should_not_write_the_empty_scope_array() throws IOException {
+ JsonNode node = writeAndRead(name);
+
+ assertNull(node.get("scope"));
+ }
+
+ @Test public void it_should_write_a_non_empty_scope_array() throws IOException {
+ name.addTheme(createSimpleNamedTopic("it_should_write_a_non_empty_scope_array"));
+ JsonNode node = writeAndRead(name);
+
+ assertTrue(node.get("scope").isArray());
+ assertGreater(0, node.get("scope").size());
+ }
+
+ @Test public void it_should_not_write_the_empty_variants_array() throws IOException {
+ JsonNode node = writeAndRead(name);
+
+ assertNull(node.get("variants"));
+ }
+
+ @Test public void it_should_write_a_non_empty_variants_array() throws IOException {
+ Name nameWithVariant = createVariant("it_should_write_a_non_empty_variants_array").getParent();
+ JsonNode node = writeAndRead(nameWithVariant);
+
+ assertTrue(node.get("variants").isArray());
+ assertGreater(0, node.get("variants").size());
+ assertNull(node.get("variants").get(0).get("version"));
+ }
+
+ @Test public void it_should_not_write_null_reifier() throws IOException {
+ JsonNode node = writeAndRead(name);
+ assertNull(node.get("reifier"));
+ }
+
+ @Test public void it_should_write_reifier() throws IOException {
+ name.setReifier(createSimpleNamedTopic(getClass().getSimpleName()));
+ JsonNode node = writeAndRead(name);
+ assertEquals(
+ "si:"+ name.getReifier().getSubjectIdentifiers().iterator().next().getReference(),
+ node.get("reifier").getTextValue());
+ }
+
+ @Test public void it_should_not_write_the_empty_item_identifiers() throws IOException {
+ JsonNode node = writeAndRead(name);
+ assertEquals(0, name.getItemIdentifiers().size());
+ assertNull(node.get("item_identifiers"));
+ }
+
+ @Test public void it_should_write_the_item_identifiers() throws IOException {
+ name.addItemIdentifier(createLocator("it_should_write_the_item_identifiers"));
+ JsonNode node = writeAndRead(name);
+
+ assertTrue(node.get("item_identifiers").isArray());
+ assertGreater(0, node.get("item_identifiers").size());
+ assertEquals(
+ name.getItemIdentifiers().iterator().next().getReference(),
+ node.get("item_identifiers").get(0).getTextValue());
+ }
+}
diff --git a/jtm-writer/src/test/java/de/topicmapslab/when_writing_a_role.java b/jtm-writer/src/test/java/de/topicmapslab/when_writing_a_role.java
new file mode 100644
index 0000000..0dd87d6
--- /dev/null
+++ b/jtm-writer/src/test/java/de/topicmapslab/when_writing_a_role.java
@@ -0,0 +1,84 @@
+package de.topicmapslab;
+
+import org.codehaus.jackson.JsonNode;
+import org.junit.Before;
+import org.junit.Test;
+import org.tmapi.core.Association;
+import org.tmapi.core.Role;
+
+import java.io.IOException;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+import static junitx.framework.ComparableAssert.assertGreater;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Author: mhoyer
+ * Created: 28.10.2010 00:41
+ */
+public class when_writing_a_role extends with_JTMWriter {
+ private Role role;
+
+ @Before public void given_a_role() {
+ Association association = createAssociation(getClass().getSimpleName());
+ role = association.createRole(
+ createSimpleNamedTopic("role-type"),
+ createSimpleNamedTopic("player"));
+ }
+
+ @Test public void it_should_write_the_version_and_item_type() throws IOException {
+ JsonNode node = writeAndRead(role);
+ assertEquals(1.0, node.get("version").getValueAsDouble());
+ assertItemType(role, node);
+ }
+
+ @Test public void it_should_write_id() throws IOException {
+ JsonNode node = writeAndRead(role);
+ assertEquals(role.getId(), node.get("id").getTextValue());
+ }
+
+ @Test public void it_should_write_player() throws IOException {
+ JsonNode node = writeAndRead(role);
+ assertEquals(
+ "si:"+ role.getPlayer().getSubjectIdentifiers().iterator().next().getReference(),
+ node.get("player").getTextValue());
+ }
+
+ @Test public void it_should_write_type() throws IOException {
+ JsonNode node = writeAndRead(role);
+ assertEquals(
+ "si:"+ role.getType().getSubjectIdentifiers().iterator().next().getReference(),
+ node.get("type").getTextValue());
+ }
+
+ @Test public void it_should_not_write_null_reifier() throws IOException {
+ JsonNode node = writeAndRead(role);
+ assertNull(node.get("reifier"));
+ }
+
+ @Test public void it_should_write_reifier() throws IOException {
+ role.setReifier(createSimpleNamedTopic(getClass().getSimpleName()));
+ JsonNode node = writeAndRead(role);
+ assertEquals(
+ "si:"+ role.getReifier().getSubjectIdentifiers().iterator().next().getReference(),
+ node.get("reifier").getTextValue());
+ }
+
+ @Test public void it_should_not_write_the_empty_item_identifiers() throws IOException {
+ JsonNode node = writeAndRead(role);
+ assertEquals(0, role.getItemIdentifiers().size());
+ assertNull(node.get("item_identifiers"));
+ }
+
+ @Test public void it_should_write_the_item_identifiers() throws IOException {
+ role.addItemIdentifier(createLocator("it_should_write_the_item_identifiers"));
+ JsonNode node = writeAndRead(role);
+
+ assertTrue(node.get("item_identifiers").isArray());
+ assertGreater(0, node.get("item_identifiers").size());
+ assertEquals(
+ role.getItemIdentifiers().iterator().next().getReference(),
+ node.get("item_identifiers").get(0).getTextValue());
+ }
+}
diff --git a/jtm-writer/src/test/java/de/topicmapslab/when_writing_a_topic.java b/jtm-writer/src/test/java/de/topicmapslab/when_writing_a_topic.java
new file mode 100644
index 0000000..5686eb2
--- /dev/null
+++ b/jtm-writer/src/test/java/de/topicmapslab/when_writing_a_topic.java
@@ -0,0 +1,119 @@
+package de.topicmapslab;
+
+import org.codehaus.jackson.JsonNode;
+import org.junit.Before;
+import org.junit.Test;
+import org.tmapi.core.Topic;
+
+import java.io.IOException;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+import static junitx.framework.ComparableAssert.assertGreater;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Author: mhoyer
+ * Created: 27.10.2010 00:05:04
+ */
+public class when_writing_a_topic extends with_JTMWriter {
+ private Topic topic;
+
+ @Before public void given_a_topic() {
+ topic = topicMap.createTopic();
+ }
+
+ @Test public void it_should_write_the_version_and_item_type() throws IOException {
+ JsonNode node = writeAndRead(topic);
+ assertEquals(1.0, node.get("version").getValueAsDouble());
+ assertItemType(topic, node);
+ }
+
+ @Test public void it_should_write_id() throws IOException {
+ JsonNode node = writeAndRead(topic);
+ assertEquals(topic.getId(), node.get("id").getTextValue());
+ }
+
+ @Test public void it_should_not_write_the_empty_names_array() throws IOException {
+ JsonNode node = writeAndRead(topic);
+
+ assertNull(node.get("names"));
+ }
+
+ @Test public void it_should_write_a_non_empty_names_array() throws IOException {
+ topic.createName("it_should_write_a_non_empty_names_array");
+ JsonNode node = writeAndRead(topic);
+
+ assertTrue(node.get("names").isArray());
+ assertGreater(0, node.get("names").size());
+ assertNull(node.get("names").get(0).get("version"));
+ }
+
+ @Test public void it_should_not_write_the_empty_occurrences_array() throws IOException {
+ JsonNode node = writeAndRead(topic);
+
+ assertNull(node.get("names"));
+ }
+
+ @Test public void it_should_write_a_non_empty_occurrences_array() throws IOException {
+ topic.createOccurrence(topicMap.createTopic(), "it_should_write_a_non_empty_occurrencess_array");
+ JsonNode node = writeAndRead(topic);
+
+ assertTrue(node.get("occurrences").isArray());
+ assertGreater(0, node.get("occurrences").size());
+ assertNull(node.get("occurrences").get(0).get("version"));
+ }
+
+ @Test public void it_should_not_write_the_empty_item_identifiers() throws IOException {
+ topic.addSubjectIdentifier(tms.createLocator("fubar://it_should_not_write_the_empty_item_identifiers"));
+ topic.removeItemIdentifier(topic.getItemIdentifiers().iterator().next());
+ JsonNode node = writeAndRead(topic);
+ assertEquals(0, topic.getItemIdentifiers().size());
+ assertNull(node.get("item_identifiers"));
+ }
+
+ @Test public void it_should_write_the_item_identifiers() throws IOException {
+ JsonNode node = writeAndRead(topic);
+
+ assertTrue(node.get("item_identifiers").isArray());
+ assertGreater(0, node.get("item_identifiers").size());
+ assertEquals(
+ topic.getItemIdentifiers().iterator().next().getReference(),
+ node.get("item_identifiers").get(0).getTextValue());
+ }
+
+ @Test public void it_should_not_write_the_empty_subject_identifiers() throws IOException {
+ JsonNode node = writeAndRead(topic);
+ assertEquals(0, topic.getSubjectIdentifiers().size());
+ assertNull(node.get("subject_identifiers"));
+ }
+
+ @Test public void it_should_write_the_subject_identifiers() throws IOException {
+ topic.addSubjectIdentifier(tms.createLocator("fubar://it_should_write_the_subject_identifiers"));
+ JsonNode node = writeAndRead(topic);
+
+ assertTrue(node.get("subject_identifiers").isArray());
+ assertGreater(0, node.get("subject_identifiers").size());
+ assertEquals(
+ topic.getSubjectIdentifiers().iterator().next().getReference(),
+ node.get("subject_identifiers").get(0).getTextValue());
+ }
+
+ @Test public void it_should_not_write_the_empty_subject_locators() throws IOException {
+ JsonNode node = writeAndRead(topic);
+ assertEquals(0, topic.getSubjectLocators().size());
+ assertNull(node.get("subject_locators"));
+ }
+
+ @Test public void it_should_write_the_subject_locators() throws IOException {
+ topic.addSubjectLocator(tms.createLocator("fubar://it_should_write_the_subject_locators"));
+ JsonNode node = writeAndRead(topic);
+
+ assertTrue(node.get("subject_locators").isArray());
+ assertGreater(0, node.get("subject_locators").size());
+ assertEquals(
+ topic.getSubjectLocators().iterator().next().getReference(),
+ node.get("subject_locators").get(0).getTextValue());
+ }
+
+}
diff --git a/jtm-writer/src/test/java/de/topicmapslab/when_writing_a_topic_map.java b/jtm-writer/src/test/java/de/topicmapslab/when_writing_a_topic_map.java
new file mode 100644
index 0000000..ce5462b
--- /dev/null
+++ b/jtm-writer/src/test/java/de/topicmapslab/when_writing_a_topic_map.java
@@ -0,0 +1,120 @@
+package de.topicmapslab;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+import static junitx.framework.ComparableAssert.assertGreater;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonNode;
+import org.junit.Test;
+import org.tmapi.core.Topic;
+
+import de.topicmapslab.jtm.writer.IJTMConstants;
+import de.topicmapslab.jtm.writer.JTMVersion;
+
+/**
+ * Author: mhoyer Created: 28.10.2010 01:14
+ */
+public class when_writing_a_topic_map extends with_JTMWriter {
+
+ @Test
+ public void it_should_write_the_version_and_item_type() throws IOException {
+ JsonNode node = writeAndRead(topicMap);
+ assertEquals(1.0, node.get("version").getValueAsDouble());
+ assertItemType(topicMap, node);
+ }
+
+ @Test
+ public void it_should_not_write_the_empty_topics_array() throws IOException {
+ JsonNode node = writeAndRead(topicMap);
+
+ assertNull(node.get("topics"));
+ }
+
+ @Test
+ public void it_should_write_a_version() throws IOException {
+ topicMap.createTopic();
+ JsonNode node = writeAndRead(topicMap, JTMVersion.JTM_1_1);
+ assertEquals(IJTMConstants.VERSION_11, node.get(IJTMConstants.VERSION).getTextValue());
+ }
+
+ @Test
+ public void it_should_write_a_non_empty_instance_of_array() throws IOException {
+ Topic t = topicMap.createTopicBySubjectIdentifier(topicMap.createLocator("http://topic-with-si"));
+ Topic type = topicMap.createTopicBySubjectIdentifier(topicMap.createLocator("http://type-with-si"));
+ t.addType(type);
+ JsonNode node = writeAndRead(topicMap, JTMVersion.JTM_1_1);
+ assertTrue(node.get(IJTMConstants.TOPICS).isArray());
+ assertGreater(2, node.get(IJTMConstants.TOPICS).size());
+ boolean found = false;
+ for (JsonNode n : node.get(IJTMConstants.TOPICS)) {
+ if (n.has(IJTMConstants.INSTANCE_OF)) {
+ found = true;
+ assertTrue(n.get(IJTMConstants.INSTANCE_OF).isArray());
+ assertEquals(1, n.get(IJTMConstants.INSTANCE_OF).size());
+ assertEquals("si:http://type-with-si", n.get(IJTMConstants.INSTANCE_OF).get(0).getTextValue());
+ }
+ }
+ assertTrue("At least one topic should contain an instance_of topic array", found);
+ }
+
+ @Test
+ public void it_should_write_a_non_empty_topics_array() throws IOException {
+ topicMap.createTopic();
+ JsonNode node = writeAndRead(topicMap);
+
+ assertTrue(node.get("topics").isArray());
+ assertGreater(0, node.get("topics").size());
+ assertNull(node.get("topics").get(0).get("version"));
+ }
+
+ @Test
+ public void it_should_not_write_the_empty_associations_array() throws IOException {
+ JsonNode node = writeAndRead(topicMap);
+
+ assertNull(node.get("associations"));
+ }
+
+ @Test
+ public void it_should_write_a_non_empty_associations_array() throws IOException {
+ topicMap.createAssociation(topicMap.createTopic()).createRole(topicMap.createTopic(), topicMap.createTopic());
+ JsonNode node = writeAndRead(topicMap);
+
+ assertTrue(node.get("associations").isArray());
+ assertGreater(0, node.get("associations").size());
+ assertNull(node.get("associations").get(0).get("version"));
+ }
+
+ @Test
+ public void it_should_not_write_the_empty_item_identifiers() throws IOException {
+ JsonNode node = writeAndRead(topicMap);
+ assertEquals(0, topicMap.getItemIdentifiers().size());
+ assertNull(node.get("item_identifiers"));
+ }
+
+ @Test
+ public void it_should_write_the_item_identifiers() throws IOException {
+ topicMap.addItemIdentifier(tms.createLocator("fubar://it_should_write_the_item_identifiers"));
+ JsonNode node = writeAndRead(topicMap);
+
+ assertTrue(node.get("item_identifiers").isArray());
+ assertGreater(0, node.get("item_identifiers").size());
+ assertEquals(topicMap.getItemIdentifiers().iterator().next().getReference(), node.get("item_identifiers").get(0).getTextValue());
+ }
+
+ @Test
+ public void it_should_not_write_null_reifier() throws IOException {
+ JsonNode node = writeAndRead(topicMap);
+ assertNull(node.get("reifier"));
+ }
+
+ @Test
+ public void it_should_write_reifier() throws IOException {
+ topicMap.setReifier(createSimpleNamedTopic(getClass().getSimpleName()));
+ JsonNode node = writeAndRead(topicMap);
+ assertEquals("si:" + topicMap.getReifier().getSubjectIdentifiers().iterator().next().getReference(), node.get("reifier").getTextValue());
+ }
+
+}
diff --git a/jtm-writer/src/test/java/de/topicmapslab/when_writing_a_variant.java b/jtm-writer/src/test/java/de/topicmapslab/when_writing_a_variant.java
new file mode 100644
index 0000000..a0d58c7
--- /dev/null
+++ b/jtm-writer/src/test/java/de/topicmapslab/when_writing_a_variant.java
@@ -0,0 +1,106 @@
+package de.topicmapslab;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+import static junitx.framework.ComparableAssert.assertGreater;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonNode;
+import org.junit.Before;
+import org.junit.Test;
+import org.tmapi.core.Topic;
+import org.tmapi.core.Variant;
+
+import de.topicmapslab.majortom.model.namespace.Namespaces;
+
+/**
+ * Author: mhoyer
+ * Created: 27.10.2010 17:39:06
+ */
+public class when_writing_a_variant extends with_JTMWriter {
+ private Variant stringVariant;
+ private Variant locatorVariant;
+
+ @Before public void given_a_string_variant() {
+ stringVariant = createVariant(getClass().getSimpleName());
+ }
+
+ @Before public void given_a_locator_variant() {
+ locatorVariant = createVariant("f");
+ locatorVariant.setValue(topicMap.createLocator(Namespaces.XSD.ANY));
+ }
+
+ @Test public void it_should_write_id() throws IOException {
+ JsonNode node = writeAndRead(stringVariant);
+ assertEquals(stringVariant.getId(), node.get("id").getTextValue());
+ }
+
+ @Test public void it_should_write_the_version_and_item_type() throws IOException {
+ JsonNode node = writeAndRead(stringVariant);
+ assertEquals(1.0, node.get("version").getValueAsDouble());
+ assertItemType(stringVariant, node);
+ }
+
+ @Test public void it_should_not_write_the_datatype_for_string_variants() throws IOException {
+ JsonNode node = writeAndRead(stringVariant);
+ assertNull(node.get("datatype"));
+ }
+
+ @Test public void it_should_write_the_datatype_for_non_string_variants() throws IOException {
+ JsonNode node = writeAndRead(locatorVariant);
+ assertEquals(Namespaces.XSD.ANYURI, node.get("datatype").getTextValue());
+ }
+
+ @Test public void it_should_write_the_empty_scope_array() throws IOException {
+ Topic theme = stringVariant.getScope().iterator().next();
+ stringVariant.removeTheme(theme);
+ JsonNode node = writeAndRead(stringVariant);
+
+ assertTrue(node.get("scope").isArray());
+ assertEquals(0, node.get("scope").size());
+ }
+
+ @Test public void it_should_write_a_non_empty_scope_array() throws IOException {
+ JsonNode node = writeAndRead(stringVariant);
+
+ assertTrue(node.get("scope").isArray());
+ assertGreater(0, node.get("scope").size());
+ }
+
+ @Test public void it_should_write_value() throws IOException {
+ JsonNode node = writeAndRead(stringVariant);
+ assertEquals(stringVariant.getValue(), node.get("value").getTextValue());
+ }
+
+ @Test public void it_should_not_write_null_reifier() throws IOException {
+ JsonNode node = writeAndRead(stringVariant);
+ assertNull(node.get("reifier"));
+ }
+
+ @Test public void it_should_write_reifier() throws IOException {
+ stringVariant.setReifier(createSimpleNamedTopic(getClass().getSimpleName()));
+ JsonNode node = writeAndRead(stringVariant);
+ assertEquals(
+ "si:"+stringVariant.getReifier().getSubjectIdentifiers().iterator().next().getReference(),
+ node.get("reifier").getTextValue());
+ }
+
+ @Test public void it_should_not_write_the_empty_item_identifiers() throws IOException {
+ JsonNode node = writeAndRead(stringVariant);
+ assertEquals(0, stringVariant.getItemIdentifiers().size());
+ assertNull(node.get("item_identifiers"));
+ }
+
+ @Test public void it_should_write_the_item_identifiers() throws IOException {
+ stringVariant.addItemIdentifier(createLocator("it_should_write_the_item_identifiers"));
+ JsonNode node = writeAndRead(stringVariant);
+
+ assertTrue(node.get("item_identifiers").isArray());
+ assertGreater(0, node.get("item_identifiers").size());
+ assertEquals(
+ stringVariant.getItemIdentifiers().iterator().next().getReference(),
+ node.get("item_identifiers").get(0).getTextValue());
+ }
+}
diff --git a/jtm-writer/src/test/java/de/topicmapslab/when_writing_an_association.java b/jtm-writer/src/test/java/de/topicmapslab/when_writing_an_association.java
new file mode 100644
index 0000000..bbebeac
--- /dev/null
+++ b/jtm-writer/src/test/java/de/topicmapslab/when_writing_an_association.java
@@ -0,0 +1,105 @@
+package de.topicmapslab;
+
+import org.codehaus.jackson.JsonGenerationException;
+import org.codehaus.jackson.JsonNode;
+import org.junit.Before;
+import org.junit.Test;
+import org.tmapi.core.Association;
+
+import java.io.IOException;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+import static junitx.framework.ComparableAssert.assertGreater;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Author: mhoyer
+ * Created: 28.10.2010 00:56
+ */
+public class when_writing_an_association extends with_JTMWriter {
+ private Association association;
+
+ @Before public void given_an_association() {
+ association = createAssociation(getClass().getSimpleName(), "simple-role:player");
+ }
+
+ @Test public void it_should_write_the_version_and_item_type() throws IOException {
+ JsonNode node = writeAndRead(association);
+ assertEquals(1.0, node.get("version").getValueAsDouble());
+ assertItemType(association, node);
+ }
+
+ @Test public void it_should_write_id() throws IOException {
+ JsonNode node = writeAndRead(association);
+ assertEquals(association.getId(), node.get("id").getTextValue());
+ }
+
+ @Test public void it_should_write_type() throws IOException {
+ JsonNode node = writeAndRead(association);
+ assertEquals(
+ "si:"+ association.getType().getSubjectIdentifiers().iterator().next().getReference(),
+ node.get("type").getTextValue());
+ }
+
+ @Test public void it_should_not_write_the_empty_scope_array() throws IOException {
+ JsonNode node = writeAndRead(association);
+
+ assertNull(node.get("scope"));
+ }
+
+ @Test public void it_should_write_a_non_empty_scope_array() throws IOException {
+ association.addTheme(createSimpleNamedTopic("it_should_write_a_non_empty_scope_array"));
+ JsonNode node = writeAndRead(association);
+
+ assertTrue(node.get("scope").isArray());
+ assertGreater(0, node.get("scope").size());
+ }
+
+ @Test(expected = JsonGenerationException.class)
+ public void it_should_throw_exception_if_no_role_given() throws IOException {
+ association.getRoles().iterator().next().remove();
+ JsonNode node = writeAndRead(association);
+
+ assertEquals(0, association.getRoles().size());
+ assertNull(node.get("roles"));
+ }
+
+ @Test public void it_should_write_a_non_empty_roles_array() throws IOException {
+ JsonNode node = writeAndRead(association);
+
+ assertTrue(node.get("roles").isArray());
+ assertGreater(0, node.get("roles").size());
+ assertNull(node.get("roles").get(0).get("version"));
+ }
+
+ @Test public void it_should_not_write_null_reifier() throws IOException {
+ JsonNode node = writeAndRead(association);
+ assertNull(node.get("reifier"));
+ }
+
+ @Test public void it_should_write_reifier() throws IOException {
+ association.setReifier(createSimpleNamedTopic(getClass().getSimpleName()));
+ JsonNode node = writeAndRead(association);
+ assertEquals(
+ "si:"+ association.getReifier().getSubjectIdentifiers().iterator().next().getReference(),
+ node.get("reifier").getTextValue());
+ }
+
+ @Test public void it_should_not_write_the_empty_item_identifiers() throws IOException {
+ JsonNode node = writeAndRead(association);
+ assertEquals(0, association.getItemIdentifiers().size());
+ assertNull(node.get("item_identifiers"));
+ }
+
+ @Test public void it_should_write_the_item_identifiers() throws IOException {
+ association.addItemIdentifier(createLocator("it_should_write_the_item_identifiers"));
+ JsonNode node = writeAndRead(association);
+
+ assertTrue(node.get("item_identifiers").isArray());
+ assertGreater(0, node.get("item_identifiers").size());
+ assertEquals(
+ association.getItemIdentifiers().iterator().next().getReference(),
+ node.get("item_identifiers").get(0).getTextValue());
+ }
+}
diff --git a/jtm-writer/src/test/java/de/topicmapslab/when_writing_an_occurrence.java b/jtm-writer/src/test/java/de/topicmapslab/when_writing_an_occurrence.java
new file mode 100644
index 0000000..5cd2c52
--- /dev/null
+++ b/jtm-writer/src/test/java/de/topicmapslab/when_writing_an_occurrence.java
@@ -0,0 +1,110 @@
+package de.topicmapslab;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+import static junitx.framework.ComparableAssert.assertGreater;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonNode;
+import org.junit.Before;
+import org.junit.Test;
+import org.tmapi.core.Occurrence;
+
+import de.topicmapslab.majortom.model.namespace.Namespaces;
+
+/**
+ * Author: mhoyer
+ * Created: 27.10.2010 23:56:33
+ */
+public class when_writing_an_occurrence extends with_JTMWriter {
+ private Occurrence stringOccurrence;
+ private Occurrence locatorOccurrence;
+
+ @Before public void given_a_string_occurrence() {
+ stringOccurrence = createOccurrence(getClass().getSimpleName());
+ }
+
+ @Before public void given_a_locator_occurrence() {
+ locatorOccurrence = createOccurrence("f");
+ locatorOccurrence.setValue( topicMap.createLocator(Namespaces.XSD.ANY));
+ }
+
+ @Test public void it_should_write_the_version_and_item_type() throws IOException {
+ JsonNode node = writeAndRead(stringOccurrence);
+ assertEquals(1.0, node.get("version").getValueAsDouble());
+ assertItemType(stringOccurrence, node);
+ }
+
+ @Test public void it_should_not_write_the_datatype_for_string_occurrences() throws IOException {
+ JsonNode node = writeAndRead(stringOccurrence);
+ assertNull(node.get("datatype"));
+ }
+
+ @Test public void it_should_write_the_datatype_for_non_string_occurrences() throws IOException {
+ JsonNode node = writeAndRead(locatorOccurrence);
+ assertEquals(Namespaces.XSD.ANYURI, node.get("datatype").getTextValue());
+ }
+
+ @Test public void it_should_not_write_the_empty_scope_array() throws IOException {
+ JsonNode node = writeAndRead(stringOccurrence);
+
+ assertNull(node.get("scope"));
+ }
+
+ @Test public void it_should_write_a_non_empty_scope_array() throws IOException {
+ stringOccurrence.addTheme(createSimpleNamedTopic("it_should_write_a_non_empty_scope_array"));
+ JsonNode node = writeAndRead(stringOccurrence);
+
+ assertTrue(node.get("scope").isArray());
+ assertGreater(0, node.get("scope").size());
+ }
+
+ @Test public void it_should_write_value() throws IOException {
+ JsonNode node = writeAndRead(stringOccurrence);
+ assertEquals(stringOccurrence.getValue(), node.get("value").getTextValue());
+ }
+
+ @Test public void it_should_write_id() throws IOException {
+ JsonNode node = writeAndRead(stringOccurrence);
+ assertEquals(stringOccurrence.getId(), node.get("id").getTextValue());
+ }
+
+ @Test public void it_should_write_type() throws IOException {
+ JsonNode node = writeAndRead(stringOccurrence);
+ assertEquals(
+ "si:"+ stringOccurrence.getType().getSubjectIdentifiers().iterator().next().getReference(),
+ node.get("type").getTextValue());
+ }
+
+ @Test public void it_should_not_write_null_reifier() throws IOException {
+ JsonNode node = writeAndRead(stringOccurrence);
+ assertNull(node.get("reifier"));
+ }
+
+ @Test public void it_should_write_reifier() throws IOException {
+ stringOccurrence.setReifier(createSimpleNamedTopic(getClass().getSimpleName()));
+ JsonNode node = writeAndRead(stringOccurrence);
+ assertEquals(
+ "si:"+ stringOccurrence.getReifier().getSubjectIdentifiers().iterator().next().getReference(),
+ node.get("reifier").getTextValue());
+ }
+
+ @Test public void it_should_not_write_the_empty_item_identifiers() throws IOException {
+ JsonNode node = writeAndRead(stringOccurrence);
+ assertEquals(0, stringOccurrence.getItemIdentifiers().size());
+ assertNull(node.get("item_identifiers"));
+ }
+
+ @Test public void it_should_write_the_item_identifiers() throws IOException {
+ stringOccurrence.addItemIdentifier(createLocator("it_should_write_the_item_identifiers"));
+ JsonNode node = writeAndRead(stringOccurrence);
+
+ assertTrue(node.get("item_identifiers").isArray());
+ assertGreater(0, node.get("item_identifiers").size());
+ assertEquals(
+ stringOccurrence.getItemIdentifiers().iterator().next().getReference(),
+ node.get("item_identifiers").get(0).getTextValue());
+ }
+}
diff --git a/jtm-writer/src/test/java/de/topicmapslab/with_JTMWriter.java b/jtm-writer/src/test/java/de/topicmapslab/with_JTMWriter.java
new file mode 100644
index 0000000..a11f945
--- /dev/null
+++ b/jtm-writer/src/test/java/de/topicmapslab/with_JTMWriter.java
@@ -0,0 +1,80 @@
+package de.topicmapslab;
+
+import static junit.framework.Assert.assertEquals;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Collection;
+
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.junit.Before;
+import org.tmapi.core.Association;
+import org.tmapi.core.Construct;
+import org.tmapi.core.Name;
+import org.tmapi.core.Occurrence;
+import org.tmapi.core.Role;
+import org.tmapi.core.Topic;
+import org.tmapi.core.TopicMap;
+import org.tmapi.core.Variant;
+
+import de.topicmapslab.jtm.writer.JTMVersion;
+import de.topicmapslab.jtm.writer.JTMWriter;
+
+/**
+ * Author: mhoyer Created: 27.10.2010 17:39:06
+ */
+public class with_JTMWriter extends with_TopicMap {
+ protected ByteArrayOutputStream out;
+ protected JTMWriter jtmwriter;
+ protected ObjectMapper jsonReader;
+
+ @Before
+ public void given_JTMWriter() {
+ out = new ByteArrayOutputStream();
+ jtmwriter = new JTMWriter(out);
+ }
+
+ @Before
+ public void given_JSON_reader() {
+ jsonReader = new ObjectMapper();
+ }
+
+ protected void assertItemType(Construct construct, JsonNode node) {
+ if (construct instanceof Variant) {
+ assertEquals("variant", node.get("item_type").getValueAsText());
+ }
+ if (construct instanceof Name) {
+ assertEquals("name", node.get("item_type").getValueAsText());
+ }
+ if (construct instanceof Occurrence) {
+ assertEquals("occurrence", node.get("item_type").getValueAsText());
+ }
+ if (construct instanceof Topic) {
+ assertEquals("topic", node.get("item_type").getValueAsText());
+ }
+ if (construct instanceof TopicMap) {
+ assertEquals("topicmap", node.get("item_type").getValueAsText());
+ }
+ if (construct instanceof Association) {
+ assertEquals("association", node.get("item_type").getValueAsText());
+ }
+ if (construct instanceof Role) {
+ assertEquals("role", node.get("item_type").getValueAsText());
+ }
+ }
+
+ protected JsonNode writeAndRead(Construct construct, JTMVersion version) throws IOException {
+ jtmwriter.write(construct, version).flush();
+ return jsonReader.readTree(out.toString());
+ }
+
+ protected JsonNode writeAndRead(Construct construct) throws IOException {
+ return writeAndRead(construct, JTMVersion.JTM_1_0);
+ }
+
+ protected JsonNode writeAndRead(Collection constructs) throws IOException {
+ jtmwriter.write(constructs, JTMVersion.JTM_1_0).flush();
+ return jsonReader.readTree(out.toString());
+ }
+}
diff --git a/jtm-writer/src/test/java/de/topicmapslab/with_TopicMap.java b/jtm-writer/src/test/java/de/topicmapslab/with_TopicMap.java
new file mode 100644
index 0000000..6d823e5
--- /dev/null
+++ b/jtm-writer/src/test/java/de/topicmapslab/with_TopicMap.java
@@ -0,0 +1,114 @@
+package de.topicmapslab;
+
+import org.junit.Before;
+import org.tmapi.core.*;
+
+import java.util.ArrayList;
+
+/**
+ * Author: mhoyer
+ * Created: 27.10.2010 17:39:06
+ */
+public class with_TopicMap {
+ protected TopicMapSystem tms;
+ protected TopicMap topicMap;
+
+ @Before public void given_a_TopicMap() throws TMAPIException {
+ tms = TopicMapSystemFactory.newInstance().newTopicMapSystem();
+ topicMap = tms.createTopicMap("class:" + getClass().getName());
+ }
+
+ protected Association createAssociation(String typeName, String... roles) {
+ Topic assocType = createSimpleNamedTopic(typeName);
+ Association association = topicMap.createAssociation(assocType);
+
+ for(String role: roles)
+ {
+ String[] roleTypeAndPlayer = role.split(":");
+
+ if (roleTypeAndPlayer.length >= 2) {
+ association.createRole(
+ createSimpleNamedTopic(roleTypeAndPlayer[0]),
+ createSimpleNamedTopic(roleTypeAndPlayer[1])
+ );
+ }
+ }
+
+ return association;
+ }
+
+ protected Topic createSimpleNamedTopic(String typeName) {
+ return createTopic(typeName, getClass().getPackage().getName() + "/" + typeName);
+ }
+
+ protected TopicMap createTopicMap(String locator) throws TopicMapExistsException {
+ return tms.createTopicMap("class:" + locator);
+ }
+
+ protected Topic createTopic(String name, String subjectIdentifier)
+ {
+ Topic topic = topicMap.createTopicBySubjectIdentifier(createLocator(subjectIdentifier));
+ topic.createName(name);
+
+ return topic;
+ }
+
+ protected Locator createLocator(String locator)
+ {
+ return tms.createLocator("class:" + locator);
+ }
+
+ protected String getIdentifier(Topic topic) {
+ return ((Locator)topic.getSubjectIdentifiers().toArray()[0]).getReference();
+ }
+
+ protected Name createName(String name, String... themes)
+ {
+ ArrayList scope = new ArrayList();
+ String mergedName = name;
+
+ for(String theme: themes)
+ {
+ scope.add(createSimpleNamedTopic(theme));
+ mergedName = mergedName.concat(theme);
+ }
+
+ Topic temp = createSimpleNamedTopic(name);
+ return temp.createName(createSimpleNamedTopic("MultiScopedNameType"),
+ mergedName,
+ scope);
+ }
+
+ protected Occurrence createOccurrence(String name, String... themes)
+ {
+ ArrayList scope = new ArrayList();
+ String mergedName = name;
+
+ for(String theme: themes)
+ {
+ scope.add(createSimpleNamedTopic(theme));
+ mergedName = mergedName.concat(theme);
+ }
+
+ Topic temp = createSimpleNamedTopic(name);
+ return temp.createOccurrence(createSimpleNamedTopic("MultiScopedNameType"),
+ mergedName,
+ scope);
+ }
+
+ protected Variant createVariant(String name, String... themes)
+ {
+ ArrayList scope = new ArrayList();
+ String mergedName = name;
+
+ for(String theme: themes)
+ {
+ scope.add(createSimpleNamedTopic(theme));
+ mergedName = mergedName.concat(theme);
+ }
+
+ if (scope.isEmpty()) scope.add(createSimpleNamedTopic("variant"));
+
+ Name baseName = createName("base" + name);
+ return baseName.createVariant(mergedName, scope);
+ }}