Showing the changes to Source/Libraries/TimeSeriesJavaLibrary (37 of 37 files). Show all
Unified · Split
| @@ -0,0 +1,6 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <classpath> | ||
| 3 | <classpathentry kind="src" path="src"/> | ||
| 4 | <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> | ||
| 5 | <classpathentry kind="output" path="bin"/> | ||
| 6 | </classpath> | ||
| @@ -0,0 +1,17 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <projectDescription> | ||
| 3 | <name>TimeSeriesJavaLibrary</name> | ||
| 4 | <comment></comment> | ||
| 5 | <projects> | ||
| 6 | </projects> | ||
| 7 | <buildSpec> | ||
| 8 | <buildCommand> | ||
| 9 | <name>org.eclipse.jdt.core.javabuilder</name> | ||
| 10 | <arguments> | ||
| 11 | </arguments> | ||
| 12 | </buildCommand> | ||
| 13 | </buildSpec> | ||
| 14 | <natures> | ||
| 15 | <nature>org.eclipse.jdt.core.javanature</nature> | ||
| 16 | </natures> | ||
| 17 | </projectDescription> | ||
| @@ -0,0 +1,301 @@ | |||
| 1 | eclipse.preferences.version=1 | ||
| 2 | org.eclipse.jdt.core.codeComplete.argumentPrefixes= | ||
| 3 | org.eclipse.jdt.core.codeComplete.argumentSuffixes= | ||
| 4 | org.eclipse.jdt.core.codeComplete.fieldPrefixes=m_ | ||
| 5 | org.eclipse.jdt.core.codeComplete.fieldSuffixes= | ||
| 6 | org.eclipse.jdt.core.codeComplete.localPrefixes= | ||
| 7 | org.eclipse.jdt.core.codeComplete.localSuffixes= | ||
| 8 | org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= | ||
| 9 | org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= | ||
| 10 | org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes= | ||
| 11 | org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes= | ||
| 12 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled | ||
| 13 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 | ||
| 14 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve | ||
| 15 | org.eclipse.jdt.core.compiler.compliance=1.6 | ||
| 16 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate | ||
| 17 | org.eclipse.jdt.core.compiler.debug.localVariable=generate | ||
| 18 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate | ||
| 19 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error | ||
| 20 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error | ||
| 21 | org.eclipse.jdt.core.compiler.source=1.6 | ||
| 22 | org.eclipse.jdt.core.formatter.align_type_members_on_columns=false | ||
| 23 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 | ||
| 24 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 | ||
| 25 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 | ||
| 26 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 | ||
| 27 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 | ||
| 28 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 | ||
| 29 | org.eclipse.jdt.core.formatter.alignment_for_assignment=0 | ||
| 30 | org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 | ||
| 31 | org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 | ||
| 32 | org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 | ||
| 33 | org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 | ||
| 34 | org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 | ||
| 35 | org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 | ||
| 36 | org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 | ||
| 37 | org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 | ||
| 38 | org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 | ||
| 39 | org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 | ||
| 40 | org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 | ||
| 41 | org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 | ||
| 42 | org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 | ||
| 43 | org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 | ||
| 44 | org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 | ||
| 45 | org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 | ||
| 46 | org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 | ||
| 47 | org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 | ||
| 48 | org.eclipse.jdt.core.formatter.blank_lines_after_package=1 | ||
| 49 | org.eclipse.jdt.core.formatter.blank_lines_before_field=0 | ||
| 50 | org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 | ||
| 51 | org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 | ||
| 52 | org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 | ||
| 53 | org.eclipse.jdt.core.formatter.blank_lines_before_method=1 | ||
| 54 | org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 | ||
| 55 | org.eclipse.jdt.core.formatter.blank_lines_before_package=0 | ||
| 56 | org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 | ||
| 57 | org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 | ||
| 58 | org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=next_line | ||
| 59 | org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=next_line | ||
| 60 | org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line | ||
| 61 | org.eclipse.jdt.core.formatter.brace_position_for_block=next_line | ||
| 62 | org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=next_line | ||
| 63 | org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=next_line | ||
| 64 | org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=next_line | ||
| 65 | org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=next_line | ||
| 66 | org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=next_line | ||
| 67 | org.eclipse.jdt.core.formatter.brace_position_for_switch=next_line | ||
| 68 | org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_line | ||
| 69 | org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false | ||
| 70 | org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false | ||
| 71 | org.eclipse.jdt.core.formatter.comment.format_block_comments=true | ||
| 72 | org.eclipse.jdt.core.formatter.comment.format_header=false | ||
| 73 | org.eclipse.jdt.core.formatter.comment.format_html=true | ||
| 74 | org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true | ||
| 75 | org.eclipse.jdt.core.formatter.comment.format_line_comments=true | ||
| 76 | org.eclipse.jdt.core.formatter.comment.format_source_code=true | ||
| 77 | org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true | ||
| 78 | org.eclipse.jdt.core.formatter.comment.indent_root_tags=true | ||
| 79 | org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert | ||
| 80 | org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert | ||
| 81 | org.eclipse.jdt.core.formatter.comment.line_length=80 | ||
| 82 | org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true | ||
| 83 | org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true | ||
| 84 | org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false | ||
| 85 | org.eclipse.jdt.core.formatter.compact_else_if=true | ||
| 86 | org.eclipse.jdt.core.formatter.continuation_indentation=2 | ||
| 87 | org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 | ||
| 88 | org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off | ||
| 89 | org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on | ||
| 90 | org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false | ||
| 91 | org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true | ||
| 92 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true | ||
| 93 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true | ||
| 94 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true | ||
| 95 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true | ||
| 96 | org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true | ||
| 97 | org.eclipse.jdt.core.formatter.indent_empty_lines=false | ||
| 98 | org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true | ||
| 99 | org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true | ||
| 100 | org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true | ||
| 101 | org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false | ||
| 102 | org.eclipse.jdt.core.formatter.indentation.size=4 | ||
| 103 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert | ||
| 104 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert | ||
| 105 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert | ||
| 106 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert | ||
| 107 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert | ||
| 108 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert | ||
| 109 | org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert | ||
| 110 | org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert | ||
| 111 | org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert | ||
| 112 | org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert | ||
| 113 | org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert | ||
| 114 | org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert | ||
| 115 | org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert | ||
| 116 | org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert | ||
| 117 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert | ||
| 118 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert | ||
| 119 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert | ||
| 120 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert | ||
| 121 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert | ||
| 122 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert | ||
| 123 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert | ||
| 124 | org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert | ||
| 125 | org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert | ||
| 126 | org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert | ||
| 127 | org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert | ||
| 128 | org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert | ||
| 129 | org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert | ||
| 130 | org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert | ||
| 131 | org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert | ||
| 132 | org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert | ||
| 133 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert | ||
| 134 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert | ||
| 135 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert | ||
| 136 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert | ||
| 137 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert | ||
| 138 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert | ||
| 139 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert | ||
| 140 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert | ||
| 141 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert | ||
| 142 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert | ||
| 143 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert | ||
| 144 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert | ||
| 145 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert | ||
| 146 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert | ||
| 147 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert | ||
| 148 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert | ||
| 149 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert | ||
| 150 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert | ||
| 151 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert | ||
| 152 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert | ||
| 153 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert | ||
| 154 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert | ||
| 155 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert | ||
| 156 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert | ||
| 157 | org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert | ||
| 158 | org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert | ||
| 159 | org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert | ||
| 160 | org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert | ||
| 161 | org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert | ||
| 162 | org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert | ||
| 163 | org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert | ||
| 164 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert | ||
| 165 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert | ||
| 166 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert | ||
| 167 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert | ||
| 168 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert | ||
| 169 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert | ||
| 170 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert | ||
| 171 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert | ||
| 172 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert | ||
| 173 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert | ||
| 174 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert | ||
| 175 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert | ||
| 176 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert | ||
| 177 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert | ||
| 178 | org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert | ||
| 179 | org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert | ||
| 180 | org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert | ||
| 181 | org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert | ||
| 182 | org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert | ||
| 183 | org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert | ||
| 184 | org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert | ||
| 185 | org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert | ||
| 186 | org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert | ||
| 187 | org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert | ||
| 188 | org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert | ||
| 189 | org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert | ||
| 190 | org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert | ||
| 191 | org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert | ||
| 192 | org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert | ||
| 193 | org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert | ||
| 194 | org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert | ||
| 195 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert | ||
| 196 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert | ||
| 197 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert | ||
| 198 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert | ||
| 199 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert | ||
| 200 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert | ||
| 201 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert | ||
| 202 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert | ||
| 203 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert | ||
| 204 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert | ||
| 205 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert | ||
| 206 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert | ||
| 207 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert | ||
| 208 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert | ||
| 209 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert | ||
| 210 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert | ||
| 211 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert | ||
| 212 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert | ||
| 213 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert | ||
| 214 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert | ||
| 215 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert | ||
| 216 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert | ||
| 217 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert | ||
| 218 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert | ||
| 219 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert | ||
| 220 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert | ||
| 221 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert | ||
| 222 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert | ||
| 223 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert | ||
| 224 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert | ||
| 225 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert | ||
| 226 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert | ||
| 227 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert | ||
| 228 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert | ||
| 229 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert | ||
| 230 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert | ||
| 231 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert | ||
| 232 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert | ||
| 233 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert | ||
| 234 | org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert | ||
| 235 | org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert | ||
| 236 | org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert | ||
| 237 | org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert | ||
| 238 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert | ||
| 239 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert | ||
| 240 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert | ||
| 241 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert | ||
| 242 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert | ||
| 243 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert | ||
| 244 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert | ||
| 245 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert | ||
| 246 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert | ||
| 247 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert | ||
| 248 | org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert | ||
| 249 | org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert | ||
| 250 | org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert | ||
| 251 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert | ||
| 252 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert | ||
| 253 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert | ||
| 254 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert | ||
| 255 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert | ||
| 256 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert | ||
| 257 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert | ||
| 258 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert | ||
| 259 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert | ||
| 260 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert | ||
| 261 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert | ||
| 262 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert | ||
| 263 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert | ||
| 264 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert | ||
| 265 | org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert | ||
| 266 | org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert | ||
| 267 | org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert | ||
| 268 | org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert | ||
| 269 | org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert | ||
| 270 | org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert | ||
| 271 | org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert | ||
| 272 | org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert | ||
| 273 | org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert | ||
| 274 | org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert | ||
| 275 | org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert | ||
| 276 | org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert | ||
| 277 | org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert | ||
| 278 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert | ||
| 279 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert | ||
| 280 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert | ||
| 281 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert | ||
| 282 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert | ||
| 283 | org.eclipse.jdt.core.formatter.join_lines_in_comments=true | ||
| 284 | org.eclipse.jdt.core.formatter.join_wrapped_lines=true | ||
| 285 | org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false | ||
| 286 | org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false | ||
| 287 | org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false | ||
| 288 | org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false | ||
| 289 | org.eclipse.jdt.core.formatter.lineSplit=80 | ||
| 290 | org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false | ||
| 291 | org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false | ||
| 292 | org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 | ||
| 293 | org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 | ||
| 294 | org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true | ||
| 295 | org.eclipse.jdt.core.formatter.tabulation.char=tab | ||
| 296 | org.eclipse.jdt.core.formatter.tabulation.size=4 | ||
| 297 | org.eclipse.jdt.core.formatter.use_on_off_tags=false | ||
| 298 | org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false | ||
| 299 | org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true | ||
| 300 | org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true | ||
| 301 | org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true | ||
| @@ -0,0 +1,9 @@ | |||
| 1 | eclipse.preferences.version=1 | ||
| 2 | formatter_profile=_TimeSeries | ||
| 3 | formatter_settings_version=12 | ||
| 4 | org.eclipse.jdt.ui.exception.name=e | ||
| 5 | org.eclipse.jdt.ui.gettersetter.use.is=true | ||
| 6 | org.eclipse.jdt.ui.javadoc=false | ||
| 7 | org.eclipse.jdt.ui.keywordthis=false | ||
| 8 | org.eclipse.jdt.ui.overrideannotation=true | ||
| 9 | org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\r\n * @return the ${bare_field_name}\r\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\r\n * @param ${param} the ${bare_field_name} to set\r\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\r\n * \r\n */</template><template autoinsert\="false" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\r\n *\r\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Javadoc)\r\n * ${see_to_overridden}\r\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\r\n * ${tags}\r\n * ${see_to_target}\r\n */</template><template autoinsert\="false" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">//******************************************************************************************************\r\n// ${file_name} - Gbtc\r\n//\r\n// Copyright \u00A9 2010, Grid Protection Alliance. All Rights Reserved.\r\n//\r\n// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See\r\n// the NOTICE file distributed with this work for additional information regarding copyright ownership.\r\n// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may\r\n// not use this file except in compliance with the License. You may obtain a copy of the License at\:\r\n//\r\n// http\://www.opensource.org/licenses/eclipse-1.0.php\r\n//\r\n// Unless agreed to in writing, the subject software distributed under the License is distributed on an\r\n// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the\r\n// License for the specific language governing permissions and limitations.\r\n//\r\n// Code Modification History\:\r\n// ----------------------------------------------------------------------------------------------------\r\n// ${date} - ${user}\r\n// Generated original version of source code.\r\n//\r\n//******************************************************************************************************\r\n\r\n${package_declaration}\r\n\r\n${typecomment}\r\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\r\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\r\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\r\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\r\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\r\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\r\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\r\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates> | ||
| @@ -0,0 +1,287 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // Measurement.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/12/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries; | ||
| 25 | |||
| 26 | import java.util.UUID; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * Fundamental data type used by the Time Series Framework. | ||
| 30 | */ | ||
| 31 | public class Measurement | ||
| 32 | { | ||
| 33 | private int m_id; | ||
| 34 | private String m_source; | ||
| 35 | private UUID m_signalId; | ||
| 36 | private String m_tag; | ||
| 37 | private double m_value; | ||
| 38 | private double m_adder; | ||
| 39 | private double m_multiplier; | ||
| 40 | private long m_timestamp; | ||
| 41 | private int m_flags; | ||
| 42 | |||
| 43 | /** | ||
| 44 | * Creates a new instance. | ||
| 45 | */ | ||
| 46 | public Measurement() | ||
| 47 | { | ||
| 48 | m_multiplier = 1; | ||
| 49 | } | ||
| 50 | |||
| 51 | /** | ||
| 52 | * Creates a new instance that is a copy of another instance. | ||
| 53 | * | ||
| 54 | * @param copy the measurement to be copied | ||
| 55 | */ | ||
| 56 | public Measurement(Measurement copy) | ||
| 57 | { | ||
| 58 | m_id = copy.m_id; | ||
| 59 | m_source = copy.m_source; | ||
| 60 | m_signalId = copy.m_signalId; | ||
| 61 | m_tag = copy.m_tag; | ||
| 62 | m_value = copy.m_value; | ||
| 63 | m_adder = copy.m_adder; | ||
| 64 | m_multiplier = copy.m_multiplier; | ||
| 65 | m_timestamp = copy.m_timestamp; | ||
| 66 | m_flags = copy.m_flags; | ||
| 67 | } | ||
| 68 | |||
| 69 | /** | ||
| 70 | * Gets the point ID of the measurement, which is | ||
| 71 | * the suffix of the human-readable measurement key. | ||
| 72 | * | ||
| 73 | * @return the point ID of the measurement | ||
| 74 | * @see #setId(int) | ||
| 75 | */ | ||
| 76 | public int getId() | ||
| 77 | { | ||
| 78 | return m_id; | ||
| 79 | } | ||
| 80 | |||
| 81 | /** | ||
| 82 | * Sets the point ID of the measurement. | ||
| 83 | * | ||
| 84 | * @param id the new value of the point ID | ||
| 85 | * @see #getId() | ||
| 86 | */ | ||
| 87 | public void setId(int id) | ||
| 88 | { | ||
| 89 | m_id = id; | ||
| 90 | } | ||
| 91 | |||
| 92 | /** | ||
| 93 | * Gets the source of the measurement, which is | ||
| 94 | * the prefix of the human-readable measurement key. | ||
| 95 | * | ||
| 96 | * @return the source of the measurement | ||
| 97 | * @see #setSource(String) | ||
| 98 | */ | ||
| 99 | public String getSource() | ||
| 100 | { | ||
| 101 | return m_source; | ||
| 102 | } | ||
| 103 | |||
| 104 | /** | ||
| 105 | * Sets the source of the measurement. | ||
| 106 | * | ||
| 107 | * @param source the new value of the source | ||
| 108 | * @see #getSource() | ||
| 109 | */ | ||
| 110 | public void setSource(String source) | ||
| 111 | { | ||
| 112 | m_source = source; | ||
| 113 | } | ||
| 114 | |||
| 115 | /** | ||
| 116 | * Gets the measurement's globally unique identifier. | ||
| 117 | * | ||
| 118 | * @return the measurement's globally unique identifier | ||
| 119 | * @see #setSignalId(UUID) | ||
| 120 | */ | ||
| 121 | public UUID getSignalId() | ||
| 122 | { | ||
| 123 | return m_signalId; | ||
| 124 | } | ||
| 125 | |||
| 126 | /** | ||
| 127 | * Sets the measurement's globally unique identifier. | ||
| 128 | * | ||
| 129 | * @param signalID the new value of the measurement's globally unique identifier | ||
| 130 | * @see #getSignalId() | ||
| 131 | */ | ||
| 132 | public void setSignalId(UUID signalID) | ||
| 133 | { | ||
| 134 | m_signalId = signalID; | ||
| 135 | } | ||
| 136 | |||
| 137 | /** | ||
| 138 | * Gets the human-readable tag name that describes the measurement. | ||
| 139 | * | ||
| 140 | * @return the human readable tag name | ||
| 141 | * @see #setTag(String) | ||
| 142 | */ | ||
| 143 | public String getTag() | ||
| 144 | { | ||
| 145 | return m_tag; | ||
| 146 | } | ||
| 147 | |||
| 148 | /** | ||
| 149 | * Sets the human-readable tag name. | ||
| 150 | * | ||
| 151 | * @param tag the new value of the human-readable tag name | ||
| 152 | * @see #getTag() | ||
| 153 | */ | ||
| 154 | public void setTag(String tag) | ||
| 155 | { | ||
| 156 | m_tag = tag; | ||
| 157 | } | ||
| 158 | |||
| 159 | /** | ||
| 160 | * Gets the value of the measurement. | ||
| 161 | * | ||
| 162 | * @return the value of the measurement | ||
| 163 | * @see #setValue(double) | ||
| 164 | * @see #getAdjustedValue() | ||
| 165 | */ | ||
| 166 | public double getValue() | ||
| 167 | { | ||
| 168 | return m_value; | ||
| 169 | } | ||
| 170 | |||
| 171 | /** | ||
| 172 | * Sets the value of the measurement. | ||
| 173 | * | ||
| 174 | * @param value the new value | ||
| 175 | * @see #getValue() | ||
| 176 | * @see #getAdjustedValue() | ||
| 177 | */ | ||
| 178 | public void setValue(double value) | ||
| 179 | { | ||
| 180 | m_value = value; | ||
| 181 | } | ||
| 182 | |||
| 183 | /** | ||
| 184 | * Gets the additive value modifier. | ||
| 185 | * | ||
| 186 | * @return the additive value modifier | ||
| 187 | * @see #setAdder(double) | ||
| 188 | * @see #getAdjustedValue() | ||
| 189 | */ | ||
| 190 | public double getAdder() | ||
| 191 | { | ||
| 192 | return m_adder; | ||
| 193 | } | ||
| 194 | |||
| 195 | /** | ||
| 196 | * Sets the additive value modifier. | ||
| 197 | * | ||
| 198 | * @param adder the new additive value modifier | ||
| 199 | * @see #getAdder() | ||
| 200 | * @see #getAdjustedValue() | ||
| 201 | */ | ||
| 202 | public void setAdder(double adder) | ||
| 203 | { | ||
| 204 | m_adder = adder; | ||
| 205 | } | ||
| 206 | |||
| 207 | /** | ||
| 208 | * Gets the multiplicative value modifier. | ||
| 209 | * | ||
| 210 | * @return the multiplicative value modifier | ||
| 211 | * @see #setMultiplier(double) | ||
| 212 | * @see #getAdjustedValue() | ||
| 213 | */ | ||
| 214 | public double getMultiplier() | ||
| 215 | { | ||
| 216 | return m_multiplier; | ||
| 217 | } | ||
| 218 | |||
| 219 | /** | ||
| 220 | * Sets the multiplicative value modifier. | ||
| 221 | * | ||
| 222 | * @param multiplier the new multiplicative value modifier | ||
| 223 | * @see #getMultiplier() | ||
| 224 | * @see #getAdjustedValue() | ||
| 225 | */ | ||
| 226 | public void setMultiplier(double multiplier) | ||
| 227 | { | ||
| 228 | m_multiplier = multiplier; | ||
| 229 | } | ||
| 230 | |||
| 231 | /** | ||
| 232 | * Gets the timestamp of the measurement in ticks. | ||
| 233 | * | ||
| 234 | * @return the timestamp of the measurement | ||
| 235 | */ | ||
| 236 | public long getTimestamp() | ||
| 237 | { | ||
| 238 | return m_timestamp; | ||
| 239 | } | ||
| 240 | |||
| 241 | /** | ||
| 242 | * Sets the timestamp of the measurement. | ||
| 243 | * | ||
| 244 | * @param timestamp the new timestamp | ||
| 245 | */ | ||
| 246 | public void setTimestamp(long timestamp) | ||
| 247 | { | ||
| 248 | m_timestamp = timestamp; | ||
| 249 | } | ||
| 250 | |||
| 251 | /** | ||
| 252 | * Gets the flags which define the measurement's state. | ||
| 253 | * | ||
| 254 | * @return the measurement's state flags | ||
| 255 | */ | ||
| 256 | public int getFlags() | ||
| 257 | { | ||
| 258 | return m_flags; | ||
| 259 | } | ||
| 260 | |||
| 261 | /** | ||
| 262 | * Sets the flags which define the measurement's state. | ||
| 263 | * | ||
| 264 | * @param flags the new state flags | ||
| 265 | */ | ||
| 266 | public void setFlags(int flags) | ||
| 267 | { | ||
| 268 | m_flags = flags; | ||
| 269 | } | ||
| 270 | |||
| 271 | /** | ||
| 272 | * Gets the adjusted value of the measurement, which is the value | ||
| 273 | * of the measurement after applying the multiplicative and | ||
| 274 | * additive value modifiers. Mathematically defined as: | ||
| 275 | * <p> | ||
| 276 | * {@code AdjustedValue = (Multiplier * Value) + Adder} | ||
| 277 | * | ||
| 278 | * @return the value of the measurement after applying modifiers | ||
| 279 | * @see #getValue() | ||
| 280 | * @see #getAdder() | ||
| 281 | * @see #getMultiplier() | ||
| 282 | */ | ||
| 283 | public double getAdjustedValue() | ||
| 284 | { | ||
| 285 | return m_value * m_multiplier + m_adder; | ||
| 286 | } | ||
| 287 | } | ||
| @@ -0,0 +1,143 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // MeasurementKey.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/12/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries; | ||
| 25 | |||
| 26 | import java.util.UUID; | ||
| 27 | |||
| 28 | import org.gpa.gsf.timeseries.util.StringExtensions; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * Represents a grouping of a measurement's globally unique identifier | ||
| 32 | * and the alternate human-readable identifier {@code SOURCE:ID}. | ||
| 33 | * @see Measurement | ||
| 34 | */ | ||
| 35 | public class MeasurementKey | ||
| 36 | { | ||
| 37 | private UUID m_signalId; | ||
| 38 | private String m_source; | ||
| 39 | private int m_id; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * Constructs a measurement key by grouping the given parameters. | ||
| 43 | * | ||
| 44 | * @param signalId the measurement's globally unique identifier | ||
| 45 | * @param source the measurement's source | ||
| 46 | * @param id the measurement's ID | ||
| 47 | * @throws IllegalArgumentException if the given {@code signalID} is {@code null} | ||
| 48 | * or the given {@code source} is {@code null} or empty | ||
| 49 | */ | ||
| 50 | public MeasurementKey(UUID signalId, String source, int id) | ||
| 51 | { | ||
| 52 | if (signalId == null) | ||
| 53 | throw new IllegalArgumentException("signalId must not be null"); | ||
| 54 | |||
| 55 | if (StringExtensions.isNullOrWhitespace(source)) | ||
| 56 | throw new IllegalArgumentException("source must not be null or empty"); | ||
| 57 | |||
| 58 | m_signalId = signalId; | ||
| 59 | m_source = source; | ||
| 60 | m_id = id; | ||
| 61 | } | ||
| 62 | |||
| 63 | /** | ||
| 64 | * Gets the globally unique identifier of the measurement. | ||
| 65 | * | ||
| 66 | * @return the measurement's globally unique identifier | ||
| 67 | * @see Measurement#getSignalId() | ||
| 68 | */ | ||
| 69 | public UUID getSignalId() | ||
| 70 | { | ||
| 71 | return m_signalId; | ||
| 72 | } | ||
| 73 | |||
| 74 | /** | ||
| 75 | * Gets the source of the measurement. | ||
| 76 | * | ||
| 77 | * @return the measurement's source | ||
| 78 | * @see Measurement#getSource() | ||
| 79 | */ | ||
| 80 | public String getSource() | ||
| 81 | { | ||
| 82 | return m_source; | ||
| 83 | } | ||
| 84 | |||
| 85 | /** | ||
| 86 | * Gets the simple numeric identifier of the measurement. | ||
| 87 | * | ||
| 88 | * @return the measurement's simple numeric identifier | ||
| 89 | * @see Measurement#getId() | ||
| 90 | */ | ||
| 91 | public int getId() | ||
| 92 | { | ||
| 93 | return m_id; | ||
| 94 | } | ||
| 95 | |||
| 96 | /** | ||
| 97 | * Compares this object to the specified object. The result is | ||
| 98 | * true if and only if the argument is not {@code null} and is | ||
| 99 | * a {@code MeasurementKey} that contains the same signal ID as | ||
| 100 | * this object. | ||
| 101 | */ | ||
| 102 | @Override | ||
| 103 | public boolean equals(Object obj) | ||
| 104 | { | ||
| 105 | MeasurementKey key; | ||
| 106 | |||
| 107 | if(obj == null || !(obj instanceof MeasurementKey)) | ||
| 108 | return false; | ||
| 109 | |||
| 110 | key = (MeasurementKey)obj; | ||
| 111 | return m_signalId.equals(key.m_signalId); | ||
| 112 | } | ||
| 113 | |||
| 114 | /** | ||
| 115 | * Returns a hash code for this {@code MeasurementKey}. | ||
| 116 | */ | ||
| 117 | @Override | ||
| 118 | public int hashCode() | ||
| 119 | { | ||
| 120 | return m_signalId.hashCode(); | ||
| 121 | } | ||
| 122 | |||
| 123 | /** | ||
| 124 | * Creates a measurement key for the given measurement, if it has one. | ||
| 125 | * This method returns null if either the measurement's signal ID | ||
| 126 | * is null or the source is null or empty. | ||
| 127 | * | ||
| 128 | * @param measurement the measurement whose key is to be created | ||
| 129 | * @return the key for the given measurement | ||
| 130 | */ | ||
| 131 | public static MeasurementKey getKey(Measurement measurement) | ||
| 132 | { | ||
| 133 | UUID signalId = measurement.getSignalId(); | ||
| 134 | String source = measurement.getSource(); | ||
| 135 | int id = measurement.getId(); | ||
| 136 | MeasurementKey key = null; | ||
| 137 | |||
| 138 | if (signalId != null && StringExtensions.isNullOrWhitespace(source)) | ||
| 139 | key = new MeasurementKey(signalId, source, id); | ||
| 140 | |||
| 141 | return key; | ||
| 142 | } | ||
| 143 | } | ||
| @@ -0,0 +1,453 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // AdvancedSubscribe.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/23/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.sample; | ||
| 25 | |||
| 26 | import java.awt.GridBagConstraints; | ||
| 27 | import java.awt.GridBagLayout; | ||
| 28 | import java.awt.event.ActionEvent; | ||
| 29 | import java.awt.event.ActionListener; | ||
| 30 | import java.io.IOException; | ||
| 31 | import java.io.OutputStream; | ||
| 32 | import java.io.PrintStream; | ||
| 33 | import java.net.SocketException; | ||
| 34 | import java.nio.ByteBuffer; | ||
| 35 | import java.nio.charset.Charset; | ||
| 36 | |||
| 37 | import javax.swing.Box; | ||
| 38 | import javax.swing.BoxLayout; | ||
| 39 | import javax.swing.JApplet; | ||
| 40 | import javax.swing.JButton; | ||
| 41 | import javax.swing.JLabel; | ||
| 42 | import javax.swing.JScrollPane; | ||
| 43 | import javax.swing.JTextArea; | ||
| 44 | import javax.swing.JTextField; | ||
| 45 | import javax.swing.SwingUtilities; | ||
| 46 | |||
| 47 | import org.gpa.gsf.timeseries.transport.DataSubscriber; | ||
| 48 | import org.gpa.gsf.timeseries.transport.SubscriberConnector; | ||
| 49 | import org.gpa.gsf.timeseries.transport.SubscriptionInfo; | ||
| 50 | import org.gpa.gsf.timeseries.transport.event.SubscriberConnectorListener; | ||
| 51 | |||
| 52 | /** | ||
| 53 | * Sample applet to demonstrate the more advanced use of the subscriber API. | ||
| 54 | * | ||
| 55 | * This application accepts the hostname and port of the publisher via text | ||
| 56 | * fields on the applet, connects to the publisher, subscribes, and displays | ||
| 57 | * information about the measurements it receives. It assumes that the | ||
| 58 | * publisher is providing fourteen measurements (PPA:1 through PPA:14) and | ||
| 59 | * will retry infinitely if it has any trouble connecting. It will also | ||
| 60 | * automatically reconnect if the connection is terminated. | ||
| 61 | * | ||
| 62 | * Measurements are transmitted via a separate UDP data channel. | ||
| 63 | */ | ||
| 64 | public class AdvancedSubscribe extends JApplet | ||
| 65 | { | ||
| 66 | private Object m_connectLock; | ||
| 67 | private ActionListener m_connectListener; | ||
| 68 | private ActionListener m_disconnectListener; | ||
| 69 | |||
| 70 | private JScrollPane m_outputScrollPane; | ||
| 71 | private JTextArea m_outputTextArea; | ||
| 72 | private JLabel m_hostnameLabel; | ||
| 73 | private JLabel m_portLabel; | ||
| 74 | private JTextField m_hostnameTextField; | ||
| 75 | private JTextField m_portTextField; | ||
| 76 | private JButton m_connectButton; | ||
| 77 | private JButton m_disconnectButton; | ||
| 78 | private Box m_buttonBox; | ||
| 79 | |||
| 80 | private PrintStream m_outputStream; | ||
| 81 | private SubscriptionInfo m_subscriptionInfo; | ||
| 82 | private SubscriberConnector m_connector; | ||
| 83 | private DataSubscriber m_subscriber; | ||
| 84 | |||
| 85 | @Override | ||
| 86 | public void init() | ||
| 87 | { | ||
| 88 | GridBagConstraints constraints; | ||
| 89 | |||
| 90 | super.init(); | ||
| 91 | |||
| 92 | // Initialize members | ||
| 93 | m_connectLock = new Object(); | ||
| 94 | m_connectListener = createConnectListener(); | ||
| 95 | m_disconnectListener = createDisconnectListener(); | ||
| 96 | |||
| 97 | m_outputTextArea = createOutputTextArea(); | ||
| 98 | m_outputScrollPane = new JScrollPane(m_outputTextArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); | ||
| 99 | m_hostnameLabel = new JLabel("Hostname"); | ||
| 100 | m_portLabel = new JLabel("Port"); | ||
| 101 | m_hostnameTextField = createHostnameTextField(); | ||
| 102 | m_portTextField = createPortTextField(); | ||
| 103 | m_connectButton = createConnectButton(); | ||
| 104 | m_disconnectButton = createDisconnectButton(); | ||
| 105 | m_buttonBox = createButtonBox(); | ||
| 106 | |||
| 107 | m_outputStream = createOutputStream(); | ||
| 108 | m_subscriptionInfo = createSubscriptionInfo(); | ||
| 109 | m_connector = createSubscriberConnector(m_subscriptionInfo, m_outputStream); | ||
| 110 | m_subscriber = createSubscriber(); | ||
| 111 | |||
| 112 | // Component layout | ||
| 113 | getContentPane().setLayout(new GridBagLayout()); | ||
| 114 | |||
| 115 | constraints = new GridBagConstraints(); | ||
| 116 | constraints.fill = GridBagConstraints.BOTH; | ||
| 117 | constraints.gridwidth = 2; | ||
| 118 | constraints.weighty = 1.0; | ||
| 119 | getContentPane().add(m_outputScrollPane, constraints); | ||
| 120 | |||
| 121 | constraints = new GridBagConstraints(); | ||
| 122 | constraints.gridy = 1; | ||
| 123 | constraints.weightx = 0.5; | ||
| 124 | getContentPane().add(m_hostnameLabel, constraints); | ||
| 125 | |||
| 126 | constraints = new GridBagConstraints(); | ||
| 127 | constraints.gridx = 1; | ||
| 128 | constraints.gridy = 1; | ||
| 129 | constraints.weightx = 0.5; | ||
| 130 | getContentPane().add(m_portLabel, constraints); | ||
| 131 | |||
| 132 | constraints = new GridBagConstraints(); | ||
| 133 | constraints.fill = GridBagConstraints.HORIZONTAL; | ||
| 134 | constraints.gridy = 2; | ||
| 135 | constraints.weightx = 0.5; | ||
| 136 | getContentPane().add(m_hostnameTextField, constraints); | ||
| 137 | |||
| 138 | constraints = new GridBagConstraints(); | ||
| 139 | constraints.fill = GridBagConstraints.HORIZONTAL; | ||
| 140 | constraints.gridx = 1; | ||
| 141 | constraints.gridy = 2; | ||
| 142 | constraints.weightx = 0.5; | ||
| 143 | getContentPane().add(m_portTextField, constraints); | ||
| 144 | |||
| 145 | constraints = new GridBagConstraints(); | ||
| 146 | constraints.anchor = GridBagConstraints.CENTER; | ||
| 147 | constraints.gridy = 3; | ||
| 148 | constraints.gridwidth = 2; | ||
| 149 | getContentPane().add(m_buttonBox, constraints); | ||
| 150 | } | ||
| 151 | |||
| 152 | // Creates the action listener used to connect to the publisher. | ||
| 153 | private ActionListener createConnectListener() | ||
| 154 | { | ||
| 155 | return new ActionListener() | ||
| 156 | { | ||
| 157 | @Override | ||
| 158 | public void actionPerformed(ActionEvent arg0) | ||
| 159 | { | ||
| 160 | // Set the hostname and port before attempting to connect | ||
| 161 | m_connector.setHostname(m_hostnameTextField.getText()); | ||
| 162 | m_connector.setPort(Integer.parseInt(m_portTextField.getText())); | ||
| 163 | |||
| 164 | // Connect asynchronously so we don't hog the UI thread | ||
| 165 | connectAsync(); | ||
| 166 | } | ||
| 167 | }; | ||
| 168 | } | ||
| 169 | |||
| 170 | // Connects and subscribes to the publisher asynchronously. | ||
| 171 | private void connectAsync() | ||
| 172 | { | ||
| 173 | new Thread(new Runnable() | ||
| 174 | { | ||
| 175 | @Override | ||
| 176 | public void run() | ||
| 177 | { | ||
| 178 | // Lock the connect lock so we don't encounter | ||
| 179 | // synchronization issues between calls to connectAsync | ||
| 180 | // and disconnectAsync | ||
| 181 | synchronized (m_connectLock) | ||
| 182 | { | ||
| 183 | try | ||
| 184 | { | ||
| 185 | if (m_connector.connect(m_subscriber)) | ||
| 186 | m_subscriber.subscribe(m_subscriptionInfo); | ||
| 187 | } | ||
| 188 | catch (SocketException ex) | ||
| 189 | { | ||
| 190 | ex.printStackTrace(m_outputStream); | ||
| 191 | } | ||
| 192 | } | ||
| 193 | } | ||
| 194 | }).start(); | ||
| 195 | } | ||
| 196 | |||
| 197 | // Creates the disconnect listener used to disconnect from the publisher. | ||
| 198 | private ActionListener createDisconnectListener() | ||
| 199 | { | ||
| 200 | return new ActionListener() | ||
| 201 | { | ||
| 202 | @Override | ||
| 203 | public void actionPerformed(ActionEvent arg0) | ||
| 204 | { | ||
| 205 | // Disconnect asynchronously so we don't hog the UI thread | ||
| 206 | disconnectAsync(); | ||
| 207 | } | ||
| 208 | }; | ||
| 209 | } | ||
| 210 | |||
| 211 | // Disconnects from the publisher asynchronously. | ||
| 212 | private void disconnectAsync() | ||
| 213 | { | ||
| 214 | new Thread(new Runnable() | ||
| 215 | { | ||
| 216 | @Override | ||
| 217 | public void run() | ||
| 218 | { | ||
| 219 | // Cancel the connector first so it won't try | ||
| 220 | // to automatically reconnect for any reason | ||
| 221 | m_connector.cancel(); | ||
| 222 | |||
| 223 | // Lock the connect lock so we don't encounter | ||
| 224 | // synchronization issues between calls to connectAsync | ||
| 225 | // and disconnectAsync | ||
| 226 | synchronized (m_connectLock) | ||
| 227 | { | ||
| 228 | // Disconnect from the publisher | ||
| 229 | m_subscriber.disconnect(); | ||
| 230 | |||
| 231 | // Create a new subscriber connector since we cancelled the old one | ||
| 232 | m_connector = createSubscriberConnector(m_subscriptionInfo, m_outputStream); | ||
| 233 | } | ||
| 234 | } | ||
| 235 | }).start(); | ||
| 236 | } | ||
| 237 | |||
| 238 | // Creates the text area to which we send our program output. | ||
| 239 | private JTextArea createOutputTextArea() | ||
| 240 | { | ||
| 241 | JTextArea outputTextArea = new JTextArea(); | ||
| 242 | outputTextArea.setEditable(false); | ||
| 243 | outputTextArea.setLineWrap(true); | ||
| 244 | outputTextArea.setWrapStyleWord(true); | ||
| 245 | return outputTextArea; | ||
| 246 | } | ||
| 247 | |||
| 248 | // Creates the text field where the user enters the hostname. | ||
| 249 | private JTextField createHostnameTextField() | ||
| 250 | { | ||
| 251 | JTextField hostnameTextField = new JTextField("localhost"); | ||
| 252 | hostnameTextField.addActionListener(m_connectListener); | ||
| 253 | return hostnameTextField; | ||
| 254 | } | ||
| 255 | |||
| 256 | // Creates the text field where the user enters the port number. | ||
| 257 | private JTextField createPortTextField() | ||
| 258 | { | ||
| 259 | JTextField portTextField = new JTextField("6170"); | ||
| 260 | portTextField.addActionListener(m_connectListener); | ||
| 261 | return portTextField; | ||
| 262 | } | ||
| 263 | |||
| 264 | // Creates the button used to connect to the publisher. | ||
| 265 | private JButton createConnectButton() | ||
| 266 | { | ||
| 267 | JButton connectButton = new JButton("Connect"); | ||
| 268 | connectButton.addActionListener(m_connectListener); | ||
| 269 | return connectButton; | ||
| 270 | } | ||
| 271 | |||
| 272 | // Creates the button used to disconnect from the publisher. | ||
| 273 | private JButton createDisconnectButton() | ||
| 274 | { | ||
| 275 | JButton disconnectButton = new JButton("Disconnect"); | ||
| 276 | disconnectButton.addActionListener(m_disconnectListener); | ||
| 277 | return disconnectButton; | ||
| 278 | } | ||
| 279 | |||
| 280 | // Creates the box that contains the connect and disconnect buttons. | ||
| 281 | private Box createButtonBox() | ||
| 282 | { | ||
| 283 | Box buttonBox = new Box(BoxLayout.X_AXIS); | ||
| 284 | buttonBox.add(m_connectButton); | ||
| 285 | buttonBox.add(m_disconnectButton); | ||
| 286 | return buttonBox; | ||
| 287 | } | ||
| 288 | |||
| 289 | // Creates the output stream that writes to the text area. | ||
| 290 | private PrintStream createOutputStream() | ||
| 291 | { | ||
| 292 | return new PrintStream(new TextAreaOutputStream(m_outputTextArea)); | ||
| 293 | } | ||
| 294 | |||
| 295 | // SubscriptionInfo is a helper object which allows the user | ||
| 296 | // to set up their subscription and resuse subscription settings. | ||
| 297 | private SubscriptionInfo createSubscriptionInfo() | ||
| 298 | { | ||
| 299 | SubscriptionInfo info = new SubscriptionInfo(); | ||
| 300 | |||
| 301 | // The following filter expression formats are also available: | ||
| 302 | // | ||
| 303 | // - Signal ID list - | ||
| 304 | //info.setFilterExpression("7aaf0a8f-3a4f-4c43-ab43-ed9d1e64a255;" + | ||
| 305 | // "93673c68-d59d-4926-b7e9-e7678f9f66b4;" + | ||
| 306 | // "65ac9cf6-ae33-4ece-91b6-bb79343855d5;" + | ||
| 307 | // "3647f729-d0ed-4f79-85ad-dae2149cd432;" + | ||
| 308 | // "069c5e29-f78a-46f6-9dff-c92cb4f69371;" + | ||
| 309 | // "25355a7b-2a9d-4ef2-99ba-4dd791461379"); | ||
| 310 | // | ||
| 311 | // - Filter pattern - | ||
| 312 | //info.setFilterExpression("FILTER ActiveMeasurements WHERE ID LIKE 'PPA:*'"); | ||
| 313 | //info.setFilterExpression("FILTER ActiveMeasurements WHERE Device = 'SHELBY' AND SignalType = 'FREQ'"); | ||
| 314 | |||
| 315 | info.setFilterExpression("PPA:1;PPA:2;PPA:3;PPA:4;PPA:5;PPA:6;PPA:7;PPA:8;PPA:9;PPA:10;PPA:11;PPA:12;PPA:13;PPA:14"); | ||
| 316 | |||
| 317 | // To set up a remotely synchronized subscription, set this flag | ||
| 318 | // to true and add the framesPerSecond parameter to the | ||
| 319 | // ExtraConnectionStringParameters. Additionally, the following | ||
| 320 | // example demonstrates the use of some other useful parameters | ||
| 321 | // when setting up remotely synchronized subscriptions. | ||
| 322 | // | ||
| 323 | //info.setRemotelySynchronized(true); | ||
| 324 | //info.setExtraConnectionStringParameters("framesPerSecond=30;timeResolution=10000;downsamplingMethod=Closest"); | ||
| 325 | |||
| 326 | info.setRemotelySynchronized(false); | ||
| 327 | info.setThrottled(false); | ||
| 328 | |||
| 329 | info.setUdpDataChannel(true); | ||
| 330 | info.setDataChannelLocalPort(9600); | ||
| 331 | |||
| 332 | info.setTimeIncluded(true); | ||
| 333 | info.setLagTime(3.0); | ||
| 334 | info.setLeadTime(1.0); | ||
| 335 | info.setLocalClockAsRealTime(false); | ||
| 336 | info.setMillisecondResolution(true); | ||
| 337 | |||
| 338 | return info; | ||
| 339 | } | ||
| 340 | |||
| 341 | // SubscriberConnector is another helper object which allows the | ||
| 342 | // user to modify settings for auto-reconnects and retry cycles. | ||
| 343 | private SubscriberConnector createSubscriberConnector(SubscriptionInfo info, PrintStream outputStream) | ||
| 344 | { | ||
| 345 | SubscriberConnector connector = new SubscriberConnector(); | ||
| 346 | SubscriberConnectorListener listener = new SampleSubscriberConnectorListener(info, outputStream); | ||
| 347 | |||
| 348 | connector.setMaxRetries(-1); | ||
| 349 | connector.setRetryInterval(5000); | ||
| 350 | connector.setAutoReconnect(true); | ||
| 351 | connector.addSubscriberConnectorListener(listener); | ||
| 352 | |||
| 353 | return connector; | ||
| 354 | } | ||
| 355 | |||
| 356 | // Creates the data subscriber. | ||
| 357 | private DataSubscriber createSubscriber() | ||
| 358 | { | ||
| 359 | DataSubscriber subscriber = new DataSubscriber(); | ||
| 360 | subscriber.addSubscriberListener(new SampleSubscriberListener(m_outputStream, m_outputStream)); | ||
| 361 | return subscriber; | ||
| 362 | } | ||
| 363 | |||
| 364 | private static final long serialVersionUID = -787591661184215315L; | ||
| 365 | |||
| 366 | // OutputStream that, when wrapped by a | ||
| 367 | // PrintStream, allows for output to a JTextArea. | ||
| 368 | private class TextAreaOutputStream extends OutputStream | ||
| 369 | { | ||
| 370 | private ByteBuffer m_buffer; | ||
| 371 | private JTextArea m_outputArea; | ||
| 372 | |||
| 373 | public TextAreaOutputStream(JTextArea outputTextArea) | ||
| 374 | { | ||
| 375 | if (outputTextArea == null) | ||
| 376 | throw new IllegalArgumentException("outputTextArea must not be null"); | ||
| 377 | |||
| 378 | m_buffer = ByteBuffer.allocate(2000); | ||
| 379 | m_outputArea = outputTextArea; | ||
| 380 | } | ||
| 381 | |||
| 382 | @Override | ||
| 383 | public void flush() throws IOException | ||
| 384 | { | ||
| 385 | m_buffer.flip(); | ||
| 386 | append(Charset.defaultCharset().decode(m_buffer).toString()); | ||
| 387 | m_buffer = m_buffer.compact(); | ||
| 388 | } | ||
| 389 | |||
| 390 | @Override | ||
| 391 | public void write(byte[] b) throws IOException | ||
| 392 | { | ||
| 393 | write(b, 0, b.length); | ||
| 394 | } | ||
| 395 | |||
| 396 | @Override | ||
| 397 | public void write(byte[] b, int off, int len) throws IOException | ||
| 398 | { | ||
| 399 | int rem = m_buffer.remaining(); | ||
| 400 | |||
| 401 | if (len <= rem) | ||
| 402 | { | ||
| 403 | m_buffer.put(b, off, len); | ||
| 404 | |||
| 405 | if (m_buffer.position() >= DumpThreshold) | ||
| 406 | flush(); | ||
| 407 | } | ||
| 408 | else | ||
| 409 | { | ||
| 410 | m_buffer.put(b, off, rem); | ||
| 411 | flush(); | ||
| 412 | |||
| 413 | for (int i = rem; i < len; i += m_buffer.capacity()) | ||
| 414 | { | ||
| 415 | rem = Math.min(m_buffer.remaining(), len - i); | ||
| 416 | m_buffer.put(b, off + i, rem); | ||
| 417 | flush(); | ||
| 418 | } | ||
| 419 | } | ||
| 420 | } | ||
| 421 | |||
| 422 | @Override | ||
| 423 | public void write(int b) throws IOException | ||
| 424 | { | ||
| 425 | m_buffer.put((byte)b); | ||
| 426 | |||
| 427 | if (m_buffer.position() >= DumpThreshold) | ||
| 428 | flush(); | ||
| 429 | } | ||
| 430 | |||
| 431 | private void append(final String text) | ||
| 432 | { | ||
| 433 | SwingUtilities.invokeLater(new Runnable() | ||
| 434 | { | ||
| 435 | @Override | ||
| 436 | public void run() | ||
| 437 | { | ||
| 438 | StringBuilder textBuilder = new StringBuilder(m_outputArea.getText()); | ||
| 439 | |||
| 440 | textBuilder.append(text); | ||
| 441 | |||
| 442 | while (textBuilder.length() > CharacterLimit) | ||
| 443 | textBuilder.delete(0, textBuilder.indexOf(System.lineSeparator()) + 1); | ||
| 444 | |||
| 445 | m_outputArea.setText(textBuilder.toString()); | ||
| 446 | } | ||
| 447 | }); | ||
| 448 | } | ||
| 449 | |||
| 450 | private static final int DumpThreshold = 50; | ||
| 451 | private static final int CharacterLimit = 8192; | ||
| 452 | } | ||
| 453 | } | ||
| @@ -0,0 +1,90 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // SampleSubscriberConnectorListener.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/23/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.sample; | ||
| 25 | |||
| 26 | import java.io.PrintStream; | ||
| 27 | |||
| 28 | import org.gpa.gsf.timeseries.transport.SubscriptionInfo; | ||
| 29 | import org.gpa.gsf.timeseries.transport.event.MessageEvent; | ||
| 30 | import org.gpa.gsf.timeseries.transport.event.SubscriberConnectorAdapter; | ||
| 31 | import org.gpa.gsf.timeseries.transport.event.SubscriberEvent; | ||
| 32 | |||
| 33 | /** | ||
| 34 | * Sample listener for a subscriber connector. | ||
| 35 | * | ||
| 36 | * @see SubscriberConnector | ||
| 37 | */ | ||
| 38 | public class SampleSubscriberConnectorListener extends SubscriberConnectorAdapter | ||
| 39 | { | ||
| 40 | private SubscriptionInfo m_info; | ||
| 41 | private PrintStream m_errorStream; | ||
| 42 | |||
| 43 | /** | ||
| 44 | * Constructs a new instance using the standard {@code System.err} | ||
| 45 | * print stream for displaying errors. | ||
| 46 | * | ||
| 47 | * @param info subscription info used to automatically | ||
| 48 | * resubscribe to the publisher | ||
| 49 | */ | ||
| 50 | public SampleSubscriberConnectorListener(SubscriptionInfo info) | ||
| 51 | { | ||
| 52 | this(info, System.err); | ||
| 53 | } | ||
| 54 | |||
| 55 | /** | ||
| 56 | * Constructs a new instance. | ||
| 57 | * | ||
| 58 | * @param info subscription info used to automatically | ||
| 59 | * resubscribe to the publisher | ||
| 60 | * @param errorStream print stream used for displaying errors | ||
| 61 | */ | ||
| 62 | public SampleSubscriberConnectorListener(SubscriptionInfo info, PrintStream errorStream) | ||
| 63 | { | ||
| 64 | if (info == null) | ||
| 65 | throw new IllegalArgumentException("info must not be null"); | ||
| 66 | |||
| 67 | m_info = info; | ||
| 68 | m_errorStream = errorStream; | ||
| 69 | } | ||
| 70 | |||
| 71 | @Override | ||
| 72 | public void exceptionEncountered(MessageEvent evt) | ||
| 73 | { | ||
| 74 | if (m_errorStream != null) | ||
| 75 | evt.getException().printStackTrace(m_errorStream); | ||
| 76 | } | ||
| 77 | |||
| 78 | @Override | ||
| 79 | public void reconnected(SubscriberEvent evt) | ||
| 80 | { | ||
| 81 | try | ||
| 82 | { | ||
| 83 | evt.getSubscriber().subscribe(m_info); | ||
| 84 | } | ||
| 85 | catch (Exception ex) | ||
| 86 | { | ||
| 87 | ex.printStackTrace(m_errorStream); | ||
| 88 | } | ||
| 89 | } | ||
| 90 | } | ||
| @@ -0,0 +1,182 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // SampleSubscriberListener.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/19/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.sample; | ||
| 25 | |||
| 26 | import java.io.PrintStream; | ||
| 27 | import java.text.DateFormat; | ||
| 28 | import java.text.SimpleDateFormat; | ||
| 29 | import java.util.Collection; | ||
| 30 | import java.util.Iterator; | ||
| 31 | |||
| 32 | import org.gpa.gsf.timeseries.Measurement; | ||
| 33 | import org.gpa.gsf.timeseries.transport.DataSubscriber; | ||
| 34 | import org.gpa.gsf.timeseries.transport.event.MeasurementEvent; | ||
| 35 | import org.gpa.gsf.timeseries.transport.event.MessageEvent; | ||
| 36 | import org.gpa.gsf.timeseries.transport.event.SubscriberAdapter; | ||
| 37 | import org.gpa.gsf.timeseries.util.TimeExtensions; | ||
| 38 | |||
| 39 | /** | ||
| 40 | * Sample listener class for the {@link DataSubscriber}. | ||
| 41 | * | ||
| 42 | * @see SimpleSubscribe | ||
| 43 | */ | ||
| 44 | public class SampleSubscriberListener extends SubscriberAdapter | ||
| 45 | { | ||
| 46 | private PrintStream m_outputStream; | ||
| 47 | private PrintStream m_errorStream; | ||
| 48 | private int m_processCount; | ||
| 49 | |||
| 50 | /** | ||
| 51 | * Constructs a new sample subscriber listener using the standard | ||
| 52 | * {@link System.out} and {@link System.err} print streams. | ||
| 53 | */ | ||
| 54 | public SampleSubscriberListener() | ||
| 55 | { | ||
| 56 | this(System.out, System.err); | ||
| 57 | } | ||
| 58 | |||
| 59 | /** | ||
| 60 | * Constructs a new sample subscriber listener using | ||
| 61 | * the given output stream and no error stream. | ||
| 62 | * | ||
| 63 | * @param outputStream the output stream to which messages will be written | ||
| 64 | * @throws IllegalArgumentException if {@code outputStream} is {@code null} | ||
| 65 | */ | ||
| 66 | public SampleSubscriberListener(PrintStream outputStream) | ||
| 67 | { | ||
| 68 | this(outputStream, null); | ||
| 69 | } | ||
| 70 | |||
| 71 | /** | ||
| 72 | * Constructs a new sample subscriber litener using | ||
| 73 | * the given output stream and error stream. | ||
| 74 | * | ||
| 75 | * @param outputStream the output stream to which status messages will be written | ||
| 76 | * @param errorStream the error stream to which error messages will be written | ||
| 77 | * @throws IllegalArgumentException if {@code outputStream} is {@code null} | ||
| 78 | */ | ||
| 79 | public SampleSubscriberListener(PrintStream outputStream, PrintStream errorStream) | ||
| 80 | { | ||
| 81 | if (outputStream == null) | ||
| 82 | throw new IllegalArgumentException("outputStream cannot be null"); | ||
| 83 | |||
| 84 | m_outputStream = outputStream; | ||
| 85 | m_errorStream = errorStream; | ||
| 86 | } | ||
| 87 | |||
| 88 | /** | ||
| 89 | * Writes status messages from the {@link DataSubscriber} to the output stream. | ||
| 90 | */ | ||
| 91 | @Override | ||
| 92 | public void statusMessageReceived(MessageEvent evt) | ||
| 93 | { | ||
| 94 | m_outputStream.println(evt.getMessage()); | ||
| 95 | m_outputStream.println(); | ||
| 96 | } | ||
| 97 | |||
| 98 | /** | ||
| 99 | * Writes the stack trace of exceptions encountered | ||
| 100 | * by the {@link DataSubscriber} to the error stream. | ||
| 101 | */ | ||
| 102 | @Override | ||
| 103 | public void exceptionEncountered(MessageEvent evt) | ||
| 104 | { | ||
| 105 | if (m_errorStream != null) | ||
| 106 | { | ||
| 107 | evt.getException().printStackTrace(m_errorStream); | ||
| 108 | m_errorStream.println(); | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | /** | ||
| 113 | * Writes information about measurements received from the | ||
| 114 | * {@link DataSubscriber} to the output stream every so often. | ||
| 115 | */ | ||
| 116 | @Override | ||
| 117 | public void newMeasurementsReceived(MeasurementEvent evt) | ||
| 118 | { | ||
| 119 | Collection<Measurement> newMeasurements = evt.getMeasurements(); | ||
| 120 | |||
| 121 | DataSubscriber subscriber = null; | ||
| 122 | Measurement firstMeasurement = null; | ||
| 123 | Measurement nextMeasurement = null; | ||
| 124 | Iterator<Measurement> iter = null; | ||
| 125 | |||
| 126 | DateFormat dateFormat; | ||
| 127 | String dateString; | ||
| 128 | |||
| 129 | // Only display messages every five | ||
| 130 | // seconds (assuming 30 calls per second) | ||
| 131 | if (m_processCount % 150 == 0) | ||
| 132 | { | ||
| 133 | if (evt.getSource() instanceof DataSubscriber) | ||
| 134 | subscriber = (DataSubscriber)evt.getSource(); | ||
| 135 | |||
| 136 | if (newMeasurements.size() > 0) | ||
| 137 | { | ||
| 138 | firstMeasurement = newMeasurements.iterator().next(); | ||
| 139 | iter = newMeasurements.iterator(); | ||
| 140 | } | ||
| 141 | |||
| 142 | if (subscriber != null) | ||
| 143 | m_outputStream.println(subscriber.getTotalMeasurementsReceived() + " measurements received so far..."); | ||
| 144 | |||
| 145 | if (firstMeasurement != null) | ||
| 146 | { | ||
| 147 | dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); | ||
| 148 | dateString = dateFormat.format(TimeExtensions.fromTicks(firstMeasurement.getTimestamp()).getTime()); | ||
| 149 | m_outputStream.println("Timestamp: " + dateString); | ||
| 150 | } | ||
| 151 | |||
| 152 | if (iter != null) | ||
| 153 | { | ||
| 154 | m_outputStream.println("Point\tValue"); | ||
| 155 | |||
| 156 | while (iter.hasNext()) | ||
| 157 | { | ||
| 158 | nextMeasurement = iter.next(); | ||
| 159 | m_outputStream.println(nextMeasurement.getId() + "\t" + nextMeasurement.getValue()); | ||
| 160 | } | ||
| 161 | |||
| 162 | m_outputStream.println(); | ||
| 163 | } | ||
| 164 | } | ||
| 165 | |||
| 166 | m_processCount++; | ||
| 167 | } | ||
| 168 | |||
| 169 | /** | ||
| 170 | * Writes the message received when the {@link DataSubscriber}'s | ||
| 171 | * connection is terminated to the error stream. | ||
| 172 | */ | ||
| 173 | @Override | ||
| 174 | public void connectionTerminated(MessageEvent evt) | ||
| 175 | { | ||
| 176 | if (m_errorStream != null) | ||
| 177 | { | ||
| 178 | m_errorStream.println(evt.getMessage()); | ||
| 179 | m_errorStream.println(); | ||
| 180 | } | ||
| 181 | } | ||
| 182 | } | ||
| @@ -0,0 +1,111 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // SimpleSubscribe.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/19/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.sample; | ||
| 25 | |||
| 26 | import java.io.IOException; | ||
| 27 | import java.util.Scanner; | ||
| 28 | |||
| 29 | import org.gpa.gsf.timeseries.transport.DataSubscriber; | ||
| 30 | import org.gpa.gsf.timeseries.transport.SubscriptionInfo; | ||
| 31 | |||
| 32 | /** | ||
| 33 | * Provides an example of how to use the Subscriber API. | ||
| 34 | * | ||
| 35 | * @see DataSubscriber | ||
| 36 | */ | ||
| 37 | public class SimpleSubscribe | ||
| 38 | { | ||
| 39 | private static DataSubscriber s_subscriber; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * Main method. Entry point into the program. | ||
| 43 | * | ||
| 44 | * @param args command line arguments | ||
| 45 | */ | ||
| 46 | public static void main(String[] args) | ||
| 47 | { | ||
| 48 | String hostname; | ||
| 49 | int port; | ||
| 50 | |||
| 51 | // Ensure that the necessary | ||
| 52 | // command line arguments are given | ||
| 53 | if (args.length < 2) | ||
| 54 | { | ||
| 55 | System.err.println("Error: requires two command line arguments"); | ||
| 56 | System.err.println(" 1. hostname of publisher"); | ||
| 57 | System.err.println(" 2. port used to initiate connection"); | ||
| 58 | return; | ||
| 59 | } | ||
| 60 | |||
| 61 | // Get hostname and port | ||
| 62 | hostname = args[0]; | ||
| 63 | port = Integer.parseInt(args[1]); | ||
| 64 | |||
| 65 | // Run the subscriber | ||
| 66 | runSubscriber(hostname, port); | ||
| 67 | |||
| 68 | // Wait until user presses enter before quitting | ||
| 69 | waitForUserInput(); | ||
| 70 | |||
| 71 | // Disconnect the subscriber to stop background threads | ||
| 72 | if (s_subscriber != null) | ||
| 73 | s_subscriber.disconnect(); | ||
| 74 | } | ||
| 75 | |||
| 76 | // The proper procedure when creating and running a subscriber is: | ||
| 77 | // - Create subscriber | ||
| 78 | // - Add listeners | ||
| 79 | // - Connect to publisher | ||
| 80 | // - Subscribe | ||
| 81 | private static void runSubscriber(String hostname, int port) | ||
| 82 | { | ||
| 83 | try | ||
| 84 | { | ||
| 85 | s_subscriber = new DataSubscriber(); | ||
| 86 | s_subscriber.addSubscriberListener(new SampleSubscriberListener()); | ||
| 87 | s_subscriber.connect(hostname, port); | ||
| 88 | s_subscriber.subscribe(createSubscriptionInfo()); | ||
| 89 | } | ||
| 90 | catch (IOException ex) | ||
| 91 | { | ||
| 92 | ex.printStackTrace(); | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | // SubscriptionInfo is a helper object which allows the user | ||
| 97 | // to set up their subscription and reuse subscription settings | ||
| 98 | private static SubscriptionInfo createSubscriptionInfo() | ||
| 99 | { | ||
| 100 | SubscriptionInfo info = new SubscriptionInfo(); | ||
| 101 | info.setFilterExpression("PPA:1;PPA:2;PPA:3;PPA:4;PPA:5;PPA:6;PPA:7;PPA:8;PPA:9;PPA:10;PPA:11;PPA:12;PPA:13;PPA:14"); | ||
| 102 | return info; | ||
| 103 | } | ||
| 104 | |||
| 105 | // Waits for the user to press Enter before proceeding | ||
| 106 | private static void waitForUserInput() | ||
| 107 | { | ||
| 108 | Scanner scan = new Scanner(System.in); | ||
| 109 | scan.nextLine(); | ||
| 110 | } | ||
| 111 | } | ||
| @@ -0,0 +1,288 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // CompactMeasurementParser.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/12/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport; | ||
| 25 | |||
| 26 | import java.nio.ByteBuffer; | ||
| 27 | import java.util.ArrayList; | ||
| 28 | import java.util.Collection; | ||
| 29 | |||
| 30 | import org.gpa.gsf.timeseries.Measurement; | ||
| 31 | import org.gpa.gsf.timeseries.MeasurementKey; | ||
| 32 | import org.gpa.gsf.timeseries.util.Masks; | ||
| 33 | |||
| 34 | /** | ||
| 35 | * Implementation of {@link GatewayMeasurementParser} that parses | ||
| 36 | * measurements serialized using the compact measurement format. | ||
| 37 | */ | ||
| 38 | public class CompactMeasurementParser implements GatewayMeasurementParser | ||
| 39 | { | ||
| 40 | private SignalIndexCache m_signalIndexCache; | ||
| 41 | private long[] m_baseTimeOffsets; | ||
| 42 | private boolean m_includeTime; | ||
| 43 | private boolean m_useMillisecondResolution; | ||
| 44 | |||
| 45 | /** | ||
| 46 | * Constructs a new compact measurement parser with the given signal index cache. | ||
| 47 | * | ||
| 48 | * @param signalIndexCache the cache used to compact measurement IDs during serialization | ||
| 49 | * @throws IllegalArgumentException if {@code signalIndexCache} is {@code null} | ||
| 50 | */ | ||
| 51 | public CompactMeasurementParser(SignalIndexCache signalIndexCache) | ||
| 52 | { | ||
| 53 | this(signalIndexCache, null, true, false); | ||
| 54 | } | ||
| 55 | |||
| 56 | /** | ||
| 57 | * Constructs a new compact measurement parser with the | ||
| 58 | * given signal index cache and base time offsets. | ||
| 59 | * | ||
| 60 | * @param signalIndexCache the cache used to compact measurement IDs during serialization | ||
| 61 | * @param baseTimeOffsets the offsets used to compact measurement timestamps during serialization | ||
| 62 | * @param includeTime indicates whether timestamps were included when serializing the measurements | ||
| 63 | * @param useMillisecondResolution determines whether measurement timestamps were further compacted | ||
| 64 | * during serialization by specifying them to be in millisecond resolution | ||
| 65 | * @throws IllegalArgumentException if {@code signalIndexCache} is {@code null} | ||
| 66 | */ | ||
| 67 | public CompactMeasurementParser(SignalIndexCache signalIndexCache, long[] baseTimeOffsets, boolean includeTime, boolean useMillisecondResolution) | ||
| 68 | { | ||
| 69 | if(signalIndexCache == null) | ||
| 70 | throw new IllegalArgumentException("signalIndexCache cannot be null"); | ||
| 71 | |||
| 72 | m_signalIndexCache = signalIndexCache; | ||
| 73 | m_baseTimeOffsets = baseTimeOffsets; | ||
| 74 | m_includeTime = includeTime; | ||
| 75 | m_useMillisecondResolution = useMillisecondResolution; | ||
| 76 | } | ||
| 77 | |||
| 78 | /** | ||
| 79 | * Parses a collection of serialized measurements. | ||
| 80 | */ | ||
| 81 | @Override | ||
| 82 | public Collection<Measurement> parseMeasurements(byte[] serializedMeasurements, int offset, int length) | ||
| 83 | { | ||
| 84 | return parseMeasurements(ByteBuffer.wrap(serializedMeasurements, offset, length)); | ||
| 85 | } | ||
| 86 | |||
| 87 | /** | ||
| 88 | * Parses a collection of serialized measurements. | ||
| 89 | */ | ||
| 90 | @Override | ||
| 91 | public Collection<Measurement> parseMeasurements(ByteBuffer serializedMeasurementBuffer) | ||
| 92 | { | ||
| 93 | Collection<Measurement> measurements = new ArrayList<Measurement>(); | ||
| 94 | Measurement parsedMeasurement; | ||
| 95 | |||
| 96 | // Parsed from serialized measurement | ||
| 97 | byte compactFlags; | ||
| 98 | short signalIndex; | ||
| 99 | float measurementValue; | ||
| 100 | long timestamp = 0L; | ||
| 101 | |||
| 102 | // Used for base time offsets | ||
| 103 | boolean usingBaseTimeOffset; | ||
| 104 | int timeIndex; | ||
| 105 | |||
| 106 | // Obtained from signal index cache | ||
| 107 | MeasurementKey key; | ||
| 108 | |||
| 109 | while (serializedMeasurementBuffer.hasRemaining()) | ||
| 110 | { | ||
| 111 | // Get and validate compact measurement flags | ||
| 112 | compactFlags = serializedMeasurementBuffer.get(); | ||
| 113 | usingBaseTimeOffset = (compactFlags & CompactBaseTimeOffsetFlag) != 0; | ||
| 114 | timeIndex = ((compactFlags & CompactTimeIndexFlag) != 0) ? 1 : 0; | ||
| 115 | |||
| 116 | if (usingBaseTimeOffset && (m_baseTimeOffsets == null || m_baseTimeOffsets[timeIndex] == 0)) | ||
| 117 | break; | ||
| 118 | |||
| 119 | if (serializedMeasurementBuffer.remaining() + 1 < getMeasurementByteLength(usingBaseTimeOffset)) | ||
| 120 | break; | ||
| 121 | |||
| 122 | // Get and validate signal index | ||
| 123 | signalIndex = serializedMeasurementBuffer.getShort(); | ||
| 124 | |||
| 125 | if (!m_signalIndexCache.contains(signalIndex)) | ||
| 126 | break; | ||
| 127 | |||
| 128 | // Get measurement value and timestamp | ||
| 129 | measurementValue = serializedMeasurementBuffer.getFloat(); | ||
| 130 | |||
| 131 | if (m_includeTime) | ||
| 132 | { | ||
| 133 | if (!usingBaseTimeOffset) | ||
| 134 | { | ||
| 135 | timestamp = serializedMeasurementBuffer.getLong(); | ||
| 136 | } | ||
| 137 | else if (!m_useMillisecondResolution) | ||
| 138 | { | ||
| 139 | timestamp = serializedMeasurementBuffer.getInt() & Masks.getLongMask(Integer.SIZE); | ||
| 140 | timestamp += m_baseTimeOffsets[timeIndex]; | ||
| 141 | } | ||
| 142 | else | ||
| 143 | { | ||
| 144 | timestamp = serializedMeasurementBuffer.getShort() & Masks.getLongMask(Short.SIZE); | ||
| 145 | timestamp *= 10000; | ||
| 146 | timestamp += m_baseTimeOffsets[timeIndex]; | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 150 | // Construct the parsed measurement and add it to the collection | ||
| 151 | key = m_signalIndexCache.getMeasurementKey(signalIndex); | ||
| 152 | parsedMeasurement = new Measurement(); | ||
| 153 | |||
| 154 | parsedMeasurement.setFlags(mapToFullFlags(compactFlags)); | ||
| 155 | parsedMeasurement.setSignalId(key.getSignalId()); | ||
| 156 | parsedMeasurement.setSource(key.getSource()); | ||
| 157 | parsedMeasurement.setId(key.getId()); | ||
| 158 | parsedMeasurement.setValue(measurementValue); | ||
| 159 | parsedMeasurement.setTimestamp(timestamp); | ||
| 160 | |||
| 161 | measurements.add(parsedMeasurement); | ||
| 162 | } | ||
| 163 | |||
| 164 | return measurements; | ||
| 165 | } | ||
| 166 | |||
| 167 | /** | ||
| 168 | * Gets the byte length of measurements parsed by this parser. | ||
| 169 | * | ||
| 170 | * @param usingBaseTimeOffset If false, measurement timestamps are 8 bytes; otherwise, they're smaller. | ||
| 171 | * This value is determined at serialization time for each individual measurement, so the value | ||
| 172 | * returned by this method may not be representative of all parsed measurements. | ||
| 173 | * @return the byte length of measurements parsed by this parser | ||
| 174 | */ | ||
| 175 | public int getMeasurementByteLength(boolean usingBaseTimeOffset) | ||
| 176 | { | ||
| 177 | int byteLength = 7; | ||
| 178 | |||
| 179 | if (m_includeTime) | ||
| 180 | { | ||
| 181 | if (!usingBaseTimeOffset) | ||
| 182 | byteLength += 8; | ||
| 183 | else if(!m_useMillisecondResolution) | ||
| 184 | byteLength += 4; | ||
| 185 | else | ||
| 186 | byteLength += 2; | ||
| 187 | } | ||
| 188 | |||
| 189 | return byteLength; | ||
| 190 | } | ||
| 191 | |||
| 192 | // Maps the 8-bit compact flag format to the 32-bit full flag format. | ||
| 193 | private int mapToFullFlags(byte compactFlags) | ||
| 194 | { | ||
| 195 | int fullFlags = 0; | ||
| 196 | |||
| 197 | if ((compactFlags & CompactDataRangeFlag) != 0) | ||
| 198 | fullFlags |= DataRangeMask; | ||
| 199 | |||
| 200 | if ((compactFlags & CompactDataQualityFlag) != 0) | ||
| 201 | fullFlags |= DataQualityMask; | ||
| 202 | |||
| 203 | if ((compactFlags & CompactTimeQualityFlag) != 0) | ||
| 204 | fullFlags |= TimeQualityMask; | ||
| 205 | |||
| 206 | if ((compactFlags & CompactSystemIssueFlag) != 0) | ||
| 207 | fullFlags |= SystemIssueMask; | ||
| 208 | |||
| 209 | if ((compactFlags & CompactCalculatedValueFlag) != 0) | ||
| 210 | fullFlags |= CalculatedValueMask; | ||
| 211 | |||
| 212 | if ((compactFlags & CompactDiscardedValueFlag) != 0) | ||
| 213 | fullFlags |= DiscardedValueMask; | ||
| 214 | |||
| 215 | return fullFlags; | ||
| 216 | } | ||
| 217 | |||
| 218 | /** | ||
| 219 | * A data range flag was set. | ||
| 220 | */ | ||
| 221 | public static final byte CompactDataRangeFlag = 0x01; | ||
| 222 | |||
| 223 | /** | ||
| 224 | * A data quality flag was set. | ||
| 225 | */ | ||
| 226 | public static final byte CompactDataQualityFlag = 0x02; | ||
| 227 | |||
| 228 | /** | ||
| 229 | * A time quality flag was set. | ||
| 230 | */ | ||
| 231 | public static final byte CompactTimeQualityFlag = 0x04; | ||
| 232 | |||
| 233 | /** | ||
| 234 | * A system flag was set. | ||
| 235 | */ | ||
| 236 | public static final byte CompactSystemIssueFlag = 0x08; | ||
| 237 | |||
| 238 | /** | ||
| 239 | * Calculated value bit was set. | ||
| 240 | */ | ||
| 241 | public static final byte CompactCalculatedValueFlag = 0x10; | ||
| 242 | |||
| 243 | /** | ||
| 244 | * Discarded value bit was set. | ||
| 245 | */ | ||
| 246 | public static final byte CompactDiscardedValueFlag = 0x20; | ||
| 247 | |||
| 248 | /** | ||
| 249 | * Compact measurement timestamp was serialized using base time offset when set. | ||
| 250 | */ | ||
| 251 | public static final byte CompactBaseTimeOffsetFlag = 0x40; | ||
| 252 | |||
| 253 | /** | ||
| 254 | * Use odd time index (i.e., 1) when bit is set; even time index (i.e., 0) when bit is clear. | ||
| 255 | */ | ||
| 256 | public static final byte CompactTimeIndexFlag = (byte)0x80; | ||
| 257 | |||
| 258 | /** | ||
| 259 | * Mask over the data range flags. | ||
| 260 | */ | ||
| 261 | public static final int DataRangeMask = 0x000000FC; | ||
| 262 | |||
| 263 | /** | ||
| 264 | * Mask over the data quality flags. | ||
| 265 | */ | ||
| 266 | public static final int DataQualityMask = 0x0000EF03; | ||
| 267 | |||
| 268 | /** | ||
| 269 | * Mask over the time quality flags. | ||
| 270 | */ | ||
| 271 | public static final int TimeQualityMask = 0x00BF0000; | ||
| 272 | |||
| 273 | /** | ||
| 274 | * Mask over the system issue flags. | ||
| 275 | */ | ||
| 276 | public static final int SystemIssueMask = 0xE0000000; | ||
| 277 | |||
| 278 | /** | ||
| 279 | * Mask over the calculated value bit. | ||
| 280 | */ | ||
| 281 | public static final int CalculatedValueMask = 0x00001000; | ||
| 282 | |||
| 283 | /** | ||
| 284 | * Mask over the dicarded value bit. | ||
| 285 | */ | ||
| 286 | public static final int DiscardedValueMask = 0x00400000; | ||
| 287 | |||
| 288 | } | ||
| @@ -0,0 +1,1212 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // DataSubscriber.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/16/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport; | ||
| 25 | |||
| 26 | import java.io.ByteArrayInputStream; | ||
| 27 | import java.io.IOException; | ||
| 28 | import java.io.InputStream; | ||
| 29 | import java.io.OutputStream; | ||
| 30 | import java.net.DatagramPacket; | ||
| 31 | import java.net.DatagramSocket; | ||
| 32 | import java.net.InetAddress; | ||
| 33 | import java.net.Socket; | ||
| 34 | import java.net.SocketException; | ||
| 35 | import java.net.UnknownHostException; | ||
| 36 | import java.nio.ByteBuffer; | ||
| 37 | import java.nio.ByteOrder; | ||
| 38 | import java.nio.charset.Charset; | ||
| 39 | import java.util.ArrayList; | ||
| 40 | import java.util.Collection; | ||
| 41 | import java.util.UUID; | ||
| 42 | import java.util.concurrent.BlockingQueue; | ||
| 43 | import java.util.concurrent.LinkedBlockingQueue; | ||
| 44 | import java.util.concurrent.TimeUnit; | ||
| 45 | import java.util.zip.GZIPInputStream; | ||
| 46 | |||
| 47 | import org.gpa.gsf.timeseries.Measurement; | ||
| 48 | import org.gpa.gsf.timeseries.transport.constant.CompressionMode; | ||
| 49 | import org.gpa.gsf.timeseries.transport.constant.DataPacketFlags; | ||
| 50 | import org.gpa.gsf.timeseries.transport.constant.OperationalEncoding; | ||
| 51 | import org.gpa.gsf.timeseries.transport.constant.OperationalModes; | ||
| 52 | import org.gpa.gsf.timeseries.transport.constant.ServerCommand; | ||
| 53 | import org.gpa.gsf.timeseries.transport.constant.ServerResponse; | ||
| 54 | import org.gpa.gsf.timeseries.transport.event.MeasurementEvent; | ||
| 55 | import org.gpa.gsf.timeseries.transport.event.MessageEvent; | ||
| 56 | import org.gpa.gsf.timeseries.transport.event.MetadataEvent; | ||
| 57 | import org.gpa.gsf.timeseries.transport.event.StartTimeEvent; | ||
| 58 | import org.gpa.gsf.timeseries.transport.event.SubscriberListener; | ||
| 59 | import org.gpa.gsf.timeseries.util.ArrayExtensions; | ||
| 60 | import org.gpa.gsf.timeseries.util.InputStreamExtensions; | ||
| 61 | import org.gpa.gsf.timeseries.util.Masks; | ||
| 62 | import org.gpa.gsf.timeseries.util.StringExtensions; | ||
| 63 | |||
| 64 | /** | ||
| 65 | * Implementation of the Subscriber API that will connect | ||
| 66 | * to a data publisher for a data subscription. | ||
| 67 | */ | ||
| 68 | public class DataSubscriber | ||
| 69 | { | ||
| 70 | private SubscriptionInfo m_currentSubscription; | ||
| 71 | private InetAddress[] m_allHostAddresses; | ||
| 72 | private InetAddress m_hostAddress; | ||
| 73 | private int m_operationalModes; | ||
| 74 | private Charset m_characterEncoding; | ||
| 75 | private boolean m_unsubscribing; | ||
| 76 | private boolean m_disconnecting; | ||
| 77 | |||
| 78 | // Statistics counters | ||
| 79 | private long m_totalCommandChannelBytesReceived; | ||
| 80 | private long m_totalDataChannelBytesReceived; | ||
| 81 | private long m_totalMeasurementsReceived; | ||
| 82 | private boolean m_connected; | ||
| 83 | private boolean m_subscribed; | ||
| 84 | |||
| 85 | // Measurement parsing | ||
| 86 | private SignalIndexCache m_signalIndexCache; | ||
| 87 | private long[] m_baseTimeOffsets; | ||
| 88 | |||
| 89 | // Command thread members | ||
| 90 | private Thread m_commandThread; | ||
| 91 | private BlockingQueue<byte[]> m_commandQueue; | ||
| 92 | |||
| 93 | // Callback thread members | ||
| 94 | private Thread m_callbackThread; | ||
| 95 | private BlockingQueue<Runnable> m_callbackQueue; | ||
| 96 | |||
| 97 | // Command channel | ||
| 98 | private Thread m_commandChannelResponseThread; | ||
| 99 | private Socket m_commandChannelSocket; | ||
| 100 | |||
| 101 | // Data channel | ||
| 102 | private Thread m_dataChannelResponseThread; | ||
| 103 | private DatagramSocket m_dataChannelSocket; | ||
| 104 | |||
| 105 | // Callbacks | ||
| 106 | private Collection<SubscriberListener> m_subscriberListeners; | ||
| 107 | |||
| 108 | /** | ||
| 109 | * Constructs a new data subscriber. | ||
| 110 | */ | ||
| 111 | public DataSubscriber() | ||
| 112 | { | ||
| 113 | m_commandQueue = new LinkedBlockingQueue<byte[]>(); | ||
| 114 | m_callbackQueue = new LinkedBlockingQueue<Runnable>(); | ||
| 115 | m_subscriberListeners = new ArrayList<SubscriberListener>(); | ||
| 116 | |||
| 117 | setOperationalModes(OperationalModes.UseCommonSerializationFormat | OperationalEncoding.Unicode | OperationalModes.CompressMetadata); | ||
| 118 | } | ||
| 119 | |||
| 120 | /** | ||
| 121 | * Adds the given listener to receive events from this subscriber. | ||
| 122 | * If the {@code listener} is {@code null}, no exception is thrown | ||
| 123 | * and no action is performed. | ||
| 124 | * | ||
| 125 | * @param subscriberListener the listener to be added | ||
| 126 | */ | ||
| 127 | public void addSubscriberListener(SubscriberListener subscriberListener) | ||
| 128 | { | ||
| 129 | if (subscriberListener != null) | ||
| 130 | m_subscriberListeners.add(subscriberListener); | ||
| 131 | } | ||
| 132 | |||
| 133 | /** | ||
| 134 | * Removes the given listener so that it no longer receives events | ||
| 135 | * from this subscriber. This method performs no function, nor does | ||
| 136 | * it throw an exception, if {@code subscriberListener} was not | ||
| 137 | * previously added to this component. If {@code subscriberListener} | ||
| 138 | * is {@code null}, no exception is thrown and no action is performed. | ||
| 139 | * | ||
| 140 | * @param subscriberListener the listener to be removed | ||
| 141 | */ | ||
| 142 | public void removeSubscriberListener(SubscriberListener subscriberListener) | ||
| 143 | { | ||
| 144 | if (subscriberListener != null) | ||
| 145 | m_subscriberListeners.remove(subscriberListener); | ||
| 146 | } | ||
| 147 | |||
| 148 | /** | ||
| 149 | * Gets the operational modes currently in use by this subscriber. | ||
| 150 | * | ||
| 151 | * @return the subscriber's operational modes | ||
| 152 | */ | ||
| 153 | public int getOperationalModes() | ||
| 154 | { | ||
| 155 | return m_operationalModes; | ||
| 156 | } | ||
| 157 | |||
| 158 | /** | ||
| 159 | * Sets the operational modes of the subscriber. | ||
| 160 | * <p> | ||
| 161 | * The operational modes define a set of flags that can be used to | ||
| 162 | * indicate to the publisher how the subscriber wishes to communicate | ||
| 163 | * with it. This method will throw an {@code UnsupportedOperationException} | ||
| 164 | * if any of the following are true. | ||
| 165 | * <p> | ||
| 166 | * <ul> | ||
| 167 | * <li>{@link OperationalModes.UseCommonSerializationFormat} is unset</li> | ||
| 168 | * <li>{@link OperationalModes.CompressSignalIndexCache} is set</li> | ||
| 169 | * </ul> | ||
| 170 | * | ||
| 171 | * @param operationalModes the new operational modes | ||
| 172 | * @throws UnsupportedOperationException if an unsupported operational mode is detected | ||
| 173 | * @see OperationalModes | ||
| 174 | */ | ||
| 175 | public void setOperationalModes(int operationalModes) | ||
| 176 | { | ||
| 177 | int operationalEncoding; | ||
| 178 | |||
| 179 | // .NET serialization format not supported | ||
| 180 | if ((operationalModes & OperationalModes.UseCommonSerializationFormat) == 0) | ||
| 181 | throw new UnsupportedOperationException("Cannot use .NET serialization format. Use common serialization format instead."); | ||
| 182 | |||
| 183 | // Update operational modes and character encoding | ||
| 184 | m_operationalModes = operationalModes; | ||
| 185 | operationalEncoding = operationalModes & OperationalModes.EncodingMask; | ||
| 186 | |||
| 187 | switch (operationalEncoding) | ||
| 188 | { | ||
| 189 | case OperationalEncoding.Unicode: | ||
| 190 | m_characterEncoding = Charset.forName("UTF-16LE"); | ||
| 191 | break; | ||
| 192 | |||
| 193 | case OperationalEncoding.BigEndianUnicode: | ||
| 194 | m_characterEncoding = Charset.forName("UTF-16BE"); | ||
| 195 | break; | ||
| 196 | |||
| 197 | case OperationalEncoding.UTF8: | ||
| 198 | m_characterEncoding = Charset.forName("UTF-8"); | ||
| 199 | break; | ||
| 200 | |||
| 201 | case OperationalEncoding.OperatingSystemDefault: | ||
| 202 | m_characterEncoding = Charset.defaultCharset(); | ||
| 203 | break; | ||
| 204 | } | ||
| 205 | |||
| 206 | // If subscriber is connected, send automatically | ||
| 207 | if (m_connected) | ||
| 208 | sendOperationalModes(); | ||
| 209 | } | ||
| 210 | |||
| 211 | /** | ||
| 212 | * Connects to the publisher listening at the given hostname and port. | ||
| 213 | * | ||
| 214 | * @param hostname name or address of the machine hosting the publisher | ||
| 215 | * @param port the port that the publisher is listening on | ||
| 216 | * @throws IllegalStateException if the subscriber is already connected | ||
| 217 | * @throws IOException if an I/O error occurs when creating the socket | ||
| 218 | * @see #disconnect() | ||
| 219 | */ | ||
| 220 | public void connect(String hostname, int port) throws IOException | ||
| 221 | { | ||
| 222 | m_totalCommandChannelBytesReceived = 0L; | ||
| 223 | m_totalDataChannelBytesReceived = 0L; | ||
| 224 | m_totalMeasurementsReceived = 0L; | ||
| 225 | |||
| 226 | if (m_connected) | ||
| 227 | throw new IllegalStateException("Subscriber is already connected; disconnect first"); | ||
| 228 | |||
| 229 | m_commandChannelSocket = new Socket(hostname, port); | ||
| 230 | m_hostAddress = m_commandChannelSocket.getInetAddress(); | ||
| 231 | |||
| 232 | if (m_hostAddress.isAnyLocalAddress()) | ||
| 233 | m_hostAddress = InetAddress.getLocalHost(); | ||
| 234 | |||
| 235 | try | ||
| 236 | { | ||
| 237 | m_allHostAddresses = InetAddress.getAllByName(m_hostAddress.getHostName()); | ||
| 238 | } | ||
| 239 | catch (UnknownHostException ex) | ||
| 240 | { | ||
| 241 | m_allHostAddresses = new InetAddress[0]; | ||
| 242 | } | ||
| 243 | |||
| 244 | startCommandThread(); | ||
| 245 | startCallbackThread(); | ||
| 246 | startCommandChannelResponseThread(); | ||
| 247 | |||
| 248 | sendOperationalModes(); | ||
| 249 | m_connected = true; | ||
| 250 | } | ||
| 251 | |||
| 252 | /** | ||
| 253 | * Disconnects from the data publisher. This method does not return | ||
| 254 | * until all connections have been closed and all threads spawned by | ||
| 255 | * the subscriber have shut down gracefully (with the exception of | ||
| 256 | * the thread that executes the connection terminated callback). | ||
| 257 | * | ||
| 258 | * @see #connect(String, int) | ||
| 259 | */ | ||
| 260 | public void disconnect() | ||
| 261 | { | ||
| 262 | // Notify running threads that | ||
| 263 | // the subscriber is disconnecting | ||
| 264 | m_unsubscribing = true; | ||
| 265 | m_disconnecting = true; | ||
| 266 | |||
| 267 | try | ||
| 268 | { | ||
| 269 | // Close sockets so that threads using | ||
| 270 | // them can shut down gracefully | ||
| 271 | if (m_commandChannelSocket != null) | ||
| 272 | m_commandChannelSocket.close(); | ||
| 273 | } | ||
| 274 | catch (IOException ex) | ||
| 275 | { | ||
| 276 | // Ignore exceptions and | ||
| 277 | // continue shutdown procedure | ||
| 278 | } | ||
| 279 | |||
| 280 | if (m_dataChannelSocket != null) | ||
| 281 | m_dataChannelSocket.close(); | ||
| 282 | |||
| 283 | // Join with all threads to guarantee their completion | ||
| 284 | // before returning control to the caller | ||
| 285 | joinThread(m_commandThread); | ||
| 286 | joinThread(m_callbackThread); | ||
| 287 | joinThread(m_commandChannelResponseThread); | ||
| 288 | joinThread(m_dataChannelResponseThread); | ||
| 289 | |||
| 290 | // Empty queues so they can be used again later | ||
| 291 | m_commandQueue.clear(); | ||
| 292 | m_callbackQueue.clear(); | ||
| 293 | |||
| 294 | // Release references to threads and | ||
| 295 | // sockets that we are no longer using | ||
| 296 | m_commandThread = null; | ||
| 297 | m_callbackThread = null; | ||
| 298 | m_commandChannelResponseThread = null; | ||
| 299 | m_dataChannelResponseThread = null; | ||
| 300 | m_commandChannelSocket = null; | ||
| 301 | m_dataChannelSocket = null; | ||
| 302 | |||
| 303 | // Disconnect completed | ||
| 304 | m_unsubscribing = false; | ||
| 305 | m_subscribed = false; | ||
| 306 | m_disconnecting = false; | ||
| 307 | m_connected = false; | ||
| 308 | } | ||
| 309 | |||
| 310 | /** | ||
| 311 | * Subscribes to the signals specified by the | ||
| 312 | * filter expression in the {@code info} object. | ||
| 313 | * | ||
| 314 | * @param info subscription info used to configure the subscription | ||
| 315 | * @throws SocketException if, when defining a UDP data channel, the | ||
| 316 | * socket could not be opened, or the socket could not bind | ||
| 317 | * to the specified local port | ||
| 318 | * @see #unsubscribe() | ||
| 319 | */ | ||
| 320 | public void subscribe(SubscriptionInfo info) throws SocketException | ||
| 321 | { | ||
| 322 | StringBuilder connectionStringBuilder = new StringBuilder(); | ||
| 323 | byte[] connectionStringBytes; | ||
| 324 | ByteBuffer packetData; | ||
| 325 | int packetDataSize; | ||
| 326 | |||
| 327 | // Make sure to unsubscribe before attempting another | ||
| 328 | // subscription so we don't leave connections open | ||
| 329 | if (m_subscribed) | ||
| 330 | unsubscribe(); | ||
| 331 | |||
| 332 | m_currentSubscription = new SubscriptionInfo(info); | ||
| 333 | m_totalMeasurementsReceived = 0L; | ||
| 334 | |||
| 335 | connectionStringBuilder.append("trackLatestMeasurements").append(info.isThrottled()).append(';'); | ||
| 336 | connectionStringBuilder.append("includeTime=").append(info.isTimeIncluded()).append(';'); | ||
| 337 | connectionStringBuilder.append("lagTime=").append(info.getLagTime()).append(';'); | ||
| 338 | connectionStringBuilder.append("leadTime=").append(info.getLeadTime()).append(';'); | ||
| 339 | connectionStringBuilder.append("useLocalClockAsRealTime=").append(info.isLocalClockAsRealTime()).append(';'); | ||
| 340 | connectionStringBuilder.append("processingInterval=").append(info.getProcessingInterval()).append(';'); | ||
| 341 | connectionStringBuilder.append("useMillisecondResolution=").append(info.isMillisecondResolution()).append(';'); | ||
| 342 | connectionStringBuilder.append("assemblyInfo={source=TSF Java Library;version=0.9.0;buildDate=April 2012};"); | ||
| 343 | |||
| 344 | if (!StringExtensions.isNullOrWhitespace(info.getFilterExpression())) | ||
| 345 | connectionStringBuilder.append("inputMeasurementKeys={").append(info.getFilterExpression()).append("};"); | ||
| 346 | |||
| 347 | if (info.isUdpDataChannel()) | ||
| 348 | { | ||
| 349 | m_dataChannelSocket = new DatagramSocket(info.getDataChannelLocalPort(), m_commandChannelSocket.getLocalAddress()); | ||
| 350 | startDataChannelResponseThread(); | ||
| 351 | connectionStringBuilder.append("dataChannel={localport=").append(info.getDataChannelLocalPort()).append("};"); | ||
| 352 | } | ||
| 353 | |||
| 354 | if (!StringExtensions.isNullOrWhitespace(info.getStartTime())) | ||
| 355 | connectionStringBuilder.append("startTimeConstraint=").append(info.getStartTime()).append(';'); | ||
| 356 | |||
| 357 | if (!StringExtensions.isNullOrWhitespace(info.getStopTime())) | ||
| 358 | connectionStringBuilder.append("stopTimeConstraint=").append(info.getStopTime()).append(';'); | ||
| 359 | |||
| 360 | if (!StringExtensions.isNullOrWhitespace(info.getConstraintParameters())) | ||
| 361 | connectionStringBuilder.append("timeConstraintParameters=").append(info.getConstraintParameters()).append(';'); | ||
| 362 | |||
| 363 | if (!StringExtensions.isNullOrWhitespace(info.getWaitHandleNames())) | ||
| 364 | { | ||
| 365 | connectionStringBuilder.append("waitHandleNames=").append(info.getWaitHandleNames()).append(';'); | ||
| 366 | connectionStringBuilder.append("waitHandleTimeout=").append(info.getWaitHandleTimeout()).append(';'); | ||
| 367 | } | ||
| 368 | |||
| 369 | if (!StringExtensions.isNullOrWhitespace(info.getExtraConnectionStringParameters())) | ||
| 370 | connectionStringBuilder.append(info.getExtraConnectionStringParameters()).append(';'); | ||
| 371 | |||
| 372 | connectionStringBytes = connectionStringBuilder.toString().getBytes(m_characterEncoding); | ||
| 373 | packetDataSize = 5 + connectionStringBytes.length; | ||
| 374 | packetData = ByteBuffer.allocate(packetDataSize); | ||
| 375 | |||
| 376 | packetData.put((byte)(DataPacketFlags.Compact | (info.isRemotelySynchronized() ? DataPacketFlags.Synchronized : DataPacketFlags.NoFlags))); | ||
| 377 | packetData.putInt(connectionStringBytes.length); | ||
| 378 | packetData.put(connectionStringBytes); | ||
| 379 | |||
| 380 | sendServerCommand(ServerCommand.Subscribe, packetData.array(), 0, packetDataSize); | ||
| 381 | } | ||
| 382 | |||
| 383 | /** | ||
| 384 | * Gets a copy of the subscription info currently in use by the subscriber. | ||
| 385 | * | ||
| 386 | * @return copy of the subscription info currently in use by the subscriber | ||
| 387 | */ | ||
| 388 | public SubscriptionInfo getCurrentSubscription() | ||
| 389 | { | ||
| 390 | return new SubscriptionInfo(m_currentSubscription); | ||
| 391 | } | ||
| 392 | |||
| 393 | /** | ||
| 394 | * Unsubscribes to stop receiving data from the publisher. | ||
| 395 | */ | ||
| 396 | public void unsubscribe() | ||
| 397 | { | ||
| 398 | // Notify data channel response | ||
| 399 | // thread that we are unsubscribing | ||
| 400 | m_unsubscribing = true; | ||
| 401 | |||
| 402 | // Close socket so that data channel | ||
| 403 | // response thread can finish | ||
| 404 | if (m_dataChannelSocket != null) | ||
| 405 | m_dataChannelSocket.close(); | ||
| 406 | |||
| 407 | // Join with data channel response thread to ensure | ||
| 408 | // that it finishes before returning from this method | ||
| 409 | joinThread(m_dataChannelResponseThread); | ||
| 410 | |||
| 411 | // Unsubscribe complete | ||
| 412 | m_unsubscribing = false; | ||
| 413 | |||
| 414 | // Notify server to stop sending data | ||
| 415 | sendServerCommand(ServerCommand.Unsubscribe); | ||
| 416 | } | ||
| 417 | |||
| 418 | /** | ||
| 419 | * Sends a command to the publisher. | ||
| 420 | * | ||
| 421 | * @param commandCode the {@link ServerCommand} code to be sent | ||
| 422 | */ | ||
| 423 | public void sendServerCommand(byte commandCode) | ||
| 424 | { | ||
| 425 | sendServerCommand(commandCode, null, 0, 0); | ||
| 426 | } | ||
| 427 | |||
| 428 | /** | ||
| 429 | * Sends a command to the publisher over the command channel. | ||
| 430 | * | ||
| 431 | * @param commandCode the {@link ServerCommand} code to be sent | ||
| 432 | * @param data packet data to be sent to the server with the command | ||
| 433 | * @param offset offset in the buffer at which data sent to the server starts | ||
| 434 | * @param length amount of data in buffer that gets sent to the server | ||
| 435 | */ | ||
| 436 | public void sendServerCommand(byte commandCode, byte[] data, int offset, int length) | ||
| 437 | { | ||
| 438 | final int PayloadHeaderSize = 8; | ||
| 439 | |||
| 440 | int packetSize = 1 + length; | ||
| 441 | int payloadSize = PayloadHeaderSize + packetSize; | ||
| 442 | byte[] command = new byte[payloadSize]; | ||
| 443 | |||
| 444 | // Insert payload marker | ||
| 445 | command[0] = (byte)0xAA; | ||
| 446 | command[1] = (byte)0xBB; | ||
| 447 | command[2] = (byte)0xCC; | ||
| 448 | command[3] = (byte)0xDD; | ||
| 449 | |||
| 450 | // Insert packet size | ||
| 451 | command[4] = (byte)packetSize; | ||
| 452 | command[5] = (byte)(packetSize >> 8); | ||
| 453 | command[6] = (byte)(packetSize >> 16); | ||
| 454 | command[7] = (byte)(packetSize >> 24); | ||
| 455 | |||
| 456 | // Insert command code | ||
| 457 | command[8] = commandCode; | ||
| 458 | |||
| 459 | if (data != null) | ||
| 460 | ArrayExtensions.blockCopy(data, offset, command, PayloadHeaderSize + 1, length); | ||
| 461 | |||
| 462 | m_commandQueue.add(command); | ||
| 463 | } | ||
| 464 | |||
| 465 | /** | ||
| 466 | * Sends operational modes to the server. | ||
| 467 | * | ||
| 468 | * @see #setOperationalModes(int) | ||
| 469 | * @see #getOperationalModes() | ||
| 470 | */ | ||
| 471 | public void sendOperationalModes() | ||
| 472 | { | ||
| 473 | byte[] commandData = ByteBuffer.allocate(4).putInt(m_operationalModes).array(); | ||
| 474 | sendServerCommand(ServerCommand.DefineOperationalModes, commandData, 0, 4); | ||
| 475 | } | ||
| 476 | |||
| 477 | /** | ||
| 478 | * Gets the total number of bytes received on | ||
| 479 | * the command channel since last connection. | ||
| 480 | * | ||
| 481 | * @return the total number of bytes received on the command channel | ||
| 482 | */ | ||
| 483 | public long getTotalCommandChannelBytesReceived() | ||
| 484 | { | ||
| 485 | return m_totalCommandChannelBytesReceived; | ||
| 486 | } | ||
| 487 | |||
| 488 | /** | ||
| 489 | * Gets the total number of bytes received on | ||
| 490 | * the data channel since last connection. | ||
| 491 | * | ||
| 492 | * @return the total number of bytes received on the data channel | ||
| 493 | */ | ||
| 494 | public long getTotalDataChannelBytesReceived() | ||
| 495 | { | ||
| 496 | return m_totalDataChannelBytesReceived; | ||
| 497 | } | ||
| 498 | |||
| 499 | /** | ||
| 500 | * Gets the total number of measurements | ||
| 501 | * received since last subscription. | ||
| 502 | * | ||
| 503 | * @return the total number of measurements received | ||
| 504 | */ | ||
| 505 | public long getTotalMeasurementsReceived() | ||
| 506 | { | ||
| 507 | return m_totalMeasurementsReceived; | ||
| 508 | } | ||
| 509 | |||
| 510 | /** | ||
| 511 | * Indicates whether the subscriber is | ||
| 512 | * currently connected to the publisher. | ||
| 513 | * | ||
| 514 | * @return flag indicating whether subscriber is connected | ||
| 515 | */ | ||
| 516 | public boolean isConnected() | ||
| 517 | { | ||
| 518 | return m_connected; | ||
| 519 | } | ||
| 520 | |||
| 521 | /** | ||
| 522 | * Indicates whether the subscriber is | ||
| 523 | * currently subscribed to the publisher. | ||
| 524 | * | ||
| 525 | * @return flag indicating whether subscriber is subscribed | ||
| 526 | */ | ||
| 527 | public boolean isSubscribed() | ||
| 528 | { | ||
| 529 | return m_subscribed; | ||
| 530 | } | ||
| 531 | |||
| 532 | /** | ||
| 533 | * Disconnects in case sockets are | ||
| 534 | * open or threads are still running. | ||
| 535 | */ | ||
| 536 | @Override | ||
| 537 | protected void finalize() throws Throwable | ||
| 538 | { | ||
| 539 | if (m_connected) | ||
| 540 | disconnect(); | ||
| 541 | } | ||
| 542 | |||
| 543 | // Joins with the given thread, checking for null | ||
| 544 | // and ignoring possible InterruptedExceptions. | ||
| 545 | private void joinThread(Thread th) | ||
| 546 | { | ||
| 547 | try | ||
| 548 | { | ||
| 549 | if (th != null) | ||
| 550 | th.join(); | ||
| 551 | } | ||
| 552 | catch(InterruptedException ex) | ||
| 553 | { | ||
| 554 | // Ignore exception and | ||
| 555 | // continue shutdown procedure | ||
| 556 | } | ||
| 557 | } | ||
| 558 | |||
| 559 | // Creates and starts the command thread. | ||
| 560 | private void startCommandThread() | ||
| 561 | { | ||
| 562 | m_commandThread = new Thread(new Runnable() | ||
| 563 | { | ||
| 564 | @Override | ||
| 565 | public void run() | ||
| 566 | { | ||
| 567 | runCommandThread(); | ||
| 568 | } | ||
| 569 | }); | ||
| 570 | |||
| 571 | m_commandThread.start(); | ||
| 572 | } | ||
| 573 | |||
| 574 | // Creates and starts the callback thread. | ||
| 575 | private void startCallbackThread() | ||
| 576 | { | ||
| 577 | m_callbackThread = new Thread(new Runnable() | ||
| 578 | { | ||
| 579 | @Override | ||
| 580 | public void run() | ||
| 581 | { | ||
| 582 | runCallbackThread(); | ||
| 583 | } | ||
| 584 | }); | ||
| 585 | |||
| 586 | m_callbackThread.start(); | ||
| 587 | } | ||
| 588 | |||
| 589 | // Creates and starts the command channel response thread. | ||
| 590 | private void startCommandChannelResponseThread() | ||
| 591 | { | ||
| 592 | m_commandChannelResponseThread = new Thread(new Runnable() | ||
| 593 | { | ||
| 594 | @Override | ||
| 595 | public void run() | ||
| 596 | { | ||
| 597 | runCommandChannelResponseThread(); | ||
| 598 | } | ||
| 599 | }); | ||
| 600 | |||
| 601 | m_commandChannelResponseThread.start(); | ||
| 602 | } | ||
| 603 | |||
| 604 | // Creates and starts the data channel response thread. | ||
| 605 | private void startDataChannelResponseThread() | ||
| 606 | { | ||
| 607 | m_dataChannelResponseThread = new Thread(new Runnable() | ||
| 608 | { | ||
| 609 | @Override | ||
| 610 | public void run() | ||
| 611 | { | ||
| 612 | runDataChannelResponseThread(); | ||
| 613 | } | ||
| 614 | }); | ||
| 615 | |||
| 616 | m_dataChannelResponseThread.start(); | ||
| 617 | } | ||
| 618 | |||
| 619 | // Sends commands queued by other threads to the publisher. | ||
| 620 | private void runCommandThread() | ||
| 621 | { | ||
| 622 | try | ||
| 623 | { | ||
| 624 | OutputStream out = m_commandChannelSocket.getOutputStream(); | ||
| 625 | byte[] command; | ||
| 626 | |||
| 627 | while (!m_disconnecting) | ||
| 628 | { | ||
| 629 | command = m_commandQueue.poll(PollTimeout, PollTimeoutUnit); | ||
| 630 | |||
| 631 | if (command != null) | ||
| 632 | out.write(command); | ||
| 633 | } | ||
| 634 | } | ||
| 635 | catch (InterruptedException ex) | ||
| 636 | { | ||
| 637 | // This thread is internal and | ||
| 638 | // should never be interrupted | ||
| 639 | throw new IllegalStateException(ex); | ||
| 640 | } | ||
| 641 | catch (IOException ex) | ||
| 642 | { | ||
| 643 | if (!m_disconnecting) | ||
| 644 | dispatchConnectionTerminated(ex); | ||
| 645 | } | ||
| 646 | } | ||
| 647 | |||
| 648 | // Executes callbacks queued by other threads. | ||
| 649 | private void runCallbackThread() | ||
| 650 | { | ||
| 651 | try | ||
| 652 | { | ||
| 653 | Runnable callback; | ||
| 654 | |||
| 655 | while (!m_disconnecting) | ||
| 656 | { | ||
| 657 | callback = m_callbackQueue.poll(PollTimeout, PollTimeoutUnit); | ||
| 658 | |||
| 659 | if (callback != null) | ||
| 660 | { | ||
| 661 | try | ||
| 662 | { | ||
| 663 | callback.run(); | ||
| 664 | } | ||
| 665 | catch (Exception ex) | ||
| 666 | { | ||
| 667 | dispatchException(ex); | ||
| 668 | } | ||
| 669 | } | ||
| 670 | } | ||
| 671 | } | ||
| 672 | catch (InterruptedException ex) | ||
| 673 | { | ||
| 674 | // This thread is internal and | ||
| 675 | // should never be interrupted | ||
| 676 | throw new IllegalStateException(ex); | ||
| 677 | } | ||
| 678 | } | ||
| 679 | |||
| 680 | // Processes data received from the publisher on the command channel. | ||
| 681 | private void runCommandChannelResponseThread() | ||
| 682 | { | ||
| 683 | try | ||
| 684 | { | ||
| 685 | final int PayloadHeaderSize = 8; | ||
| 686 | |||
| 687 | InputStream in = m_commandChannelSocket.getInputStream(); | ||
| 688 | |||
| 689 | ByteBuffer littleEndianBuffer = ByteBuffer.allocate(PayloadHeaderSize); | ||
| 690 | ByteBuffer bigEndianBuffer = ByteBuffer.allocate(MaxPacketSize); | ||
| 691 | int bytesRead; | ||
| 692 | |||
| 693 | int payloadBodySize; | ||
| 694 | |||
| 695 | littleEndianBuffer.order(ByteOrder.LITTLE_ENDIAN); | ||
| 696 | bigEndianBuffer.order(ByteOrder.BIG_ENDIAN); | ||
| 697 | |||
| 698 | while (true) | ||
| 699 | { | ||
| 700 | // Read the payload header from the input stream | ||
| 701 | bytesRead = InputStreamExtensions.read(in, littleEndianBuffer.array(), 0, PayloadHeaderSize); | ||
| 702 | m_totalCommandChannelBytesReceived += bytesRead; | ||
| 703 | |||
| 704 | if (m_disconnecting || bytesRead < PayloadHeaderSize) | ||
| 705 | break; | ||
| 706 | |||
| 707 | // Skip the 4-byte sync pattern | ||
| 708 | payloadBodySize = littleEndianBuffer.getInt(4); | ||
| 709 | |||
| 710 | // Increase the buffer size, if necessary | ||
| 711 | if (payloadBodySize > bigEndianBuffer.capacity()) | ||
| 712 | bigEndianBuffer = ByteBuffer.allocate(payloadBodySize); | ||
| 713 | |||
| 714 | // Read the packet from the input stream | ||
| 715 | bytesRead = InputStreamExtensions.read(in, bigEndianBuffer.array(), 0, payloadBodySize); | ||
| 716 | m_totalCommandChannelBytesReceived += bytesRead; | ||
| 717 | |||
| 718 | if (m_disconnecting || bytesRead < payloadBodySize) | ||
| 719 | break; | ||
| 720 | |||
| 721 | // Set the limit on the buffer, process the | ||
| 722 | // buffer, and then rewind the buffer | ||
| 723 | bigEndianBuffer.limit(payloadBodySize); | ||
| 724 | processServerResponse(bigEndianBuffer); | ||
| 725 | bigEndianBuffer.rewind(); | ||
| 726 | } | ||
| 727 | } | ||
| 728 | catch (IOException ex) | ||
| 729 | { | ||
| 730 | if (!m_disconnecting) | ||
| 731 | dispatchConnectionTerminated(ex); | ||
| 732 | } | ||
| 733 | } | ||
| 734 | |||
| 735 | // Processes data received by the publisher on the data channel. | ||
| 736 | private void runDataChannelResponseThread() | ||
| 737 | { | ||
| 738 | DatagramPacket packet = new DatagramPacket(new byte[MaxPacketSize], MaxPacketSize); | ||
| 739 | |||
| 740 | try | ||
| 741 | { | ||
| 742 | while (true) | ||
| 743 | { | ||
| 744 | m_dataChannelSocket.receive(packet); | ||
| 745 | |||
| 746 | if (m_unsubscribing) | ||
| 747 | break; | ||
| 748 | |||
| 749 | if (isValidHostAddress(packet.getAddress())) | ||
| 750 | { | ||
| 751 | m_totalDataChannelBytesReceived += packet.getLength(); | ||
| 752 | processServerResponse(ByteBuffer.wrap(packet.getData(), packet.getOffset(), packet.getLength())); | ||
| 753 | } | ||
| 754 | } | ||
| 755 | } | ||
| 756 | catch (IOException ex) | ||
| 757 | { | ||
| 758 | if (!m_unsubscribing) | ||
| 759 | dispatchException(ex); | ||
| 760 | } | ||
| 761 | } | ||
| 762 | |||
| 763 | // Delegates data received from the publisher to the proper handler. | ||
| 764 | private void processServerResponse(ByteBuffer buffer) | ||
| 765 | { | ||
| 766 | byte responseCode = buffer.get(); | ||
| 767 | byte commandCode = buffer.get(); | ||
| 768 | |||
| 769 | // Skip length field in packet header, | ||
| 770 | // as length has already been determined | ||
| 771 | // by checking the payload header | ||
| 772 | buffer.getInt(); | ||
| 773 | |||
| 774 | switch (responseCode) | ||
| 775 | { | ||
| 776 | case ServerResponse.Succeeded: | ||
| 777 | handleSucceeded(commandCode, buffer); | ||
| 778 | break; | ||
| 779 | |||
| 780 | case ServerResponse.Failed: | ||
| 781 | handleFailed(commandCode, buffer); | ||
| 782 | break; | ||
| 783 | |||
| 784 | case ServerResponse.DataPacket: | ||
| 785 | handleDataPacket(buffer); | ||
| 786 | break; | ||
| 787 | |||
| 788 | case ServerResponse.DataStartTime: | ||
| 789 | handleDataStartTime(buffer); | ||
| 790 | break; | ||
| 791 | |||
| 792 | case ServerResponse.ProcessingComplete: | ||
| 793 | handleProcessingComplete(buffer); | ||
| 794 | break; | ||
| 795 | |||
| 796 | case ServerResponse.UpdateSignalIndexCache: | ||
| 797 | handleUpdateSignalIndexCache(buffer); | ||
| 798 | break; | ||
| 799 | |||
| 800 | case ServerResponse.UpdateBaseTimes: | ||
| 801 | handleUpdateBaseTimes(buffer); | ||
| 802 | break; | ||
| 803 | } | ||
| 804 | } | ||
| 805 | |||
| 806 | // Handle success messages from the publisher. | ||
| 807 | private void handleSucceeded(byte commandCode, ByteBuffer buffer) | ||
| 808 | { | ||
| 809 | StringBuilder messageBuilder = new StringBuilder(); | ||
| 810 | String hexCommandCode = Integer.toHexString(commandCode & Masks.getIntMask(Byte.SIZE)); | ||
| 811 | |||
| 812 | switch (commandCode) | ||
| 813 | { | ||
| 814 | case ServerCommand.MetadataRefresh: | ||
| 815 | // Metadata refresh message is not sent with a | ||
| 816 | // message, but rather the metadata itself | ||
| 817 | handleMetadataRefresh(buffer); | ||
| 818 | break; | ||
| 819 | |||
| 820 | case ServerCommand.Subscribe: | ||
| 821 | case ServerCommand.Unsubscribe: | ||
| 822 | // Do not break on these messages because there is | ||
| 823 | // still an associated message to be processed | ||
| 824 | m_subscribed = (commandCode == ServerCommand.Subscribe); | ||
| 825 | |||
| 826 | case ServerCommand.Authenticate: | ||
| 827 | case ServerCommand.RotateCipherKeys: | ||
| 828 | // Each of these responses comes with a message that will | ||
| 829 | // be delivered to the user via the status message callback | ||
| 830 | messageBuilder.append("Received success code in response to server command 0x").append(hexCommandCode).append(": "); | ||
| 831 | messageBuilder.append(m_characterEncoding.decode(buffer)); | ||
| 832 | |||
| 833 | dispatchStatusMessage(messageBuilder.toString()); | ||
| 834 | break; | ||
| 835 | |||
| 836 | default: | ||
| 837 | // If we don't know what the message is, we can't interpret | ||
| 838 | // the data sent with the packet. Deliver an error message | ||
| 839 | // to the user via the exception encountered callback | ||
| 840 | messageBuilder.append("Received success code in response to unknown server command 0x").append(hexCommandCode); | ||
| 841 | dispatchException(new UnsupportedOperationException(messageBuilder.toString())); | ||
| 842 | break; | ||
| 843 | } | ||
| 844 | } | ||
| 845 | |||
| 846 | // Handle failure messages from the publisher. | ||
| 847 | private void handleFailed(byte commandCode, ByteBuffer buffer) | ||
| 848 | { | ||
| 849 | StringBuilder messageBuilder = new StringBuilder(); | ||
| 850 | String hexCommandCode = Integer.toHexString(commandCode & Masks.getIntMask(Byte.SIZE)); | ||
| 851 | |||
| 852 | messageBuilder.append("Received failure code from server command 0x").append(hexCommandCode).append(": "); | ||
| 853 | messageBuilder.append(m_characterEncoding.decode(buffer)); | ||
| 854 | dispatchException(new RuntimeException(messageBuilder.toString())); | ||
| 855 | } | ||
| 856 | |||
| 857 | // Handle metadata received from the publisher. | ||
| 858 | private void handleMetadataRefresh(ByteBuffer buffer) | ||
| 859 | { | ||
| 860 | ByteBuffer buf = buffer; | ||
| 861 | |||
| 862 | if ((m_operationalModes & OperationalModes.CompressMetadata) != 0) | ||
| 863 | { | ||
| 864 | if ((m_operationalModes & OperationalModes.CompressionModeMask) == CompressionMode.GZIP) | ||
| 865 | { | ||
| 866 | buf = decompress(buffer); | ||
| 867 | } | ||
| 868 | } | ||
| 869 | |||
| 870 | dispatchMetadata(m_characterEncoding.decode(buf).toString()); | ||
| 871 | } | ||
| 872 | |||
| 873 | // Handle data packets received from the publisher. | ||
| 874 | private void handleDataPacket(ByteBuffer buffer) | ||
| 875 | { | ||
| 876 | GatewayMeasurementParser parser; | ||
| 877 | Collection<Measurement> newMeasurements; | ||
| 878 | |||
| 879 | byte dataPacketFlags; | ||
| 880 | boolean compactFlag; | ||
| 881 | boolean syncFlag; | ||
| 882 | long frameLevelTimestamp = 0L; | ||
| 883 | |||
| 884 | SubscriptionInfo info; | ||
| 885 | boolean includeTime; | ||
| 886 | boolean useMillisecondResolution; | ||
| 887 | |||
| 888 | // Get relevante information about the current subscription | ||
| 889 | info = m_currentSubscription; | ||
| 890 | includeTime = info.isTimeIncluded(); | ||
| 891 | useMillisecondResolution = info.isMillisecondResolution(); | ||
| 892 | |||
| 893 | // Parse the data packet flags | ||
| 894 | dataPacketFlags = buffer.get(); | ||
| 895 | compactFlag = (dataPacketFlags & DataPacketFlags.Compact) != 0; | ||
| 896 | syncFlag = (dataPacketFlags & DataPacketFlags.Synchronized) != 0; | ||
| 897 | |||
| 898 | // Gather statistics | ||
| 899 | m_totalMeasurementsReceived += buffer.getInt(); | ||
| 900 | |||
| 901 | if (syncFlag) | ||
| 902 | { | ||
| 903 | frameLevelTimestamp = buffer.getLong(); | ||
| 904 | includeTime = false; | ||
| 905 | } | ||
| 906 | |||
| 907 | if (compactFlag) | ||
| 908 | { | ||
| 909 | // If signal index cache is null, we | ||
| 910 | // cannot parse compact measurements | ||
| 911 | if (m_signalIndexCache == null) | ||
| 912 | return; | ||
| 913 | |||
| 914 | parser = new CompactMeasurementParser(m_signalIndexCache, m_baseTimeOffsets, includeTime, useMillisecondResolution); | ||
| 915 | } | ||
| 916 | else | ||
| 917 | { | ||
| 918 | // Not supported; dispatch exception and give up | ||
| 919 | dispatchException(new UnsupportedOperationException("Non-compact measurement format not supported")); | ||
| 920 | return; | ||
| 921 | } | ||
| 922 | |||
| 923 | try | ||
| 924 | { | ||
| 925 | // Parse measurements and expose them via listener | ||
| 926 | newMeasurements = parser.parseMeasurements(buffer); | ||
| 927 | |||
| 928 | if (syncFlag) | ||
| 929 | { | ||
| 930 | // Apply frame-level timestamp | ||
| 931 | for (Measurement newMeasurement : newMeasurements) | ||
| 932 | newMeasurement.setTimestamp(frameLevelTimestamp); | ||
| 933 | } | ||
| 934 | |||
| 935 | if (newMeasurements.size() > 0) | ||
| 936 | dispatchNewMeasurements(newMeasurements); | ||
| 937 | } | ||
| 938 | catch (Exception ex) | ||
| 939 | { | ||
| 940 | // Notify of exceptions during parse | ||
| 941 | dispatchException(ex); | ||
| 942 | } | ||
| 943 | } | ||
| 944 | |||
| 945 | // Handles data start time message received from publisher. | ||
| 946 | private void handleDataStartTime(ByteBuffer buffer) | ||
| 947 | { | ||
| 948 | dispatchDataStartTime(buffer.getLong()); | ||
| 949 | } | ||
| 950 | |||
| 951 | // Handles processing complete message received from publisher. | ||
| 952 | private void handleProcessingComplete(ByteBuffer buffer) | ||
| 953 | { | ||
| 954 | dispatchProcessingComplete(m_characterEncoding.decode(buffer).toString()); | ||
| 955 | } | ||
| 956 | |||
| 957 | // Updates the signal index cache with new values received from the publisher. | ||
| 958 | private void handleUpdateSignalIndexCache(ByteBuffer buffer) | ||
| 959 | { | ||
| 960 | ByteBuffer buf = buffer; | ||
| 961 | SignalIndexCache newCache = new SignalIndexCache(); | ||
| 962 | int referenceCount; | ||
| 963 | |||
| 964 | short signalIndex; | ||
| 965 | UUID signalId; | ||
| 966 | int sourceSize; | ||
| 967 | String source; | ||
| 968 | int id; | ||
| 969 | |||
| 970 | if ((m_operationalModes & OperationalModes.CompressSignalIndexCache) != 0) | ||
| 971 | { | ||
| 972 | if ((m_operationalModes & OperationalModes.CompressionModeMask) == CompressionMode.GZIP) | ||
| 973 | { | ||
| 974 | buf = decompress(buffer); | ||
| 975 | } | ||
| 976 | } | ||
| 977 | |||
| 978 | // Skip 4-byte length and 16-byte subscriber ID | ||
| 979 | // We may need to parse these in the future... | ||
| 980 | buf.position(buf.position() + 20); | ||
| 981 | |||
| 982 | referenceCount = buf.getInt(); | ||
| 983 | |||
| 984 | for (int i = 0; i < referenceCount; i++) | ||
| 985 | { | ||
| 986 | signalIndex = buf.getShort(); | ||
| 987 | signalId = new UUID(buf.getLong(), buf.getLong()); | ||
| 988 | sourceSize = buf.getInt(); | ||
| 989 | source = m_characterEncoding.decode((ByteBuffer)buf.slice().limit(sourceSize)).toString(); | ||
| 990 | id = ((ByteBuffer)buf.position(buf.position() + sourceSize)).getInt(); | ||
| 991 | |||
| 992 | newCache.addMeasurementKey(signalIndex, signalId, source, id); | ||
| 993 | } | ||
| 994 | |||
| 995 | m_signalIndexCache = newCache; | ||
| 996 | } | ||
| 997 | |||
| 998 | // Updates the base times with new values received from the publisher. | ||
| 999 | private void handleUpdateBaseTimes(ByteBuffer buffer) | ||
| 1000 | { | ||
| 1001 | // Skip time index | ||
| 1002 | buffer.getInt(); | ||
| 1003 | |||
| 1004 | m_baseTimeOffsets = new long[] { buffer.getLong(), buffer.getLong() }; | ||
| 1005 | } | ||
| 1006 | |||
| 1007 | // Queues a status message callback. | ||
| 1008 | private void dispatchStatusMessage(final String message) | ||
| 1009 | { | ||
| 1010 | m_callbackQueue.add(new Runnable() | ||
| 1011 | { | ||
| 1012 | @Override | ||
| 1013 | public void run() | ||
| 1014 | { | ||
| 1015 | for (SubscriberListener listener : m_subscriberListeners) | ||
| 1016 | listener.statusMessageReceived(new MessageEvent(DataSubscriber.this, message)); | ||
| 1017 | } | ||
| 1018 | }); | ||
| 1019 | } | ||
| 1020 | |||
| 1021 | // Queues an exception encountered callback. | ||
| 1022 | private void dispatchException(final Exception exception) | ||
| 1023 | { | ||
| 1024 | m_callbackQueue.add(new Runnable() | ||
| 1025 | { | ||
| 1026 | @Override | ||
| 1027 | public void run() | ||
| 1028 | { | ||
| 1029 | for (SubscriberListener listener : m_subscriberListeners) | ||
| 1030 | listener.exceptionEncountered(new MessageEvent(DataSubscriber.this, exception)); | ||
| 1031 | } | ||
| 1032 | }); | ||
| 1033 | } | ||
| 1034 | |||
| 1035 | // Queues a data start time received callback. | ||
| 1036 | private void dispatchDataStartTime(final long dataStartTime) | ||
| 1037 | { | ||
| 1038 | m_callbackQueue.add(new Runnable() | ||
| 1039 | { | ||
| 1040 | @Override | ||
| 1041 | public void run() | ||
| 1042 | { | ||
| 1043 | for (SubscriberListener listener : m_subscriberListeners) | ||
| 1044 | listener.dataStartTimeReceived(new StartTimeEvent(DataSubscriber.this, dataStartTime)); | ||
| 1045 | } | ||
| 1046 | }); | ||
| 1047 | } | ||
| 1048 | |||
| 1049 | // Queues a metadata received callback. | ||
| 1050 | private void dispatchMetadata(final byte[] compressedMetadata) | ||
| 1051 | { | ||
| 1052 | m_callbackQueue.add(new Runnable() | ||
| 1053 | { | ||
| 1054 | @Override | ||
| 1055 | public void run() | ||
| 1056 | { | ||
| 1057 | for (SubscriberListener listener : m_subscriberListeners) | ||
| 1058 | listener.metadataReceived(new MetadataEvent(DataSubscriber.this, compressedMetadata)); | ||
| 1059 | } | ||
| 1060 | }); | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | // Queues a metadata received callback. | ||
| 1064 | private void dispatchMetadata(final String xmlMetadata) | ||
| 1065 | { | ||
| 1066 | m_callbackQueue.add(new Runnable() | ||
| 1067 | { | ||
| 1068 | @Override | ||
| 1069 | public void run() | ||
| 1070 | { | ||
| 1071 | for (SubscriberListener listener : m_subscriberListeners) | ||
| 1072 | listener.metadataReceived(new MetadataEvent(DataSubscriber.this, xmlMetadata)); | ||
| 1073 | } | ||
| 1074 | }); | ||
| 1075 | } | ||
| 1076 | |||
| 1077 | // Queues a new measurements callback. | ||
| 1078 | private void dispatchNewMeasurements(final Collection<Measurement> newMeasurements) | ||
| 1079 | { | ||
| 1080 | m_callbackQueue.add(new Runnable() | ||
| 1081 | { | ||
| 1082 | @Override | ||
| 1083 | public void run() | ||
| 1084 | { | ||
| 1085 | for (SubscriberListener listener : m_subscriberListeners) | ||
| 1086 | listener.newMeasurementsReceived(new MeasurementEvent(DataSubscriber.this, newMeasurements)); | ||
| 1087 | } | ||
| 1088 | }); | ||
| 1089 | } | ||
| 1090 | |||
| 1091 | // Queues a processing complete callback. | ||
| 1092 | private void dispatchProcessingComplete(final String message) | ||
| 1093 | { | ||
| 1094 | m_callbackQueue.add(new Runnable() | ||
| 1095 | { | ||
| 1096 | @Override | ||
| 1097 | public void run() | ||
| 1098 | { | ||
| 1099 | for (SubscriberListener listener : m_subscriberListeners) | ||
| 1100 | listener.processingCompleteCallback(new MessageEvent(DataSubscriber.this, message)); | ||
| 1101 | } | ||
| 1102 | }); | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | // Executes a connection terminated callback on a separate thread. | ||
| 1106 | private void dispatchConnectionTerminated(final Exception ex) | ||
| 1107 | { | ||
| 1108 | Thread connectionTerminatedThread = new Thread() | ||
| 1109 | { | ||
| 1110 | @Override | ||
| 1111 | public void run() | ||
| 1112 | { | ||
| 1113 | disconnect(); | ||
| 1114 | |||
| 1115 | for (SubscriberListener listener : m_subscriberListeners) | ||
| 1116 | listener.connectionTerminated(new MessageEvent(DataSubscriber.this, ex)); | ||
| 1117 | } | ||
| 1118 | }; | ||
| 1119 | |||
| 1120 | connectionTerminatedThread.start(); | ||
| 1121 | } | ||
| 1122 | |||
| 1123 | // Decompresses the data in the given buffer. | ||
| 1124 | private ByteBuffer decompress(ByteBuffer buffer) | ||
| 1125 | { | ||
| 1126 | ByteArrayInputStream inputStream = null; | ||
| 1127 | GZIPInputStream inflater = null; | ||
| 1128 | ArrayList<Byte> byteList; | ||
| 1129 | byte[] swap; | ||
| 1130 | int bytesRead; | ||
| 1131 | |||
| 1132 | try | ||
| 1133 | { | ||
| 1134 | inputStream = new ByteArrayInputStream(buffer.array(), buffer.position() + buffer.arrayOffset(), buffer.remaining()); | ||
| 1135 | inflater = new GZIPInputStream(inputStream); | ||
| 1136 | byteList = new ArrayList<Byte>((int)(buffer.remaining() * 1.5)); | ||
| 1137 | swap = new byte[1024]; | ||
| 1138 | |||
| 1139 | do | ||
| 1140 | { | ||
| 1141 | // Decompress data and place it into swap array. | ||
| 1142 | bytesRead = inflater.read(swap, 0, swap.length); | ||
| 1143 | |||
| 1144 | // Swap the decompressed data into the byte list. | ||
| 1145 | for (int i = 0; i < bytesRead; i++) | ||
| 1146 | byteList.add(swap[i]); | ||
| 1147 | } while (bytesRead > 0); | ||
| 1148 | |||
| 1149 | // Increase swap size to contain the fully decompressed data. | ||
| 1150 | swap = new byte[byteList.size()]; | ||
| 1151 | |||
| 1152 | // Copy the data into the swap array. | ||
| 1153 | for (int i = 0; i < swap.length; i++) | ||
| 1154 | swap[i] = byteList.get(i); | ||
| 1155 | |||
| 1156 | return ByteBuffer.wrap(swap); | ||
| 1157 | } | ||
| 1158 | catch (IOException ex) | ||
| 1159 | { | ||
| 1160 | |||
| 1161 | dispatchException(ex); | ||
| 1162 | } | ||
| 1163 | finally | ||
| 1164 | { | ||
| 1165 | try | ||
| 1166 | { | ||
| 1167 | // Attempt to close the input | ||
| 1168 | // streams to release resources. | ||
| 1169 | if (inflater != null) | ||
| 1170 | inflater.close(); | ||
| 1171 | |||
| 1172 | if (inputStream != null) | ||
| 1173 | inputStream.close(); | ||
| 1174 | } catch (IOException ex) | ||
| 1175 | { | ||
| 1176 | dispatchException(ex); | ||
| 1177 | } | ||
| 1178 | } | ||
| 1179 | |||
| 1180 | return buffer; | ||
| 1181 | } | ||
| 1182 | |||
| 1183 | // Determines whether the given IP address is | ||
| 1184 | // valid for the currently connected host. | ||
| 1185 | private boolean isValidHostAddress(InetAddress address) | ||
| 1186 | { | ||
| 1187 | // If it equals the cached host address, simply return | ||
| 1188 | if (m_hostAddress.equals(address)) | ||
| 1189 | return true; | ||
| 1190 | |||
| 1191 | // Check all valid host addresses | ||
| 1192 | for (InetAddress hostAddress : m_allHostAddresses) | ||
| 1193 | { | ||
| 1194 | if (hostAddress.equals(address)) | ||
| 1195 | { | ||
| 1196 | // Cache this address so we hopefully | ||
| 1197 | // don't have to loop every time | ||
| 1198 | m_hostAddress = hostAddress; | ||
| 1199 | return true; | ||
| 1200 | } | ||
| 1201 | } | ||
| 1202 | |||
| 1203 | // Address is not valid | ||
| 1204 | return false; | ||
| 1205 | } | ||
| 1206 | |||
| 1207 | // Maximum possible packet size to be received on the data channel. | ||
| 1208 | private static final int MaxPacketSize = 32767; | ||
| 1209 | |||
| 1210 | private static final long PollTimeout = 1L; | ||
| 1211 | private static final TimeUnit PollTimeoutUnit = TimeUnit.SECONDS; | ||
| 1212 | } | ||
| @@ -0,0 +1,56 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // GatewayMeasurementParser.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/12/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport; | ||
| 25 | |||
| 26 | import java.nio.ByteBuffer; | ||
| 27 | import java.util.Collection; | ||
| 28 | |||
| 29 | import org.gpa.gsf.timeseries.Measurement; | ||
| 30 | |||
| 31 | /** | ||
| 32 | * Represents the interface used by the {@link DataSubscriber} to parse | ||
| 33 | * measurements from the publisher. | ||
| 34 | */ | ||
| 35 | public interface GatewayMeasurementParser | ||
| 36 | { | ||
| 37 | /** | ||
| 38 | * Parses a collection of serialized measurements from a byte array. | ||
| 39 | * | ||
| 40 | * @param serializedMeasurements the serialized measurements to be parsed | ||
| 41 | * @param offset the offset into the array at which the collection starts | ||
| 42 | * @param length the byte length of the collection of serialized measurements | ||
| 43 | * @return the collection of parsed measurements | ||
| 44 | */ | ||
| 45 | Collection<Measurement> parseMeasurements(byte[] serializedMeasurements, int offset, int length); | ||
| 46 | |||
| 47 | /** | ||
| 48 | * Parses a collection of serialized measurements from a byte buffer. | ||
| 49 | * | ||
| 50 | * @param serializedMeasurementBuffer The serialized measurements to be parsed. | ||
| 51 | * This method uses relative get operations on the buffer until there is | ||
| 52 | * no longer enough data left to parse any more measurements. | ||
| 53 | * @return the collection of parsed measurements | ||
| 54 | */ | ||
| 55 | Collection<Measurement> parseMeasurements(ByteBuffer serializedMeasurementBuffer); | ||
| 56 | } | ||
| @@ -0,0 +1,128 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // SignalIndexCache.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/12/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport; | ||
| 25 | |||
| 26 | import java.util.HashMap; | ||
| 27 | import java.util.Map; | ||
| 28 | import java.util.UUID; | ||
| 29 | |||
| 30 | import org.gpa.gsf.timeseries.MeasurementKey; | ||
| 31 | |||
| 32 | /** | ||
| 33 | * Represents a cache used to map 16-bit indexes to {@link MeasurementKey}s | ||
| 34 | * in order to compact measurement IDs for the compact measurement format. | ||
| 35 | */ | ||
| 36 | public class SignalIndexCache | ||
| 37 | { | ||
| 38 | private Map<Short, MeasurementKey> m_reference; | ||
| 39 | private Map<UUID, Short> m_signalIdCache; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * Constructs a new signal index cache. | ||
| 43 | */ | ||
| 44 | public SignalIndexCache() | ||
| 45 | { | ||
| 46 | m_reference = new HashMap<Short, MeasurementKey>(); | ||
| 47 | m_signalIdCache = new HashMap<UUID, Short>(); | ||
| 48 | } | ||
| 49 | |||
| 50 | /** | ||
| 51 | * Adds a measurement key to the signal index | ||
| 52 | * cache, identified by the given signal index. | ||
| 53 | * | ||
| 54 | * @param signalIndex the 16-bit index by which the | ||
| 55 | * measurement key can be retrieved from the cache | ||
| 56 | * @param signalId the measurement's globally unique identifier | ||
| 57 | * @param source the measurement's source | ||
| 58 | * @param id the measurement's simple numeric identifier | ||
| 59 | * @throws IllegalArgumentException if the given {@code signalID} is | ||
| 60 | * {@code null} or the given {@code source} is {@code null} or | ||
| 61 | * empty | ||
| 62 | */ | ||
| 63 | public void addMeasurementKey(short signalIndex, UUID signalId, String source, int id) | ||
| 64 | { | ||
| 65 | addMeasurementKey(signalIndex, new MeasurementKey(signalId, source, id)); | ||
| 66 | } | ||
| 67 | |||
| 68 | /** | ||
| 69 | * Adds a measurement key to the signal index | ||
| 70 | * cache, identified by the given signal index. | ||
| 71 | * | ||
| 72 | * @param signalIndex the 16-bit index by which the | ||
| 73 | * measurement key can be retrieved from the cache | ||
| 74 | * @param key the measurement key to be placed in the cache | ||
| 75 | */ | ||
| 76 | public void addMeasurementKey(short signalIndex, MeasurementKey key) | ||
| 77 | { | ||
| 78 | m_reference.put(signalIndex, key); | ||
| 79 | m_signalIdCache.put(key.getSignalId(), signalIndex); | ||
| 80 | } | ||
| 81 | |||
| 82 | /** | ||
| 83 | * Empties the signal index cache. | ||
| 84 | */ | ||
| 85 | public void clear() | ||
| 86 | { | ||
| 87 | m_reference.clear(); | ||
| 88 | m_signalIdCache.clear(); | ||
| 89 | } | ||
| 90 | |||
| 91 | /** | ||
| 92 | * Determines whether a measurement key exists | ||
| 93 | * in the cache for the given signal index. | ||
| 94 | * | ||
| 95 | * @param signalIndex the signal index to be searched for | ||
| 96 | * @return true if the signal index refers to | ||
| 97 | * a measurement key; false otherwise | ||
| 98 | */ | ||
| 99 | public boolean contains(short signalIndex) | ||
| 100 | { | ||
| 101 | return m_reference.containsKey(signalIndex); | ||
| 102 | } | ||
| 103 | |||
| 104 | /** | ||
| 105 | * Gets the measurement key identified by the given signal index. | ||
| 106 | * | ||
| 107 | * @param signalIndex the signal index which identifies the measurement key | ||
| 108 | * @return the measurement key identified by the given signal index, | ||
| 109 | * or {@code null} if no mapping exists for the signal index | ||
| 110 | */ | ||
| 111 | public MeasurementKey getMeasurementKey(short signalIndex) | ||
| 112 | { | ||
| 113 | return m_reference.get(signalIndex); | ||
| 114 | } | ||
| 115 | |||
| 116 | /** | ||
| 117 | * Provides a backwards mapping from the globally unique identifiers | ||
| 118 | * of the measurements whose keys are stored in the cache to the | ||
| 119 | * signal indexes that refer to them. | ||
| 120 | * | ||
| 121 | * @param signalId the measurement's globally unique identifier | ||
| 122 | * @return the signal index which identifies the measurement key | ||
| 123 | */ | ||
| 124 | short getSignalIndex(UUID signalId) | ||
| 125 | { | ||
| 126 | return m_signalIdCache.get(signalId); | ||
| 127 | } | ||
| 128 | } | ||
| @@ -0,0 +1,356 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // SubscriberConnector.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/23/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport; | ||
| 25 | |||
| 26 | import java.util.ArrayList; | ||
| 27 | import java.util.Collection; | ||
| 28 | |||
| 29 | import org.gpa.gsf.timeseries.transport.event.MessageEvent; | ||
| 30 | import org.gpa.gsf.timeseries.transport.event.SubscriberAdapter; | ||
| 31 | import org.gpa.gsf.timeseries.transport.event.SubscriberConnectorListener; | ||
| 32 | import org.gpa.gsf.timeseries.transport.event.SubscriberEvent; | ||
| 33 | import org.gpa.gsf.timeseries.transport.event.SubscriberListener; | ||
| 34 | |||
| 35 | /** | ||
| 36 | * Helper class to provide retry and auto-reconnect | ||
| 37 | * functionality to the subscriber. | ||
| 38 | * | ||
| 39 | * @see DataSubscriber | ||
| 40 | */ | ||
| 41 | public class SubscriberConnector | ||
| 42 | { | ||
| 43 | Collection<SubscriberConnectorListener> m_listeners; | ||
| 44 | private DataSubscriber m_subscriber; | ||
| 45 | private SubscriberListener m_autoReconnectHandler; | ||
| 46 | |||
| 47 | private String m_hostname; | ||
| 48 | private int m_port; | ||
| 49 | |||
| 50 | private int m_maxRetries; | ||
| 51 | private int m_retryInterval; | ||
| 52 | private boolean m_autoReconnect; | ||
| 53 | |||
| 54 | private boolean m_cancel; | ||
| 55 | |||
| 56 | /** | ||
| 57 | * Constructs a new instance. The default configuration is infinite | ||
| 58 | * retries on a 2-second interval, and auto-reconnect is on. | ||
| 59 | */ | ||
| 60 | public SubscriberConnector() | ||
| 61 | { | ||
| 62 | m_maxRetries = -1; | ||
| 63 | m_retryInterval = 2000; | ||
| 64 | m_autoReconnect = true; | ||
| 65 | |||
| 66 | m_listeners = new ArrayList<SubscriberConnectorListener>(); | ||
| 67 | } | ||
| 68 | |||
| 69 | /** | ||
| 70 | * Adds the given listener to receive events from this subscriber | ||
| 71 | * connector. If the {@code listener} is {@code null}, no exception | ||
| 72 | * is thrown and no action is performed. | ||
| 73 | * | ||
| 74 | * @param listener the listener to be added | ||
| 75 | */ | ||
| 76 | public void addSubscriberConnectorListener(SubscriberConnectorListener listener) | ||
| 77 | { | ||
| 78 | if (listener != null) | ||
| 79 | m_listeners.add(listener); | ||
| 80 | } | ||
| 81 | |||
| 82 | /** | ||
| 83 | * Removes the given listener so that it no longer receives events | ||
| 84 | * from this subscriber connector. This method performs no function, | ||
| 85 | * nor does it throw an exception, if {@code subscriberListener} was | ||
| 86 | * not previously added to this component. If {@code subscriberListener} | ||
| 87 | * is {@code null}, no exception is thrown and no action is performed. | ||
| 88 | * | ||
| 89 | * @param listener the listener to be removed | ||
| 90 | */ | ||
| 91 | public void removeSubscriberConnectorListener(SubscriberConnectorListener listener) | ||
| 92 | { | ||
| 93 | if (listener != null) | ||
| 94 | m_listeners.remove(listener); | ||
| 95 | } | ||
| 96 | |||
| 97 | /** | ||
| 98 | * Begins the connection sequence. | ||
| 99 | * | ||
| 100 | * @param subscriber the subscriber to be connected | ||
| 101 | * @return connected status of the subscriber | ||
| 102 | * @throws IllegalArgumentException if {@code subscriber} is {@code null} | ||
| 103 | */ | ||
| 104 | public boolean connect(DataSubscriber subscriber) | ||
| 105 | { | ||
| 106 | if (subscriber == null) | ||
| 107 | throw new IllegalArgumentException("subscriber must not be null"); | ||
| 108 | |||
| 109 | // If we are no longer set to auto reconnect, we | ||
| 110 | // may need to detach from an existing subscriber. | ||
| 111 | if (!m_autoReconnect && m_subscriber != null) | ||
| 112 | { | ||
| 113 | m_subscriber.removeSubscriberListener(m_autoReconnectHandler); | ||
| 114 | m_subscriber = null; | ||
| 115 | } | ||
| 116 | |||
| 117 | // If we are set to auto reconnect and we are not currently | ||
| 118 | // attached to the given subscriber, we need to attach to the | ||
| 119 | // new subscriber. | ||
| 120 | if (m_autoReconnect && m_subscriber != subscriber) | ||
| 121 | { | ||
| 122 | if (m_subscriber != null) | ||
| 123 | m_subscriber.removeSubscriberListener(m_autoReconnectHandler); | ||
| 124 | |||
| 125 | if (m_autoReconnectHandler == null) | ||
| 126 | m_autoReconnectHandler = getNewAutoReconnectHandler(); | ||
| 127 | |||
| 128 | m_subscriber = subscriber; | ||
| 129 | subscriber.addSubscriberListener(m_autoReconnectHandler); | ||
| 130 | } | ||
| 131 | |||
| 132 | // Attempt to connect for the given number of retries. | ||
| 133 | for (int i = 0; !m_cancel && (m_maxRetries == -1 || i < m_maxRetries); i++) | ||
| 134 | { | ||
| 135 | try | ||
| 136 | { | ||
| 137 | subscriber.connect(m_hostname, m_port); | ||
| 138 | break; | ||
| 139 | } | ||
| 140 | catch (Exception ex) | ||
| 141 | { | ||
| 142 | triggerExceptionEncounteredAsync(ex); | ||
| 143 | sleep(m_retryInterval); | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | // Return connection status of subscriber. | ||
| 148 | return subscriber.isConnected(); | ||
| 149 | } | ||
| 150 | |||
| 151 | /** | ||
| 152 | * Cancels all current and future connection sequences. | ||
| 153 | */ | ||
| 154 | public void cancel() | ||
| 155 | { | ||
| 156 | m_cancel = true; | ||
| 157 | |||
| 158 | if (m_subscriber != null) | ||
| 159 | m_subscriber.removeSubscriberListener(m_autoReconnectHandler); | ||
| 160 | } | ||
| 161 | |||
| 162 | /** | ||
| 163 | * Gets the hostname of the server this connector is connecting to. | ||
| 164 | * | ||
| 165 | * @return the hostname of the server | ||
| 166 | */ | ||
| 167 | public String getHostname() | ||
| 168 | { | ||
| 169 | return m_hostname; | ||
| 170 | } | ||
| 171 | |||
| 172 | /** | ||
| 173 | * Sets the hostname of the server this connector is connecting to. | ||
| 174 | * | ||
| 175 | * @param hostname the new value for the hostname of the server | ||
| 176 | */ | ||
| 177 | public void setHostname(String hostname) | ||
| 178 | { | ||
| 179 | m_hostname = hostname; | ||
| 180 | } | ||
| 181 | |||
| 182 | /** | ||
| 183 | * Gets the port that the publisher is listening on. | ||
| 184 | * | ||
| 185 | * @return the port that the publisher is listening on | ||
| 186 | */ | ||
| 187 | public int getPort() | ||
| 188 | { | ||
| 189 | return m_port; | ||
| 190 | } | ||
| 191 | |||
| 192 | /** | ||
| 193 | * Sets the port that the publisher is listening on. | ||
| 194 | * | ||
| 195 | * @param port the new value for the port that the publisher | ||
| 196 | * is listening on | ||
| 197 | */ | ||
| 198 | public void setPort(int port) | ||
| 199 | { | ||
| 200 | m_port = port; | ||
| 201 | } | ||
| 202 | |||
| 203 | /** | ||
| 204 | * Gets the maximum number of connection attempts to be made before | ||
| 205 | * giving up. A value of {@code -1} means an infinite number of retries. | ||
| 206 | * | ||
| 207 | * @return the maximum number of retries during a connection sequence | ||
| 208 | */ | ||
| 209 | public int getMaxRetries() | ||
| 210 | { | ||
| 211 | return m_maxRetries; | ||
| 212 | } | ||
| 213 | |||
| 214 | /** | ||
| 215 | * Sets the maximum number of connection attempts to be made before | ||
| 216 | * giving up. A value of {@code -1} means an infinite number of retries. | ||
| 217 | * | ||
| 218 | * @param maxRetries the new value for the maximum number of retries | ||
| 219 | */ | ||
| 220 | public void setMaxRetries(int maxRetries) | ||
| 221 | { | ||
| 222 | m_maxRetries = maxRetries; | ||
| 223 | } | ||
| 224 | |||
| 225 | /** | ||
| 226 | * Gets the interval of time, in milliseconds, between | ||
| 227 | * each connection attempt during a connection sequence. | ||
| 228 | * | ||
| 229 | * @return the retry interval, in milliseconds | ||
| 230 | */ | ||
| 231 | public int getRetryInterval() | ||
| 232 | { | ||
| 233 | return m_retryInterval; | ||
| 234 | } | ||
| 235 | |||
| 236 | /** | ||
| 237 | * Sets the interval of time, in milliseconds, between | ||
| 238 | * each connection attempt during a connection sequence. | ||
| 239 | * | ||
| 240 | * @param retryInterval the new value for the retry interval, | ||
| 241 | * in milliseconds | ||
| 242 | */ | ||
| 243 | public void setRetryInterval(int retryInterval) | ||
| 244 | { | ||
| 245 | m_retryInterval = retryInterval; | ||
| 246 | } | ||
| 247 | |||
| 248 | /** | ||
| 249 | * Gets the flag that indicates whether this connector should | ||
| 250 | * automatically attempt to reconnect the subscriber when the | ||
| 251 | * connection is terminated. | ||
| 252 | * | ||
| 253 | * @return the auto-reconnect flag | ||
| 254 | */ | ||
| 255 | public boolean isAutoReconnect() | ||
| 256 | { | ||
| 257 | return m_autoReconnect; | ||
| 258 | } | ||
| 259 | |||
| 260 | /** | ||
| 261 | * Sets the flag that indicates whether this connector should | ||
| 262 | * automatically attempt to reconnect the subscriber when the | ||
| 263 | * connection is terminated. | ||
| 264 | * | ||
| 265 | * @param autoReconnect the new value for the auto-reconnect flag | ||
| 266 | */ | ||
| 267 | public void setAutoReconnect(boolean autoReconnect) | ||
| 268 | { | ||
| 269 | m_autoReconnect = autoReconnect; | ||
| 270 | } | ||
| 271 | |||
| 272 | // Creates and returns a new auto-reconnect handler. | ||
| 273 | private SubscriberListener getNewAutoReconnectHandler() | ||
| 274 | { | ||
| 275 | return new SubscriberAdapter() | ||
| 276 | { | ||
| 277 | @Override | ||
| 278 | public void connectionTerminated(MessageEvent evt) | ||
| 279 | { | ||
| 280 | if (m_autoReconnect) | ||
| 281 | { | ||
| 282 | if (!m_cancel) | ||
| 283 | triggerExceptionEncountered(evt.getException()); | ||
| 284 | |||
| 285 | connect(m_subscriber); | ||
| 286 | |||
| 287 | if (!m_cancel) | ||
| 288 | triggerReconnected(); | ||
| 289 | } | ||
| 290 | } | ||
| 291 | }; | ||
| 292 | } | ||
| 293 | |||
| 294 | // Triggers the exceptionEncountered event for | ||
| 295 | // all listeners subscribed to this connector. | ||
| 296 | // The event is triggered on a separate thread. | ||
| 297 | private void triggerExceptionEncounteredAsync(final Exception ex) | ||
| 298 | { | ||
| 299 | new Thread(new Runnable() | ||
| 300 | { | ||
| 301 | @Override | ||
| 302 | public void run() | ||
| 303 | { | ||
| 304 | triggerExceptionEncountered(ex); | ||
| 305 | } | ||
| 306 | }).start(); | ||
| 307 | } | ||
| 308 | |||
| 309 | // Triggers the exceptionEncountered event for | ||
| 310 | // all listeners subscribed to this connector. | ||
| 311 | private void triggerExceptionEncountered(Exception encounteredException) | ||
| 312 | { | ||
| 313 | for (SubscriberConnectorListener listener : m_listeners) | ||
| 314 | { | ||
| 315 | try | ||
| 316 | { | ||
| 317 | listener.exceptionEncountered(new MessageEvent(this, encounteredException)); | ||
| 318 | } | ||
| 319 | catch (Exception ex) | ||
| 320 | { | ||
| 321 | // Ignore exceptions encountered | ||
| 322 | // while reporting exceptions | ||
| 323 | } | ||
| 324 | } | ||
| 325 | } | ||
| 326 | |||
| 327 | // Triggers the reconnected event for all | ||
| 328 | // listeners subscribed to this connector. | ||
| 329 | private void triggerReconnected() | ||
| 330 | { | ||
| 331 | for (SubscriberConnectorListener listener : m_listeners) | ||
| 332 | { | ||
| 333 | try | ||
| 334 | { | ||
| 335 | listener.reconnected(new SubscriberEvent(this, m_subscriber)); | ||
| 336 | } | ||
| 337 | catch (Exception ex) | ||
| 338 | { | ||
| 339 | triggerExceptionEncountered(ex); | ||
| 340 | } | ||
| 341 | } | ||
| 342 | } | ||
| 343 | |||
| 344 | // Puts the current thread to sleep for the given period of time. | ||
| 345 | private void sleep(long millis) | ||
| 346 | { | ||
| 347 | try | ||
| 348 | { | ||
| 349 | Thread.sleep(millis); | ||
| 350 | } | ||
| 351 | catch (InterruptedException ex) | ||
| 352 | { | ||
| 353 | triggerExceptionEncountered(ex); | ||
| 354 | } | ||
| 355 | } | ||
| 356 | } | ||
| @@ -0,0 +1,563 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // SubscriptionInfo.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/16/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * Configuration object for data subscriptions. | ||
| 28 | * | ||
| 29 | * @see DataSubscriber | ||
| 30 | * @see DataSubscriber#subscribe(SubscriptionInfo) | ||
| 31 | */ | ||
| 32 | public class SubscriptionInfo | ||
| 33 | { | ||
| 34 | private String m_filterExpression; | ||
| 35 | |||
| 36 | private boolean m_remotelySynchronized; | ||
| 37 | private boolean m_throttled; | ||
| 38 | |||
| 39 | private boolean m_udpDataChannel; | ||
| 40 | private int m_dataChannelLocalPort; | ||
| 41 | |||
| 42 | private boolean m_timeIncluded; | ||
| 43 | private double m_lagTime; | ||
| 44 | private double m_leadTime; | ||
| 45 | private boolean m_localClockAsRealTime; | ||
| 46 | private boolean m_millisecondResolution; | ||
| 47 | |||
| 48 | private String m_startTime; | ||
| 49 | private String m_stopTime; | ||
| 50 | private String m_constraintParameters; | ||
| 51 | private int m_processingInterval; | ||
| 52 | |||
| 53 | private String m_waitHandleNames; | ||
| 54 | private int m_waitHandleTimeout; | ||
| 55 | |||
| 56 | private String m_extraConnectionStringParameters; | ||
| 57 | |||
| 58 | /** | ||
| 59 | * Constructs a new subscription info. | ||
| 60 | * The following default values have been overwritten. | ||
| 61 | * | ||
| 62 | * <ul> | ||
| 63 | * <li>{@code DataChannelLocalPort = 9500}</li> | ||
| 64 | * <li>{@code IncludeTime = true}</li> | ||
| 65 | * <li>{@code LagTime = 10.0}</li> | ||
| 66 | * <li>{@code LeadTime = 5.0}</li> | ||
| 67 | * <li>{@code ProcessingInterval = -1}</li> | ||
| 68 | * </ul> | ||
| 69 | */ | ||
| 70 | public SubscriptionInfo() | ||
| 71 | { | ||
| 72 | m_dataChannelLocalPort = 9500; | ||
| 73 | m_timeIncluded = true; | ||
| 74 | m_lagTime = 10.0; | ||
| 75 | m_leadTime = 5.0; | ||
| 76 | m_processingInterval = -1; | ||
| 77 | } | ||
| 78 | |||
| 79 | /** | ||
| 80 | * Constructs a new subscription info object that | ||
| 81 | * is a copy of an existing subscription info object. | ||
| 82 | * | ||
| 83 | * @param info the subscription info to be copied | ||
| 84 | */ | ||
| 85 | public SubscriptionInfo(SubscriptionInfo info) | ||
| 86 | { | ||
| 87 | m_filterExpression = info.m_filterExpression; | ||
| 88 | |||
| 89 | m_remotelySynchronized = info.m_remotelySynchronized; | ||
| 90 | m_throttled = info.m_throttled; | ||
| 91 | |||
| 92 | m_udpDataChannel = info.m_udpDataChannel; | ||
| 93 | m_dataChannelLocalPort = info.m_dataChannelLocalPort; | ||
| 94 | |||
| 95 | m_timeIncluded = info.m_timeIncluded; | ||
| 96 | m_lagTime = info.m_lagTime; | ||
| 97 | m_leadTime = info.m_leadTime; | ||
| 98 | m_localClockAsRealTime = info.m_localClockAsRealTime; | ||
| 99 | m_millisecondResolution = info.m_millisecondResolution; | ||
| 100 | |||
| 101 | m_startTime = info.m_startTime; | ||
| 102 | m_stopTime = info.m_stopTime; | ||
| 103 | m_constraintParameters = info.m_constraintParameters; | ||
| 104 | m_processingInterval = info.m_processingInterval; | ||
| 105 | |||
| 106 | m_waitHandleNames = info.m_waitHandleNames; | ||
| 107 | m_waitHandleTimeout = info.m_waitHandleTimeout; | ||
| 108 | |||
| 109 | m_extraConnectionStringParameters = info.m_extraConnectionStringParameters; | ||
| 110 | } | ||
| 111 | |||
| 112 | /** | ||
| 113 | * Gets the filter expression used to define which | ||
| 114 | * measurements are being requested by the subscriber. | ||
| 115 | * | ||
| 116 | * @return the filter expression | ||
| 117 | * @see #setFilterExpression(String) | ||
| 118 | */ | ||
| 119 | public String getFilterExpression() | ||
| 120 | { | ||
| 121 | return m_filterExpression; | ||
| 122 | } | ||
| 123 | |||
| 124 | /** | ||
| 125 | * Sets the filter expression used to define which | ||
| 126 | * measurements are being requested by the subscriber. | ||
| 127 | * | ||
| 128 | * @param filterExpression the new value for the filter expression | ||
| 129 | * @see #getFilterExpression() | ||
| 130 | */ | ||
| 131 | public void setFilterExpression(String filterExpression) | ||
| 132 | { | ||
| 133 | m_filterExpression = filterExpression; | ||
| 134 | } | ||
| 135 | |||
| 136 | /** | ||
| 137 | * Gets the flag that indicates whether the subscriber is requesting | ||
| 138 | * that its measurements be synchronized by the publisher. | ||
| 139 | * | ||
| 140 | * @return the flag that indicates whether the subscriber is requesting | ||
| 141 | * that its measurements be synchronized by the publisher | ||
| 142 | * @see #setRemotelySynchronized(boolean) | ||
| 143 | */ | ||
| 144 | public boolean isRemotelySynchronized() | ||
| 145 | { | ||
| 146 | return m_remotelySynchronized; | ||
| 147 | } | ||
| 148 | |||
| 149 | /** | ||
| 150 | * Sets the flag that indicates whether the subscriber is requesting | ||
| 151 | * that its measurements be synchronized by the publisher. | ||
| 152 | * | ||
| 153 | * @param remotelySynchronized the new value of the flag that indicates | ||
| 154 | * whether the subscriber is requesting that its measurements be | ||
| 155 | * synchronized by the publisher | ||
| 156 | * @see #isRemotelySynchronized() | ||
| 157 | */ | ||
| 158 | public void setRemotelySynchronized(boolean remotelySynchronized) | ||
| 159 | { | ||
| 160 | m_remotelySynchronized = remotelySynchronized; | ||
| 161 | } | ||
| 162 | |||
| 163 | /** | ||
| 164 | * Gets a flag indicating whether the | ||
| 165 | * requested position is to be throttled. | ||
| 166 | * | ||
| 167 | * @return flag indicating whether the subscription is throttled | ||
| 168 | * @see #setThrottled(boolean) | ||
| 169 | */ | ||
| 170 | public boolean isThrottled() | ||
| 171 | { | ||
| 172 | return m_throttled; | ||
| 173 | } | ||
| 174 | |||
| 175 | /** | ||
| 176 | * Sets the flag which determines whether to | ||
| 177 | * request that the subscription be throttled. | ||
| 178 | * | ||
| 179 | * @param throttled the new value for the flag | ||
| 180 | * @see #isThrottled() | ||
| 181 | */ | ||
| 182 | public void setThrottled(boolean throttled) | ||
| 183 | { | ||
| 184 | m_throttled = throttled; | ||
| 185 | } | ||
| 186 | |||
| 187 | /** | ||
| 188 | * Gets the flag which indicates whether the subscriber is | ||
| 189 | * requesting its data over a separate UDP data channel. | ||
| 190 | * | ||
| 191 | * @return the flag which indicates whether the subscriber is | ||
| 192 | * requesting its data over a separate UDP data channel | ||
| 193 | * @see #setUdpDataChannel(boolean) | ||
| 194 | */ | ||
| 195 | public boolean isUdpDataChannel() | ||
| 196 | { | ||
| 197 | return m_udpDataChannel; | ||
| 198 | } | ||
| 199 | |||
| 200 | /** | ||
| 201 | * Sets the flag which determines whether the subscriber is | ||
| 202 | * requesting its data over a separate UDP data channel. | ||
| 203 | * | ||
| 204 | * @param udpDataChannel the new value for the flag | ||
| 205 | * @see #isUdpDataChannel() | ||
| 206 | */ | ||
| 207 | public void setUdpDataChannel(boolean udpDataChannel) | ||
| 208 | { | ||
| 209 | m_udpDataChannel = udpDataChannel; | ||
| 210 | } | ||
| 211 | |||
| 212 | /** | ||
| 213 | * Gets the port that the UDP data channel binds to. This value is | ||
| 214 | * only used when the subscriber requests a separate UDP data channel. | ||
| 215 | * | ||
| 216 | * @return the local port that the UDP data channel binds to | ||
| 217 | * @see #setDataChannelLocalPort(int) | ||
| 218 | * @see #isUdpDataChannel() | ||
| 219 | */ | ||
| 220 | public int getDataChannelLocalPort() | ||
| 221 | { | ||
| 222 | return m_dataChannelLocalPort; | ||
| 223 | } | ||
| 224 | |||
| 225 | /** | ||
| 226 | * Sets the port that the UDP data channel binds to. This value is | ||
| 227 | * only used when the subscriber requests a separate UDP data channel. | ||
| 228 | * | ||
| 229 | * @param dataChannelLocalPort | ||
| 230 | * @see #getDataChannelLocalPort() | ||
| 231 | * @see #setUdpDataChannel(boolean) | ||
| 232 | */ | ||
| 233 | public void setDataChannelLocalPort(int dataChannelLocalPort) | ||
| 234 | { | ||
| 235 | m_dataChannelLocalPort = dataChannelLocalPort; | ||
| 236 | } | ||
| 237 | |||
| 238 | /** | ||
| 239 | * Gets the flag indicating whether timestamps are included in the | ||
| 240 | * data sent from the publisher. This value is ignored if the data | ||
| 241 | * is remotely synchronized. | ||
| 242 | * | ||
| 243 | * @return the flag indicating whether timestamps are included | ||
| 244 | * @see #setTimeIncluded(boolean) | ||
| 245 | */ | ||
| 246 | public boolean isTimeIncluded() | ||
| 247 | { | ||
| 248 | return m_timeIncluded; | ||
| 249 | } | ||
| 250 | |||
| 251 | /** | ||
| 252 | * Sets the flag which determines whether timestamps are included in | ||
| 253 | * the data sent from the publisher. This value is ignored if the data | ||
| 254 | * is remotely synchronized. | ||
| 255 | * | ||
| 256 | * @param timeIncluded the new value for the flag | ||
| 257 | * @see #isTimeIncluded() | ||
| 258 | */ | ||
| 259 | public void setTimeIncluded(boolean timeIncluded) | ||
| 260 | { | ||
| 261 | m_timeIncluded = timeIncluded; | ||
| 262 | } | ||
| 263 | |||
| 264 | /** | ||
| 265 | * Gets the allowed past time deviation tolerance, in seconds. | ||
| 266 | * | ||
| 267 | * @return the allowed past time deviation tolerance | ||
| 268 | * @see #setLagTime(double) | ||
| 269 | */ | ||
| 270 | public double getLagTime() | ||
| 271 | { | ||
| 272 | return m_lagTime; | ||
| 273 | } | ||
| 274 | |||
| 275 | /** | ||
| 276 | * Sets the allowed past time deviation | ||
| 277 | * tolerance, in seconds (can be subscecond). | ||
| 278 | * | ||
| 279 | * @param lagTime the new value for the allowed | ||
| 280 | * past time deviation tolerance | ||
| 281 | * @see #getLagTime() | ||
| 282 | */ | ||
| 283 | public void setLagTime(double lagTime) | ||
| 284 | { | ||
| 285 | m_lagTime = lagTime; | ||
| 286 | } | ||
| 287 | |||
| 288 | /** | ||
| 289 | * Gets the allowed future time deviation tolerance, in seconds. | ||
| 290 | * | ||
| 291 | * @return the allowed future time deviation tolerance | ||
| 292 | * @see #setLeadTime(double) | ||
| 293 | */ | ||
| 294 | public double getLeadTime() | ||
| 295 | { | ||
| 296 | return m_leadTime; | ||
| 297 | } | ||
| 298 | |||
| 299 | /** | ||
| 300 | * Sets the allowed future time deviation | ||
| 301 | * tolerance, in seconds (can be subsecond). | ||
| 302 | * | ||
| 303 | * @param leadTime the new value for the allowed | ||
| 304 | * future time deviation tolerance | ||
| 305 | * @see #getLeadTime() | ||
| 306 | */ | ||
| 307 | public void setLeadTime(double leadTime) | ||
| 308 | { | ||
| 309 | m_leadTime = leadTime; | ||
| 310 | } | ||
| 311 | |||
| 312 | /** | ||
| 313 | * Gets the flag that indicates whether the server's local clock is | ||
| 314 | * used as real-time. Otherwise, the timestamps of the measurements | ||
| 315 | * will be used as real-time. | ||
| 316 | * | ||
| 317 | * @return the flag that indicates whether the server's local clock | ||
| 318 | * is used as real-time | ||
| 319 | * @see #setLocalClockAsRealTime(boolean) | ||
| 320 | */ | ||
| 321 | public boolean isLocalClockAsRealTime() | ||
| 322 | { | ||
| 323 | return m_localClockAsRealTime; | ||
| 324 | } | ||
| 325 | |||
| 326 | /** | ||
| 327 | * Sets the flag which determines whether the server's local clock is | ||
| 328 | * used as real-time. Otherwise, the timestamps of the measurements | ||
| 329 | * will be used as real-time. | ||
| 330 | * | ||
| 331 | * @param localClockAsRealTime the new value for the flag | ||
| 332 | * @see #isLocalClockAsRealTime() | ||
| 333 | */ | ||
| 334 | public void setLocalClockAsRealTime(boolean localClockAsRealTime) | ||
| 335 | { | ||
| 336 | m_localClockAsRealTime = localClockAsRealTime; | ||
| 337 | } | ||
| 338 | |||
| 339 | /** | ||
| 340 | * Gets the flag that indicates whether measurement timestamps use | ||
| 341 | * millisecond resolution. Otherwise, they will use 100-nanosecond | ||
| 342 | * resolution. | ||
| 343 | * <p> | ||
| 344 | * This flag determines the size of the timestamps transmitted as | ||
| 345 | * part of the compact measurement format when the server is using | ||
| 346 | * base time offsets. | ||
| 347 | * | ||
| 348 | * @return the flag that indicates whether measurement timestamps use | ||
| 349 | * millisecond resolution | ||
| 350 | * @see #setMillisecondResolution(boolean) | ||
| 351 | */ | ||
| 352 | public boolean isMillisecondResolution() | ||
| 353 | { | ||
| 354 | return m_millisecondResolution; | ||
| 355 | } | ||
| 356 | |||
| 357 | /** | ||
| 358 | * Gets the flag that indicates whether measurement timestamps use | ||
| 359 | * millisecond resolution. Otherwise, they will use 100-nanosecond | ||
| 360 | * resolution. | ||
| 361 | * <p> | ||
| 362 | * This flag determines the size of the timestamps transmitted as | ||
| 363 | * part of the compact measurement format when the server is using | ||
| 364 | * base time offsets. | ||
| 365 | * | ||
| 366 | * @param millisecondResolution the new value for the flag | ||
| 367 | * @see #isMillisecondResolution() | ||
| 368 | */ | ||
| 369 | public void setMillisecondResolution(boolean millisecondResolution) | ||
| 370 | { | ||
| 371 | m_millisecondResolution = millisecondResolution; | ||
| 372 | } | ||
| 373 | |||
| 374 | /** | ||
| 375 | * Gets the start time of the requested temporal | ||
| 376 | * session for streaming historic data. | ||
| 377 | * | ||
| 378 | * @return the start time of the requested temporal session | ||
| 379 | * @see #setStartTime(String) | ||
| 380 | * @see #getStopTime() | ||
| 381 | * @see #getConstraintParameters() | ||
| 382 | */ | ||
| 383 | public String getStartTime() | ||
| 384 | { | ||
| 385 | return m_startTime; | ||
| 386 | } | ||
| 387 | |||
| 388 | /** | ||
| 389 | * Sets the start time of the requested temporal | ||
| 390 | * session for streaming historic data. | ||
| 391 | * | ||
| 392 | * @param startTime the new value for the start time | ||
| 393 | * @see #getStartTime() | ||
| 394 | * @see #setStopTime(String) | ||
| 395 | * @see #setConstraintParameters(String) | ||
| 396 | */ | ||
| 397 | public void setStartTime(String startTime) | ||
| 398 | { | ||
| 399 | m_startTime = startTime; | ||
| 400 | } | ||
| 401 | |||
| 402 | /** | ||
| 403 | * Gets the stop time of the requested temporal | ||
| 404 | * session for streaming historic data. | ||
| 405 | * | ||
| 406 | * @return the stop time of the requested temporal session | ||
| 407 | * @see #setStopTime(String) | ||
| 408 | * @see #getStartTime() | ||
| 409 | * @see #getConstraintParameters() | ||
| 410 | */ | ||
| 411 | public String getStopTime() | ||
| 412 | { | ||
| 413 | return m_stopTime; | ||
| 414 | } | ||
| 415 | |||
| 416 | /** | ||
| 417 | * Sets the stop time of the requested temporal | ||
| 418 | * session for streaming historic data. | ||
| 419 | * | ||
| 420 | * @param stopTime the new value for the stop time | ||
| 421 | * @see #getStopTime() | ||
| 422 | * @see #setStartTime(String) | ||
| 423 | * @see #setConstraintParameters(String) | ||
| 424 | */ | ||
| 425 | public void setStopTime(String stopTime) | ||
| 426 | { | ||
| 427 | m_stopTime = stopTime; | ||
| 428 | } | ||
| 429 | |||
| 430 | /** | ||
| 431 | * Gets the additional constraint parameters supplied | ||
| 432 | * to temporal adapters in a temporal session. | ||
| 433 | * | ||
| 434 | * @return the additional constraint parameters for temporal adapters | ||
| 435 | * @see #setConstraintParameters(String) | ||
| 436 | * @see #getStartTime() | ||
| 437 | * @see #getStopTime() | ||
| 438 | */ | ||
| 439 | public String getConstraintParameters() | ||
| 440 | { | ||
| 441 | return m_constraintParameters; | ||
| 442 | } | ||
| 443 | |||
| 444 | /** | ||
| 445 | * Sets the additional constraint parameters supplied | ||
| 446 | * to temporal adapters in a temporal session. | ||
| 447 | * | ||
| 448 | * @param constraintParameters the new value for the additional parameters | ||
| 449 | * @see #getConstraintParameters() | ||
| 450 | * @see #setStartTime(String) | ||
| 451 | * @see #setStopTime(String) | ||
| 452 | */ | ||
| 453 | public void setConstraintParameters(String constraintParameters) | ||
| 454 | { | ||
| 455 | m_constraintParameters = constraintParameters; | ||
| 456 | } | ||
| 457 | |||
| 458 | /** | ||
| 459 | * Gets the processing interval requested by the subscriber. A value | ||
| 460 | * of {@code -1} indicates the default processing interval. A value | ||
| 461 | * of {@code 0} indicates data will be processed as fast as possible. | ||
| 462 | * | ||
| 463 | * @return the processing interval requested by the subscriber | ||
| 464 | * @see #setProcessingInterval(int) | ||
| 465 | */ | ||
| 466 | public int getProcessingInterval() | ||
| 467 | { | ||
| 468 | return m_processingInterval; | ||
| 469 | } | ||
| 470 | |||
| 471 | /** | ||
| 472 | * Sets the processing interval requested by the subscriber. A value | ||
| 473 | * of {@code -1} indicates the default processing interval. A value | ||
| 474 | * of {@code 0} indicates data will be processed as fast as possible. | ||
| 475 | * | ||
| 476 | * @param processingInterval the new value for the processing interval | ||
| 477 | * @see #getProcessingInterval() | ||
| 478 | */ | ||
| 479 | public void setProcessingInterval(int processingInterval) | ||
| 480 | { | ||
| 481 | m_processingInterval = processingInterval; | ||
| 482 | } | ||
| 483 | |||
| 484 | /** | ||
| 485 | * Gets the wait handle names used to deterministically wait for data | ||
| 486 | * to become available on the server side. | ||
| 487 | * | ||
| 488 | * @return the wait handle names | ||
| 489 | * @see #setWaitHandleNames(String) | ||
| 490 | * @see #getWaitHandleTimeout() | ||
| 491 | */ | ||
| 492 | public String getWaitHandleNames() | ||
| 493 | { | ||
| 494 | return m_waitHandleNames; | ||
| 495 | } | ||
| 496 | |||
| 497 | /** | ||
| 498 | * Sets the wait handle names used to deterministically wait for data | ||
| 499 | * to become available on the server side. | ||
| 500 | * | ||
| 501 | * @param waitHandleNames the new value for the wait handle names | ||
| 502 | * @see #getWaitHandleNames() | ||
| 503 | * @see #setWaitHandleTimeout(int) | ||
| 504 | */ | ||
| 505 | public void setWaitHandleNames(String waitHandleNames) | ||
| 506 | { | ||
| 507 | m_waitHandleNames = waitHandleNames; | ||
| 508 | } | ||
| 509 | |||
| 510 | /** | ||
| 511 | * Gets the amount of time to wait on the wait handles identified by | ||
| 512 | * the wait handle names before the operation times out. | ||
| 513 | * | ||
| 514 | * @return the amount of time to wait on the wait handles before timing out | ||
| 515 | * @see #setWaitHandleTimeout(int) | ||
| 516 | * @see #getWaitHandleNames() | ||
| 517 | */ | ||
| 518 | public int getWaitHandleTimeout() | ||
| 519 | { | ||
| 520 | return m_waitHandleTimeout; | ||
| 521 | } | ||
| 522 | |||
| 523 | /** | ||
| 524 | * Sets the amount of time to wait on the wait handle identified by | ||
| 525 | * the wait handle names before the operation times out. | ||
| 526 | * | ||
| 527 | * @param waitHandleTimeout the new value for the amount of time to | ||
| 528 | * wait on the wait handles before timing out | ||
| 529 | * @see #getWaitHandleTimeout() | ||
| 530 | * @see #setWaitHandleNames(String) | ||
| 531 | */ | ||
| 532 | public void setWaitHandleTimeout(int waitHandleTimeout) | ||
| 533 | { | ||
| 534 | m_waitHandleTimeout = waitHandleTimeout; | ||
| 535 | } | ||
| 536 | |||
| 537 | /** | ||
| 538 | * Gets the additional connection string parameters to be applied | ||
| 539 | * to the connection string sent to the publisher during subscription. | ||
| 540 | * | ||
| 541 | * @return the additional connection string parameters sent to the | ||
| 542 | * publisher during subscription | ||
| 543 | * @see #setExtraConnectionStringParameters(String) | ||
| 544 | */ | ||
| 545 | public String getExtraConnectionStringParameters() | ||
| 546 | { | ||
| 547 | return m_extraConnectionStringParameters; | ||
| 548 | } | ||
| 549 | |||
| 550 | /** | ||
| 551 | * Sets the additional connection string parameters to be applied | ||
| 552 | * to the connection string sent to the publisher during subscription. | ||
| 553 | * | ||
| 554 | * @param extraConnectionStringParameters the new value for the addtional | ||
| 555 | * connection string parameters sent to the publisher during | ||
| 556 | * subscription | ||
| 557 | * @see #getExtraConnectionStringParameters() | ||
| 558 | */ | ||
| 559 | public void setExtraConnectionStringParameters(String extraConnectionStringParameters) | ||
| 560 | { | ||
| 561 | m_extraConnectionStringParameters = extraConnectionStringParameters; | ||
| 562 | } | ||
| 563 | } | ||
| @@ -0,0 +1,40 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // CompressionMode.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 09/14/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport.constant; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * Defines character encodings supported by the Gateway Exchange Protocol. | ||
| 28 | */ | ||
| 29 | public class CompressionMode | ||
| 30 | { | ||
| 31 | /** | ||
| 32 | * GZIP compression. | ||
| 33 | */ | ||
| 34 | public static final int GZIP = 0x00000020; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * No compression. | ||
| 38 | */ | ||
| 39 | public static final int None = 0x00000000; | ||
| 40 | } | ||
| @@ -0,0 +1,52 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // DataPacketFlags.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/16/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport.constant; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * Defines the flags used for compact measurement data packets. | ||
| 28 | */ | ||
| 29 | public class DataPacketFlags | ||
| 30 | { | ||
| 31 | /** | ||
| 32 | * Attached to packets which are remotely synchronized. | ||
| 33 | */ | ||
| 34 | public static final byte Synchronized = 0x01; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * Attached to packets which are serialized | ||
| 38 | * using the compact measurement format. | ||
| 39 | */ | ||
| 40 | public static final byte Compact = 0x02; | ||
| 41 | |||
| 42 | /** | ||
| 43 | * Indicates the index which identifies the cryptography | ||
| 44 | * key used to encrypt the data in the packet. | ||
| 45 | */ | ||
| 46 | public static final byte CipherIndex = 0x03; | ||
| 47 | |||
| 48 | /** | ||
| 49 | * No flags. | ||
| 50 | */ | ||
| 51 | public static final byte NoFlags = 0x00; | ||
| 52 | } | ||
| @@ -0,0 +1,54 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // OperationalEncoding.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/16/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport.constant; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * Defines character encodings supported by the Gateway Exchange Protocol. | ||
| 28 | */ | ||
| 29 | public class OperationalEncoding | ||
| 30 | { | ||
| 31 | /** | ||
| 32 | * Little-endian UTF-16. | ||
| 33 | */ | ||
| 34 | public static final int Unicode = 0x00000000; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * Big-endian UTF-16. | ||
| 38 | */ | ||
| 39 | public static final int BigEndianUnicode = 0x00000100; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * UTF-8 | ||
| 43 | */ | ||
| 44 | public static final int UTF8 = 0x00000200; | ||
| 45 | |||
| 46 | /** | ||
| 47 | * The default character encoding used by the operating system. | ||
| 48 | * This option may not work properly if the two systems that | ||
| 49 | * are communicating are not using the same operating system default. | ||
| 50 | * On Windows systems, this will often be compatible with the ANSI | ||
| 51 | * option defined in the C# implementation of the Publisher API. | ||
| 52 | */ | ||
| 53 | public static final int OperatingSystemDefault = 0x00000300; | ||
| 54 | } | ||
| @@ -0,0 +1,78 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // OperationalModes.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/16/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport.constant; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * Defines flags and bitmasks used in the operational modes | ||
| 28 | * that define how the subscriber and publisher communicate. | ||
| 29 | * Operational modes are the first things that get transmitted | ||
| 30 | * to the publisher after a successful connection. | ||
| 31 | */ | ||
| 32 | public class OperationalModes | ||
| 33 | { | ||
| 34 | /** | ||
| 35 | * Bitmask to extract the protocol version from the operational modes. | ||
| 36 | */ | ||
| 37 | public static final int VersionMask = 0x0000001F; | ||
| 38 | |||
| 39 | /** | ||
| 40 | * Bitmask to extract the compression mode from the operational modes. | ||
| 41 | * Compression is currently not supported; these bits are reserved. | ||
| 42 | */ | ||
| 43 | public static final int CompressionModeMask = 0x000000E0; | ||
| 44 | |||
| 45 | /** | ||
| 46 | * Bitmask to extract the operational encoding from the operational modes. | ||
| 47 | * | ||
| 48 | * @see OperationalEncoding | ||
| 49 | */ | ||
| 50 | public static final int EncodingMask = 0x00000300; | ||
| 51 | |||
| 52 | /** | ||
| 53 | * Flag that determines whether to use the common serialization format. | ||
| 54 | * If the bit is set, the common serialization format is used. If the | ||
| 55 | * flag is unset, the .NET serialization format is used. This Java | ||
| 56 | * implementation of the Subscriber API only supports the common | ||
| 57 | * serialization format. | ||
| 58 | */ | ||
| 59 | public static final int UseCommonSerializationFormat = 0x01000000; | ||
| 60 | |||
| 61 | /** | ||
| 62 | * Flag that determines whether to compress the signal index cache. | ||
| 63 | * This Java implementation of the Subscriber API does not yet support | ||
| 64 | * compression of the signal index cache. | ||
| 65 | */ | ||
| 66 | public static final int CompressSignalIndexCache = 0x40000000; | ||
| 67 | |||
| 68 | /** | ||
| 69 | * Flag that determines whether to compress the metadata transmitted | ||
| 70 | * from the publisher to the subscriber. | ||
| 71 | */ | ||
| 72 | public static final int CompressMetadata = 0x80000000; | ||
| 73 | |||
| 74 | /** | ||
| 75 | * No flags. | ||
| 76 | */ | ||
| 77 | public static final int NoFlags = 0x00000000; | ||
| 78 | } | ||
| @@ -0,0 +1,82 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // ServerCommand.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/16/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport.constant; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * Defines command codes for the commands that can | ||
| 28 | * be sent to the publisher via the command channel. | ||
| 29 | */ | ||
| 30 | public class ServerCommand | ||
| 31 | { | ||
| 32 | /** | ||
| 33 | * Indicates that the subscriber would like to authenticate. | ||
| 34 | * <p> | ||
| 35 | * The data that accompanies this message is the encrypted | ||
| 36 | * authentication string prefixed with its byte length. The | ||
| 37 | * byte length should be unencrypted. The authentication | ||
| 38 | * string consists of the subscriber's authentication ID | ||
| 39 | * prefixed with a random, 8-byte salt. | ||
| 40 | */ | ||
| 41 | public static final byte Authenticate = 0x00; | ||
| 42 | |||
| 43 | /** | ||
| 44 | * Indicates that the subscriber would like | ||
| 45 | * to receive metadata from the publisher. | ||
| 46 | */ | ||
| 47 | public static final byte MetadataRefresh = 0x01; | ||
| 48 | |||
| 49 | /** | ||
| 50 | * Indicates that the subscriber would like | ||
| 51 | * to receive measurements from the publisher. | ||
| 52 | * <p> | ||
| 53 | * The data that accompanies this message is the connection string | ||
| 54 | * which defines several configuration options that can be asked | ||
| 55 | * of the publisher. | ||
| 56 | */ | ||
| 57 | public static final byte Subscribe = 0x02; | ||
| 58 | |||
| 59 | /** | ||
| 60 | * Indicates that the subscriber would like to stop | ||
| 61 | * receiving measurements from the publisher. | ||
| 62 | */ | ||
| 63 | public static final byte Unsubscribe = 0x03; | ||
| 64 | |||
| 65 | /** | ||
| 66 | * Indicates that the subscriber would | ||
| 67 | * like to initiate a cipher key rotation. | ||
| 68 | */ | ||
| 69 | public static final byte RotateCipherKeys = 0x04; | ||
| 70 | |||
| 71 | /** | ||
| 72 | * Indicates that the subscriber would like | ||
| 73 | * to change its measurement processing interval. | ||
| 74 | */ | ||
| 75 | public static final byte UpdateProcessingInterval = 0x05; | ||
| 76 | |||
| 77 | /** | ||
| 78 | * Indicates that the subscriber would like to define | ||
| 79 | * or change the way it is communicating with the publisher. | ||
| 80 | */ | ||
| 81 | public static final byte DefineOperationalModes = 0x06; | ||
| 82 | } | ||
| @@ -0,0 +1,86 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // ServerResponse.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/16/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport.constant; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * Defines response codes that can be sent by the publisher back to the | ||
| 28 | * subscriber. | ||
| 29 | */ | ||
| 30 | public class ServerResponse | ||
| 31 | { | ||
| 32 | /** | ||
| 33 | * Indicates that a command sent by the subscriber has been successfully | ||
| 34 | * processed and handled. | ||
| 35 | */ | ||
| 36 | public static final byte Succeeded = (byte) 0x80; | ||
| 37 | |||
| 38 | /** | ||
| 39 | * Indicates that the publisher was unable to properly process and handle a | ||
| 40 | * command sent by the publisher. | ||
| 41 | */ | ||
| 42 | public static final byte Failed = (byte) 0x81; | ||
| 43 | |||
| 44 | /** | ||
| 45 | * Indicates that the packet sent with this code contains measurement data. | ||
| 46 | */ | ||
| 47 | public static final byte DataPacket = (byte) 0x82; | ||
| 48 | |||
| 49 | /** | ||
| 50 | * Indicates that the packet sent with this code contains the serialized | ||
| 51 | * signal index cache. | ||
| 52 | */ | ||
| 53 | public static final byte UpdateSignalIndexCache = (byte) 0x83; | ||
| 54 | |||
| 55 | /** | ||
| 56 | * Indicates that the packet sent with this code contains the serialized | ||
| 57 | * base time offsets. | ||
| 58 | */ | ||
| 59 | public static final byte UpdateBaseTimes = (byte) 0x84; | ||
| 60 | |||
| 61 | /** | ||
| 62 | * Indicates that the packet sent with this code contains the cipher keys | ||
| 63 | * used for encryption. | ||
| 64 | */ | ||
| 65 | public static final byte UpdateCipherKeys = (byte) 0x85; | ||
| 66 | |||
| 67 | /** | ||
| 68 | * Indicates that the publisher has started sending measurement data, and | ||
| 69 | * the message includes the server's local time taken when the data stream | ||
| 70 | * was started. | ||
| 71 | */ | ||
| 72 | public static final byte DataStartTime = (byte) 0x86; | ||
| 73 | |||
| 74 | /** | ||
| 75 | * Indicates that a temporal session has been completed. | ||
| 76 | */ | ||
| 77 | public static final byte ProcessingComplete = (byte) 0x87; | ||
| 78 | |||
| 79 | /** | ||
| 80 | * Indicates that no action should be taken by the subscriber. | ||
| 81 | * This message is sent periodically by the publisher over the | ||
| 82 | * command channel in order to verify that the connection is | ||
| 83 | * still open. | ||
| 84 | */ | ||
| 85 | public static final byte NoOP = (byte) 0xFF; | ||
| 86 | } | ||
| @@ -0,0 +1,66 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // MeasurementEvent.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/16/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport.event; | ||
| 25 | |||
| 26 | import java.util.Collection; | ||
| 27 | import java.util.Collections; | ||
| 28 | import java.util.EventObject; | ||
| 29 | |||
| 30 | import org.gpa.gsf.timeseries.Measurement; | ||
| 31 | |||
| 32 | /** | ||
| 33 | * Event that occurs when new measurements are received from the publisher. | ||
| 34 | */ | ||
| 35 | public class MeasurementEvent extends EventObject | ||
| 36 | { | ||
| 37 | private Collection<Measurement> m_measurements; | ||
| 38 | |||
| 39 | /** | ||
| 40 | * Constructs a new instance. | ||
| 41 | * | ||
| 42 | * @param source the source of the event | ||
| 43 | * @param measurements the new measurements received from the publisher | ||
| 44 | */ | ||
| 45 | public MeasurementEvent(Object source, Collection<Measurement> measurements) | ||
| 46 | { | ||
| 47 | super(source); | ||
| 48 | |||
| 49 | if (measurements == null) | ||
| 50 | throw new IllegalArgumentException("measurements cannot be null"); | ||
| 51 | |||
| 52 | m_measurements = Collections.unmodifiableCollection(measurements); | ||
| 53 | } | ||
| 54 | |||
| 55 | /** | ||
| 56 | * Gets the measurements that were received from the publisher. | ||
| 57 | * | ||
| 58 | * @return the measurements received from the publisher | ||
| 59 | */ | ||
| 60 | public Collection<Measurement> getMeasurements() | ||
| 61 | { | ||
| 62 | return m_measurements; | ||
| 63 | } | ||
| 64 | |||
| 65 | private static final long serialVersionUID = 5788181880673812873L; | ||
| 66 | } | ||
| @@ -0,0 +1,86 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // MessageEvent.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/16/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport.event; | ||
| 25 | |||
| 26 | import java.util.EventObject; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * Event that occurs when the subscriber | ||
| 30 | * needs to expose a message to the user. | ||
| 31 | */ | ||
| 32 | public class MessageEvent extends EventObject | ||
| 33 | { | ||
| 34 | private String m_message; | ||
| 35 | private Exception m_exception; | ||
| 36 | |||
| 37 | /** | ||
| 38 | * Constructs a new instance. | ||
| 39 | * | ||
| 40 | * @param source the source of the message | ||
| 41 | * @param message the message to be exposed | ||
| 42 | */ | ||
| 43 | public MessageEvent(Object source, String message) | ||
| 44 | { | ||
| 45 | super(source); | ||
| 46 | m_message = message; | ||
| 47 | } | ||
| 48 | |||
| 49 | /** | ||
| 50 | * Constructs a new instance associated with an exception. | ||
| 51 | * | ||
| 52 | * @param source the source of the exception | ||
| 53 | * @param exception the exception to be exposed | ||
| 54 | */ | ||
| 55 | public MessageEvent(Object source, Exception exception) | ||
| 56 | { | ||
| 57 | this(source, exception.getMessage()); | ||
| 58 | m_exception = exception; | ||
| 59 | } | ||
| 60 | |||
| 61 | /** | ||
| 62 | * Gets the message to be exposed to the user. If this | ||
| 63 | * {@code MessageEvent} is associated with an exception, | ||
| 64 | * this is equivalent to calling {@code getException().getMessage()}. | ||
| 65 | * | ||
| 66 | * @return the message to be exposed to the user | ||
| 67 | */ | ||
| 68 | public String getMessage() | ||
| 69 | { | ||
| 70 | return m_message; | ||
| 71 | } | ||
| 72 | |||
| 73 | /** | ||
| 74 | * Gets the exception associated with this | ||
| 75 | * message event, or null if there is none. | ||
| 76 | * | ||
| 77 | * @return the exception associated with the message event, | ||
| 78 | * if there is one | ||
| 79 | */ | ||
| 80 | public Exception getException() | ||
| 81 | { | ||
| 82 | return m_exception; | ||
| 83 | } | ||
| 84 | |||
| 85 | private static final long serialVersionUID = -6228918892670504322L; | ||
| 86 | } | ||
| @@ -0,0 +1,91 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // MetadataEvent.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/16/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport.event; | ||
| 25 | |||
| 26 | import java.util.EventObject; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * Event that occurs when the subscriber receives metadata from the publisher. | ||
| 30 | */ | ||
| 31 | public class MetadataEvent extends EventObject | ||
| 32 | { | ||
| 33 | private byte[] m_compressedMetadata; | ||
| 34 | private String m_xmlMetadata; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * Constructs a new instance. | ||
| 38 | * | ||
| 39 | * @param source the source of the event | ||
| 40 | * @param compressedMetadata the compressed metadata | ||
| 41 | */ | ||
| 42 | public MetadataEvent(Object source, byte[] compressedMetadata) | ||
| 43 | { | ||
| 44 | super(source); | ||
| 45 | |||
| 46 | if (compressedMetadata == null) | ||
| 47 | throw new IllegalArgumentException("compressedMetadata cannot be null"); | ||
| 48 | |||
| 49 | m_compressedMetadata = compressedMetadata; | ||
| 50 | } | ||
| 51 | |||
| 52 | /** | ||
| 53 | * Constructs a new instance. | ||
| 54 | * | ||
| 55 | * @param source the source of the event | ||
| 56 | * @param xmlMetadata the uncompressed metadata | ||
| 57 | */ | ||
| 58 | public MetadataEvent(Object source, String xmlMetadata) | ||
| 59 | { | ||
| 60 | super(source); | ||
| 61 | |||
| 62 | if (xmlMetadata == null) | ||
| 63 | throw new IllegalArgumentException("xmlMetadata cannot be null"); | ||
| 64 | |||
| 65 | m_xmlMetadata = xmlMetadata; | ||
| 66 | } | ||
| 67 | |||
| 68 | /** | ||
| 69 | * Gets the compressed metadata received from the publisher. | ||
| 70 | * If the metadata received was uncompressed, this will return null. | ||
| 71 | * | ||
| 72 | * @return byte array containing the compressed metadata | ||
| 73 | */ | ||
| 74 | public byte[] getCompressedMetadata() | ||
| 75 | { | ||
| 76 | return m_compressedMetadata; | ||
| 77 | } | ||
| 78 | |||
| 79 | /** | ||
| 80 | * Gets the uncompressed metadata received from the publisher. | ||
| 81 | * If the metadata received was compressed, this will return null. | ||
| 82 | * | ||
| 83 | * @return the uncompressed XML metadata | ||
| 84 | */ | ||
| 85 | public String getXmlMetadata() | ||
| 86 | { | ||
| 87 | return m_xmlMetadata; | ||
| 88 | } | ||
| 89 | |||
| 90 | private static final long serialVersionUID = -1703909541078304245L; | ||
| 91 | } | ||
| @@ -0,0 +1,59 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // SubscriberEvent.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/16/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport.event; | ||
| 25 | |||
| 26 | import java.util.EventObject; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * Event that occurs when the subscriber receives | ||
| 30 | * the data start time from the publisher. | ||
| 31 | */ | ||
| 32 | public class StartTimeEvent extends EventObject | ||
| 33 | { | ||
| 34 | private long m_dataStartTime; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * Constructs a new instance with the given data start time. | ||
| 38 | * | ||
| 39 | * @param source the source of the event | ||
| 40 | * @param dataStartTime the data start time received from the publisher | ||
| 41 | */ | ||
| 42 | public StartTimeEvent(Object source, long dataStartTime) | ||
| 43 | { | ||
| 44 | super(source); | ||
| 45 | m_dataStartTime = dataStartTime; | ||
| 46 | } | ||
| 47 | |||
| 48 | /** | ||
| 49 | * Gets the data start time received from the publisher. | ||
| 50 | * | ||
| 51 | * @return the data start time | ||
| 52 | */ | ||
| 53 | public long getDataStartTime() | ||
| 54 | { | ||
| 55 | return m_dataStartTime; | ||
| 56 | } | ||
| 57 | |||
| 58 | private static final long serialVersionUID = -3551015702900244809L; | ||
| 59 | } | ||
| @@ -0,0 +1,69 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // SubscriberAdapter.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/16/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport.event; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * An abstract adapter class for receiving subscriber events. The | ||
| 28 | * methods in this class are empty. This class exists as convenience | ||
| 29 | * for creating listener objects. | ||
| 30 | */ | ||
| 31 | public class SubscriberAdapter implements SubscriberListener | ||
| 32 | { | ||
| 33 | |||
| 34 | @Override | ||
| 35 | public void statusMessageReceived(MessageEvent evt) | ||
| 36 | { | ||
| 37 | } | ||
| 38 | |||
| 39 | @Override | ||
| 40 | public void exceptionEncountered(MessageEvent evt) | ||
| 41 | { | ||
| 42 | } | ||
| 43 | |||
| 44 | @Override | ||
| 45 | public void dataStartTimeReceived(StartTimeEvent evt) | ||
| 46 | { | ||
| 47 | } | ||
| 48 | |||
| 49 | @Override | ||
| 50 | public void metadataReceived(MetadataEvent evt) | ||
| 51 | { | ||
| 52 | } | ||
| 53 | |||
| 54 | @Override | ||
| 55 | public void newMeasurementsReceived(MeasurementEvent evt) | ||
| 56 | { | ||
| 57 | } | ||
| 58 | |||
| 59 | @Override | ||
| 60 | public void processingCompleteCallback(MessageEvent evt) | ||
| 61 | { | ||
| 62 | } | ||
| 63 | |||
| 64 | @Override | ||
| 65 | public void connectionTerminated(MessageEvent evt) | ||
| 66 | { | ||
| 67 | } | ||
| 68 | |||
| 69 | } | ||
| @@ -0,0 +1,44 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // SubscriberConnectorAdapter.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/23/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport.event; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * An abstract adapter class for receiving subscriber connector events. | ||
| 28 | * The methods in this class are empty. This class exists as convenience | ||
| 29 | * for creating listener objects. | ||
| 30 | */ | ||
| 31 | public class SubscriberConnectorAdapter implements SubscriberConnectorListener | ||
| 32 | { | ||
| 33 | |||
| 34 | @Override | ||
| 35 | public void exceptionEncountered(MessageEvent evt) | ||
| 36 | { | ||
| 37 | } | ||
| 38 | |||
| 39 | @Override | ||
| 40 | public void reconnected(SubscriberEvent evt) | ||
| 41 | { | ||
| 42 | } | ||
| 43 | |||
| 44 | } | ||
| @@ -0,0 +1,47 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // SubscriberConnectorListener.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/23/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport.event; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * Interface which defines callbacks for the {@link SubscriberConnector}. | ||
| 28 | */ | ||
| 29 | public interface SubscriberConnectorListener | ||
| 30 | { | ||
| 31 | /** | ||
| 32 | * Called when an exception is encountered | ||
| 33 | * by the {@code SubscriberConnector}. | ||
| 34 | * | ||
| 35 | * @param evt the event which contains the exception | ||
| 36 | */ | ||
| 37 | void exceptionEncountered(MessageEvent evt); | ||
| 38 | |||
| 39 | /** | ||
| 40 | * Occurs when the subscriber is automatically | ||
| 41 | * reconnected by the {@code SubscriberConnector}. | ||
| 42 | * | ||
| 43 | * @param evt the event which contains the subscriber | ||
| 44 | * that was reconnected | ||
| 45 | */ | ||
| 46 | void reconnected(SubscriberEvent evt); | ||
| 47 | } | ||
| @@ -0,0 +1,60 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // SubscriberEvent.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/23/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport.event; | ||
| 25 | |||
| 26 | import java.util.EventObject; | ||
| 27 | |||
| 28 | import org.gpa.gsf.timeseries.transport.DataSubscriber; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * Generic event associated with a subscriber. | ||
| 32 | */ | ||
| 33 | public class SubscriberEvent extends EventObject | ||
| 34 | { | ||
| 35 | private DataSubscriber m_subscriber; | ||
| 36 | |||
| 37 | /** | ||
| 38 | * Constructs a new instance. | ||
| 39 | * | ||
| 40 | * @param source the source of the event | ||
| 41 | * @param subscriber the subscriber associated with the event | ||
| 42 | */ | ||
| 43 | public SubscriberEvent(Object source, DataSubscriber subscriber) | ||
| 44 | { | ||
| 45 | super(source); | ||
| 46 | m_subscriber = subscriber; | ||
| 47 | } | ||
| 48 | |||
| 49 | /** | ||
| 50 | * Gets the subscriber associated with the event. | ||
| 51 | * | ||
| 52 | * @return the subscriber associated with the event | ||
| 53 | */ | ||
| 54 | public DataSubscriber getSubscriber() | ||
| 55 | { | ||
| 56 | return m_subscriber; | ||
| 57 | } | ||
| 58 | |||
| 59 | private static final long serialVersionUID = -1854428244027543102L; | ||
| 60 | } | ||
| @@ -0,0 +1,90 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // SubscriberListener.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/16/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.transport.event; | ||
| 25 | |||
| 26 | import org.gpa.gsf.timeseries.transport.DataSubscriber; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * Interface which defines the callbacks | ||
| 30 | * used by the subscriber to handle events. | ||
| 31 | * | ||
| 32 | * @see DataSubscriber | ||
| 33 | * @see DataSubscriber#addSubscriberListener(SubscriberListener) | ||
| 34 | */ | ||
| 35 | public interface SubscriberListener | ||
| 36 | { | ||
| 37 | /** | ||
| 38 | * Occurs when the subscriber wishes to | ||
| 39 | * expose a status message to the user. | ||
| 40 | * | ||
| 41 | * @param evt the message event which contains the status message | ||
| 42 | */ | ||
| 43 | void statusMessageReceived(MessageEvent evt); | ||
| 44 | |||
| 45 | /** | ||
| 46 | * Occurs when the subscriber encounters an exception. | ||
| 47 | * | ||
| 48 | * @param evt the message event which contains the exception encountered | ||
| 49 | */ | ||
| 50 | void exceptionEncountered(MessageEvent evt); | ||
| 51 | |||
| 52 | /** | ||
| 53 | * Occurs when the data start time is received from the publisher. | ||
| 54 | * | ||
| 55 | * @param evt the event which contains the data start time received | ||
| 56 | */ | ||
| 57 | void dataStartTimeReceived(StartTimeEvent evt); | ||
| 58 | |||
| 59 | /** | ||
| 60 | * Occurs when metadata is received from the publisher. | ||
| 61 | * | ||
| 62 | * @param evt the metadata event which contains the metadata received | ||
| 63 | */ | ||
| 64 | void metadataReceived(MetadataEvent evt); | ||
| 65 | |||
| 66 | /** | ||
| 67 | * Occurs when a new collection of measurements | ||
| 68 | * are received from the publisher. | ||
| 69 | * | ||
| 70 | * @param evt the collection of measurements received | ||
| 71 | */ | ||
| 72 | void newMeasurementsReceived(MeasurementEvent evt); | ||
| 73 | |||
| 74 | /** | ||
| 75 | * Occurs when the publisher notifies the subscriber | ||
| 76 | * that a temporal session has been completed. | ||
| 77 | * | ||
| 78 | * @param evt the event which contains a message from the publisher | ||
| 79 | */ | ||
| 80 | void processingCompleteCallback(MessageEvent evt); | ||
| 81 | |||
| 82 | /** | ||
| 83 | * Occurs when the TCP connection between the publisher | ||
| 84 | * and subscriber is terminated unexpectedly. | ||
| 85 | * | ||
| 86 | * @param evt the event which contains an exception that occurred as | ||
| 87 | * a result of the connection termination | ||
| 88 | */ | ||
| 89 | void connectionTerminated(MessageEvent evt); | ||
| 90 | } | ||
| @@ -0,0 +1,195 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // ArrayExtensions.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/18/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.util; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * Utility class that provides additional functionality for arrays. | ||
| 28 | */ | ||
| 29 | public class ArrayExtensions | ||
| 30 | { | ||
| 31 | /** | ||
| 32 | * Copies the specified number of bytes from the source array to the | ||
| 33 | * destination array, starting from the given offsets in each array. | ||
| 34 | * | ||
| 35 | * @param source the source array | ||
| 36 | * @param srcOffset the offset into the source array where the data | ||
| 37 | * to be copied starts | ||
| 38 | * @param dest the destination array | ||
| 39 | * @param destOffset the offset into the destination array where the | ||
| 40 | * data is to be copied | ||
| 41 | * @param length the amount of data to be copied | ||
| 42 | */ | ||
| 43 | public static void blockCopy(byte[] source, int srcOffset, byte[] dest, int destOffset, int length) | ||
| 44 | { | ||
| 45 | for (int i = 0; i < length; i++) | ||
| 46 | dest[destOffset + i] = source[srcOffset + i]; | ||
| 47 | } | ||
| 48 | |||
| 49 | /** | ||
| 50 | * Copies the specified number of short integers from the source array | ||
| 51 | * to the destination array, starting from the given offsets in each | ||
| 52 | * array. | ||
| 53 | * | ||
| 54 | * @param source the source array | ||
| 55 | * @param srcOffset the offset into the source array where the data | ||
| 56 | * to be copied starts | ||
| 57 | * @param dest the destination array | ||
| 58 | * @param destOffset the offset into the destination array where the | ||
| 59 | * data is to be copied | ||
| 60 | * @param length the amount of data to be copied | ||
| 61 | */ | ||
| 62 | public static void blockCopy(short[] source, int srcOffset, short[] dest, int destOffset, int length) | ||
| 63 | { | ||
| 64 | for (int i = 0; i < length; i++) | ||
| 65 | dest[destOffset + i] = source[srcOffset + i]; | ||
| 66 | } | ||
| 67 | |||
| 68 | /** | ||
| 69 | * Copies the specified number of integers from the source array to the | ||
| 70 | * destination array, starting from the given offsets in each array. | ||
| 71 | * | ||
| 72 | * @param source the source array | ||
| 73 | * @param srcOffset the offset into the source array where the data | ||
| 74 | * to be copied starts | ||
| 75 | * @param dest the destination array | ||
| 76 | * @param destOffset the offset into the destination array where the | ||
| 77 | * data is to be copied | ||
| 78 | * @param length the amount of data to be copied | ||
| 79 | */ | ||
| 80 | public static void blockCopy(int[] source, int srcOffset, int[] dest, int destOffset, int length) | ||
| 81 | { | ||
| 82 | for (int i = 0; i < length; i++) | ||
| 83 | dest[destOffset + i] = source[srcOffset + i]; | ||
| 84 | } | ||
| 85 | |||
| 86 | /** | ||
| 87 | * Copies the specified number of long integers from the source array | ||
| 88 | * to the destination array, starting from the given offsets in each | ||
| 89 | * array. | ||
| 90 | * | ||
| 91 | * @param source the source array | ||
| 92 | * @param srcOffset the offset into the source array where the data | ||
| 93 | * to be copied starts | ||
| 94 | * @param dest the destination array | ||
| 95 | * @param destOffset the offset into the destination array where the | ||
| 96 | * data is to be copied | ||
| 97 | * @param length the amount of data to be copied | ||
| 98 | */ | ||
| 99 | public static void blockCopy(long[] source, int srcOffset, long[] dest, int destOffset, int length) | ||
| 100 | { | ||
| 101 | for (int i = 0; i < length; i++) | ||
| 102 | dest[destOffset + i] = source[srcOffset + i]; | ||
| 103 | } | ||
| 104 | |||
| 105 | /** | ||
| 106 | * Copies the specified number of floats from the source array to the | ||
| 107 | * destination array, starting from the given offsets in each array. | ||
| 108 | * | ||
| 109 | * @param source the source array | ||
| 110 | * @param srcOffset the offset into the source array where the data | ||
| 111 | * to be copied starts | ||
| 112 | * @param dest the destination array | ||
| 113 | * @param destOffset the offset into the destination array where the | ||
| 114 | * data is to be copied | ||
| 115 | * @param length the amount of data to be copied | ||
| 116 | */ | ||
| 117 | public static void blockCopy(float[] source, int srcOffset, float[] dest, int destOffset, int length) | ||
| 118 | { | ||
| 119 | for (int i = 0; i < length; i++) | ||
| 120 | dest[destOffset + i] = source[srcOffset + i]; | ||
| 121 | } | ||
| 122 | |||
| 123 | /** | ||
| 124 | * Copies the specified number of doubles from the source array to the | ||
| 125 | * destination array, starting from the given offsets in each array. | ||
| 126 | * | ||
| 127 | * @param source the source array | ||
| 128 | * @param srcOffset the offset into the source array where the data | ||
| 129 | * to be copied starts | ||
| 130 | * @param dest the destination array | ||
| 131 | * @param destOffset the offset into the destination array where the | ||
| 132 | * data is to be copied | ||
| 133 | * @param length the amount of data to be copied | ||
| 134 | */ | ||
| 135 | public static void blockCopy(double[] source, int srcOffset, double[] dest, int destOffset, int length) | ||
| 136 | { | ||
| 137 | for (int i = 0; i < length; i++) | ||
| 138 | dest[destOffset + i] = source[srcOffset + i]; | ||
| 139 | } | ||
| 140 | |||
| 141 | /** | ||
| 142 | * Copies the specified number of boolean values from the source array | ||
| 143 | * to the destination array, starting from the given offsets in each | ||
| 144 | * array. | ||
| 145 | * | ||
| 146 | * @param source the source array | ||
| 147 | * @param srcOffset the offset into the source array where the data | ||
| 148 | * to be copied starts | ||
| 149 | * @param dest the destination array | ||
| 150 | * @param destOffset the offset into the destination array where the | ||
| 151 | * data is to be copied | ||
| 152 | * @param length the amount of data to be copied | ||
| 153 | */ | ||
| 154 | public static void blockCopy(boolean[] source, int srcOffset, boolean[] dest, int destOffset, int length) | ||
| 155 | { | ||
| 156 | for (int i = 0; i < length; i++) | ||
| 157 | dest[destOffset + i] = source[srcOffset + i]; | ||
| 158 | } | ||
| 159 | |||
| 160 | /** | ||
| 161 | * Copies the specified number of characters from the source array to the | ||
| 162 | * destination array, starting from the given offsets in each array. | ||
| 163 | * | ||
| 164 | * @param source the source array | ||
| 165 | * @param srcOffset the offset into the source array where the data | ||
| 166 | * to be copied starts | ||
| 167 | * @param dest the destination array | ||
| 168 | * @param destOffset the offset into the destination array where the | ||
| 169 | * data is to be copied | ||
| 170 | * @param length the amount of data to be copied | ||
| 171 | */ | ||
| 172 | public static void blockCopy(char[] source, int srcOffset, char[] dest, int destOffset, int length) | ||
| 173 | { | ||
| 174 | for (int i = 0; i < length; i++) | ||
| 175 | dest[destOffset + i] = source[srcOffset + i]; | ||
| 176 | } | ||
| 177 | |||
| 178 | /** | ||
| 179 | * Copies the specified number of objects from the source array to the | ||
| 180 | * destination array, starting from the given offsets in each array. | ||
| 181 | * | ||
| 182 | * @param source the source array | ||
| 183 | * @param srcOffset the offset into the source array where the data | ||
| 184 | * to be copied starts | ||
| 185 | * @param dest the destination array | ||
| 186 | * @param destOffset the offset into the destination array where the | ||
| 187 | * data is to be copied | ||
| 188 | * @param length the amount of data to be copied | ||
| 189 | */ | ||
| 190 | public static <T> void blockCopy(T[] source, int srcOffset, T[] dest, int destOffset, int length) | ||
| 191 | { | ||
| 192 | for (int i = 0; i < length; i++) | ||
| 193 | dest[destOffset + i] = source[srcOffset + i]; | ||
| 194 | } | ||
| 195 | } | ||
| @@ -0,0 +1,73 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // InputStreamExtensions.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/16/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.util; | ||
| 25 | |||
| 26 | import java.io.BufferedInputStream; | ||
| 27 | import java.io.IOException; | ||
| 28 | import java.io.InputStream; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * Utility class that provides additional functionality for input streams. | ||
| 32 | * | ||
| 33 | * @author Stephen C. Wills | ||
| 34 | */ | ||
| 35 | public class InputStreamExtensions | ||
| 36 | { | ||
| 37 | /** | ||
| 38 | * This read method works approximately the same as the | ||
| 39 | * {@link BufferedInputStream#read(byte[], int, int)} method. | ||
| 40 | * The main difference is that this method will block until the | ||
| 41 | * requested amount of data is read from the input stream or the | ||
| 42 | * end of the stream has been reached, whereas BufferedInputStream | ||
| 43 | * will try to avoid blocking by checking the {@code available()} | ||
| 44 | * method of the underlying stream. | ||
| 45 | * | ||
| 46 | * @param stream source of the data | ||
| 47 | * @param buffer destination buffer | ||
| 48 | * @param offset offset at which to start storing bytes | ||
| 49 | * @param length requested number of bytes | ||
| 50 | * @return the number of bytes read from the stream, or -1 if the end of the stream has been reached | ||
| 51 | * @throws IOException if this input stream has been closed by invoking its | ||
| 52 | * {@link InputStream#close()} method, or an I/O error occurs | ||
| 53 | * @see java.io.BufferedInputStream | ||
| 54 | */ | ||
| 55 | public static int read(InputStream stream, byte[] buffer, int offset, int length) throws IOException | ||
| 56 | { | ||
| 57 | int index = offset; | ||
| 58 | int readAmount = 0; | ||
| 59 | int totalReadAmount = 0; | ||
| 60 | |||
| 61 | while (readAmount >= 0 && totalReadAmount < length) | ||
| 62 | { | ||
| 63 | readAmount = stream.read(buffer, index, length - readAmount); | ||
| 64 | index += readAmount; | ||
| 65 | totalReadAmount += readAmount; | ||
| 66 | } | ||
| 67 | |||
| 68 | if (readAmount < 0 && totalReadAmount == 0) | ||
| 69 | totalReadAmount = -1; | ||
| 70 | |||
| 71 | return totalReadAmount; | ||
| 72 | } | ||
| 73 | } | ||
| @@ -0,0 +1,92 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // Masks.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/12/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.util; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * Utility class to properly generate masks for different sizes of integers. | ||
| 28 | * | ||
| 29 | * @author Stephen C. Wills | ||
| 30 | */ | ||
| 31 | public class Masks | ||
| 32 | { | ||
| 33 | /** | ||
| 34 | * Gets a 64-bit integer mask with the given | ||
| 35 | * number of least significant bits turned on. | ||
| 36 | * | ||
| 37 | * @param numberOfOnBits The number of bits to be turned on. | ||
| 38 | * @return a 64-bit integer mask | ||
| 39 | */ | ||
| 40 | public static long getLongMask(int numberOfOnBits) | ||
| 41 | { | ||
| 42 | if(numberOfOnBits < 0 || numberOfOnBits > Long.SIZE) | ||
| 43 | throw new IllegalArgumentException("Number of masked bits must be between 0 and " + Long.SIZE); | ||
| 44 | |||
| 45 | return ~(~0L << numberOfOnBits); | ||
| 46 | } | ||
| 47 | |||
| 48 | /** | ||
| 49 | * Gets a 32-bit integer mask with the given | ||
| 50 | * number of least significant bits turned on. | ||
| 51 | * | ||
| 52 | * @param numberOfOnBits The number of bits to be turned on. | ||
| 53 | * @return a 32-bit integer mask | ||
| 54 | */ | ||
| 55 | public static int getIntMask(int numberOfOnBits) | ||
| 56 | { | ||
| 57 | if(numberOfOnBits < 0 || numberOfOnBits > Integer.SIZE) | ||
| 58 | throw new IllegalArgumentException("Number of masked bits must be between 0 and " + Integer.SIZE); | ||
| 59 | |||
| 60 | return ~(~0 << numberOfOnBits); | ||
| 61 | } | ||
| 62 | |||
| 63 | /** | ||
| 64 | * Gets a 16-bit integer mask with the given | ||
| 65 | * number of least significant bits turned on. | ||
| 66 | * | ||
| 67 | * @param numberOfOnBits The number of bits to be turned on. | ||
| 68 | * @return a 16-bit integer mask | ||
| 69 | */ | ||
| 70 | public static short getShortMask(int numberOfOnBits) | ||
| 71 | { | ||
| 72 | if(numberOfOnBits < 0 || numberOfOnBits > Short.SIZE) | ||
| 73 | throw new IllegalArgumentException("Number of masked bits must be between 0 and " + Short.SIZE); | ||
| 74 | |||
| 75 | return (short)getIntMask(numberOfOnBits); | ||
| 76 | } | ||
| 77 | |||
| 78 | /** | ||
| 79 | * Gets a 8-bit integer mask with the given | ||
| 80 | * number of least significant bits turned on. | ||
| 81 | * | ||
| 82 | * @param numberOfOnBits The number of bits to be turned on. | ||
| 83 | * @return a 8-bit integer mask | ||
| 84 | */ | ||
| 85 | public static byte getByteMask(int numberOfOnBits) | ||
| 86 | { | ||
| 87 | if(numberOfOnBits < 0 || numberOfOnBits > Byte.SIZE) | ||
| 88 | throw new IllegalArgumentException("Number of masked bits must be between 0 and " + Byte.SIZE); | ||
| 89 | |||
| 90 | return (byte)getIntMask(numberOfOnBits); | ||
| 91 | } | ||
| 92 | } | ||
| @@ -0,0 +1,132 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // NumberExtensions.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/12/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.util; | ||
| 25 | |||
| 26 | import java.math.BigInteger; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * Utility class that provides additional functionality for numbers. | ||
| 30 | * | ||
| 31 | * @author Stephen C. Wills | ||
| 32 | */ | ||
| 33 | public class NumberExtensions | ||
| 34 | { | ||
| 35 | /** | ||
| 36 | * Gets a string representation of a long integer | ||
| 37 | * in base 10 as if it were an unsigned long integer. | ||
| 38 | * | ||
| 39 | * @param num the long integer to be converted to a string | ||
| 40 | * @return a string representation of the given long integer | ||
| 41 | * @see Long#toString(long) | ||
| 42 | */ | ||
| 43 | public static String toUnsignedString(long num) | ||
| 44 | { | ||
| 45 | return toUnsignedString(num, 10); | ||
| 46 | } | ||
| 47 | |||
| 48 | /** | ||
| 49 | * Gets a string representation of a long integer | ||
| 50 | * as if it were an unsigned long integer. | ||
| 51 | * | ||
| 52 | * @param num the long integer to be converted to a string | ||
| 53 | * @param radix the radix to use in the string representation | ||
| 54 | * @return a string representation of the given long integer | ||
| 55 | * @see Long#toString(long, int) | ||
| 56 | */ | ||
| 57 | public static String toUnsignedString(long num, int radix) | ||
| 58 | { | ||
| 59 | BigInteger bigNum; | ||
| 60 | BigInteger bigMod; | ||
| 61 | |||
| 62 | if (num > 0L) | ||
| 63 | return Long.toString(radix); | ||
| 64 | |||
| 65 | bigNum = BigInteger.valueOf(num >>> 1); | ||
| 66 | bigMod = BigInteger.valueOf(num & 1L); | ||
| 67 | |||
| 68 | return bigNum.shiftLeft(1).add(bigMod).toString(radix); | ||
| 69 | } | ||
| 70 | |||
| 71 | /** | ||
| 72 | * Gets a string representation of an integer in | ||
| 73 | * base 10 as if it were an unsigned integer. | ||
| 74 | * | ||
| 75 | * @param num the integer to be converted to a string | ||
| 76 | * @return a string representation of the given integer | ||
| 77 | * @see Integer#toString(int) | ||
| 78 | */ | ||
| 79 | public static String toUnsignedString(int num) | ||
| 80 | { | ||
| 81 | return toUnsignedString(num, 10); | ||
| 82 | } | ||
| 83 | |||
| 84 | /** | ||
| 85 | * Gets a string representation of an integer | ||
| 86 | * as if it were an unsigned integer. | ||
| 87 | * | ||
| 88 | * @param num the integer to be converted to a string | ||
| 89 | * @param radix the radix to use in the string representation | ||
| 90 | * @return a string representation of the given integer | ||
| 91 | * @see Integer#toString(int, int) | ||
| 92 | */ | ||
| 93 | public static String toUnsignedString(int num, int radix) | ||
| 94 | { | ||
| 95 | if (num > 0) | ||
| 96 | return Integer.toString(num, radix); | ||
| 97 | |||
| 98 | return Long.toString(num & Masks.getLongMask(Integer.SIZE), radix); | ||
| 99 | } | ||
| 100 | |||
| 101 | /** | ||
| 102 | * Gets a string representation of a short integer | ||
| 103 | * in base 10 as if it were an unsigned short integer. | ||
| 104 | * | ||
| 105 | * @param num the short integer to be converted to a string | ||
| 106 | * @return a string representation of the given short integer | ||
| 107 | * @see Short#toString(short) | ||
| 108 | */ | ||
| 109 | public static String toUnsignedString(short num) | ||
| 110 | { | ||
| 111 | if (num > 0) | ||
| 112 | return Short.toString(num); | ||
| 113 | |||
| 114 | return Integer.toString(num & Masks.getIntMask(Short.SIZE)); | ||
| 115 | } | ||
| 116 | |||
| 117 | /** | ||
| 118 | * Gets a string representation of a byte in | ||
| 119 | * base 10 as if it were an unsigned byte. | ||
| 120 | * | ||
| 121 | * @param num the byte to be converted to a string | ||
| 122 | * @return a string representation of the given byte | ||
| 123 | * @see Byte#toString(byte) | ||
| 124 | */ | ||
| 125 | public static String toUnsignedString(byte num) | ||
| 126 | { | ||
| 127 | if (num > 0) | ||
| 128 | return Byte.toString(num); | ||
| 129 | |||
| 130 | return Integer.toString(num & Masks.getIntMask(Byte.SIZE)); | ||
| 131 | } | ||
| 132 | } | ||
| @@ -0,0 +1,88 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // StringExtensions.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/18/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.util; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * Utility class that provides additional functionality for strings. | ||
| 28 | */ | ||
| 29 | public class StringExtensions | ||
| 30 | { | ||
| 31 | /** | ||
| 32 | * Determines whether the given string is null or the empty string. | ||
| 33 | * | ||
| 34 | * @param str the string to be checked | ||
| 35 | * @return true if the string is null or empty; false otherwise | ||
| 36 | */ | ||
| 37 | public static boolean isNullOrEmpty(String str) | ||
| 38 | { | ||
| 39 | return (str == null) || str.isEmpty(); | ||
| 40 | } | ||
| 41 | |||
| 42 | /** | ||
| 43 | * Determines whether the given string is null or contains | ||
| 44 | * nothing but whitespace characters. | ||
| 45 | * | ||
| 46 | * @param str the string to be checked | ||
| 47 | * @return true if the string is null or whitespace; false otherwise | ||
| 48 | */ | ||
| 49 | public static boolean isNullOrWhitespace(String str) | ||
| 50 | { | ||
| 51 | return (str == null) || str.trim().isEmpty(); | ||
| 52 | } | ||
| 53 | |||
| 54 | /** | ||
| 55 | * Converts null strings to the empty string. If a string is provided | ||
| 56 | * which is not null, no operation is performed and the string is | ||
| 57 | * returned as-is. | ||
| 58 | * | ||
| 59 | * @param str the string to be checked | ||
| 60 | * @return the empty string if the parameter is null; otherwise the | ||
| 61 | * parameter itself is returned | ||
| 62 | */ | ||
| 63 | public static String toNonNull(String str) | ||
| 64 | { | ||
| 65 | return toNonNull(str, ""); | ||
| 66 | } | ||
| 67 | |||
| 68 | /** | ||
| 69 | * Converts null strings to the given default string value. If a | ||
| 70 | * string is provided which is not null, no operation is performed | ||
| 71 | * and the string is returned as-is. | ||
| 72 | * | ||
| 73 | * @param str the string to be checked | ||
| 74 | * @param defaultValue the default value to return if the provided | ||
| 75 | * string happens to be null | ||
| 76 | * @return the default value if the first parameter is null; otherwise | ||
| 77 | * the first parameter itself is returned | ||
| 78 | */ | ||
| 79 | public static String toNonNull(String str, String defaultValue) | ||
| 80 | { | ||
| 81 | if (str != null) | ||
| 82 | return str; | ||
| 83 | else if (defaultValue != null) | ||
| 84 | return defaultValue; | ||
| 85 | else | ||
| 86 | return ""; | ||
| 87 | } | ||
| 88 | } | ||
| @@ -0,0 +1,65 @@ | |||
| 1 | //****************************************************************************************************** | ||
| 2 | // TimeExtensions.java - Gbtc | ||
| 3 | // | ||
| 4 | // Copyright � 2010, Grid Protection Alliance. All Rights Reserved. | ||
| 5 | // | ||
| 6 | // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See | ||
| 7 | // the NOTICE file distributed with this work for additional information regarding copyright ownership. | ||
| 8 | // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may | ||
| 9 | // not use this file except in compliance with the License. You may obtain a copy of the License at: | ||
| 10 | // | ||
| 11 | // http://www.opensource.org/licenses/eclipse-1.0.php | ||
| 12 | // | ||
| 13 | // Unless agreed to in writing, the subject software distributed under the License is distributed on an | ||
| 14 | // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the | ||
| 15 | // License for the specific language governing permissions and limitations. | ||
| 16 | // | ||
| 17 | // Code Modification History: | ||
| 18 | // ---------------------------------------------------------------------------------------------------- | ||
| 19 | // 04/23/2012 - Stephen C. Wills | ||
| 20 | // Generated original version of source code. | ||
| 21 | // | ||
| 22 | //****************************************************************************************************** | ||
| 23 | |||
| 24 | package org.gpa.gsf.timeseries.util; | ||
| 25 | |||
| 26 | import java.util.Calendar; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * Utility class which provides additional | ||
| 30 | * functionality for time representations. | ||
| 31 | */ | ||
| 32 | public class TimeExtensions | ||
| 33 | { | ||
| 34 | /** | ||
| 35 | * Converts a value in ticks (100-nanosecond intervals since midnight, | ||
| 36 | * January 1, 0001) into a {@link Calendar} instance. Some loss of | ||
| 37 | * precision is incurred as {@code Calendar}s store up to millisecond | ||
| 38 | * precision. | ||
| 39 | * | ||
| 40 | * @param ticks the value in ticks to be converted | ||
| 41 | * @return the equivalent {@code Calendar} instance | ||
| 42 | * @see #toTicks(Calendar) | ||
| 43 | */ | ||
| 44 | public static Calendar fromTicks(long ticks) | ||
| 45 | { | ||
| 46 | Calendar calendar = Calendar.getInstance(); | ||
| 47 | calendar.setTimeInMillis((ticks - TicksAtEpoch) / TicksPerMillisecond); | ||
| 48 | return calendar; | ||
| 49 | } | ||
| 50 | |||
| 51 | /** | ||
| 52 | * Converts a {@link Calendar} instance into a value in ticks. | ||
| 53 | * | ||
| 54 | * @param calendar the {@code Calendar} instance to be converted | ||
| 55 | * @return the equivalent value in ticks | ||
| 56 | * @see #fromTicks(long) | ||
| 57 | */ | ||
| 58 | public static long toTicks(Calendar calendar) | ||
| 59 | { | ||
| 60 | return (calendar.getTimeInMillis() * TicksPerMillisecond) + TicksAtEpoch; | ||
| 61 | } | ||
| 62 | |||
| 63 | private static final long TicksAtEpoch = 621355968000000000L; | ||
| 64 | private static final long TicksPerMillisecond = 10000L; | ||
| 65 | } | ||