Compare commits

..

No commits in common. "master" and "Release_22" have entirely different histories.

368 changed files with 16335 additions and 8312 deletions

4
.gitignore vendored
View File

@ -8,6 +8,4 @@ asm3.2_*
asm_patch*
libsrc*
*private*
*genfile*
classes/
appengine-generated/
*genfile*

View File

@ -1,17 +1,10 @@
Full details available on the "InTrace Site":http://mchr3k.github.com/org.intrace/
h1. Main Projects
* org.intrace - InTrace Agent and GUI
* intrace.ecl.plugin - InTrace Eclipse Plugin
* intrace.ecl.feature - InTrace Eclipse Feature
* intrace.ecl.site - InTrace Eclipse Update Site
* intrace.appengine - InTrace AppEngine Update Site Hosting
* binaries - jars from InTrace releases
h2. Work in progress
* InTrace-VisualVM - VisualVM integration
* org.intrace.agentbug - Project containing simple Agent used to illustrate bug report to Sun
* org.intrace - InTrace Agent and CUI/GUI
* org.intrace.agentloader - Command line agent loader for loading an agent into a running JVM process
h2. Scratch Projects
* binaries - images and jars used by wiki pages
* org.intrace.agentbug - Project containing simple Agent used to illustrate bug report to Sun
* org.intrace.test - Dumping ground for toy classes used in manual testing

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="lib" path="emma.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1,14 @@
# Verbosity level for Emma
com.mountainminds.eclemma.core/debug/emmaVerbosityLevel=info
# Enable trace output for performance (time/memory)
com.mountainminds.eclemma.core/debug/performance=true
# Enable trace output for instrumentation
com.mountainminds.eclemma.core/debug/instrumentation=true
# Enable trace output for coverage launching
com.mountainminds.eclemma.core/debug/launching=true
# Enable trace output for coverage analysis
com.mountainminds.eclemma.core/debug/analysis=true

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.mountainminds.eclemma.core</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,326 @@
#Thu Jan 29 21:39:30 CET 2009
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.4
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
org.eclipse.jdt.core.compiler.problem.deprecation=warning
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
org.eclipse.jdt.core.compiler.problem.nullReference=warning
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.source=1.3
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
org.eclipse.jdt.core.formatter.comment.format_header=false
org.eclipse.jdt.core.formatter.comment.format_html=true
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
org.eclipse.jdt.core.formatter.comment.format_source_code=true
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
org.eclipse.jdt.core.formatter.comment.line_length=80
org.eclipse.jdt.core.formatter.compact_else_if=true
org.eclipse.jdt.core.formatter.continuation_indentation=2
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_empty_lines=false
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
org.eclipse.jdt.core.formatter.indentation.size=4
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
org.eclipse.jdt.core.formatter.lineSplit=80
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.jdt.core.formatter.tabulation.char=space
org.eclipse.jdt.core.formatter.tabulation.size=2
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true

View File

@ -0,0 +1,56 @@
#Sat Jan 24 15:41:03 CET 2009
eclipse.preferences.version=1
editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
formatter_profile=_EclEmma
formatter_settings_version=11
sp_cleanup.add_default_serial_version_id=true
sp_cleanup.add_generated_serial_version_id=false
sp_cleanup.add_missing_annotations=true
sp_cleanup.add_missing_deprecated_annotations=true
sp_cleanup.add_missing_methods=false
sp_cleanup.add_missing_nls_tags=false
sp_cleanup.add_missing_override_annotations=true
sp_cleanup.add_serial_version_id=false
sp_cleanup.always_use_blocks=true
sp_cleanup.always_use_parentheses_in_expressions=false
sp_cleanup.always_use_this_for_non_static_field_access=false
sp_cleanup.always_use_this_for_non_static_method_access=false
sp_cleanup.convert_to_enhanced_for_loop=false
sp_cleanup.correct_indentation=false
sp_cleanup.format_source_code=true
sp_cleanup.format_source_code_changes_only=false
sp_cleanup.make_local_variable_final=false
sp_cleanup.make_parameters_final=false
sp_cleanup.make_private_fields_final=true
sp_cleanup.make_type_abstract_if_missing_method=false
sp_cleanup.make_variable_declarations_final=true
sp_cleanup.never_use_blocks=false
sp_cleanup.never_use_parentheses_in_expressions=true
sp_cleanup.on_save_use_additional_actions=false
sp_cleanup.organize_imports=true
sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
sp_cleanup.remove_private_constructors=true
sp_cleanup.remove_trailing_whitespaces=false
sp_cleanup.remove_trailing_whitespaces_all=true
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
sp_cleanup.remove_unnecessary_casts=true
sp_cleanup.remove_unnecessary_nls_tags=false
sp_cleanup.remove_unused_imports=false
sp_cleanup.remove_unused_local_variables=false
sp_cleanup.remove_unused_private_fields=true
sp_cleanup.remove_unused_private_members=false
sp_cleanup.remove_unused_private_methods=true
sp_cleanup.remove_unused_private_types=true
sp_cleanup.sort_members=false
sp_cleanup.sort_members_all=false
sp_cleanup.use_blocks=false
sp_cleanup.use_blocks_only_for_return_and_throw=false
sp_cleanup.use_parentheses_in_expressions=false
sp_cleanup.use_this_for_non_static_field_access=false
sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
sp_cleanup.use_this_for_non_static_method_access=false
sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true

View File

@ -0,0 +1,21 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: com.mountainminds.eclemma.core; singleton:=true
Bundle-Version: 1.5.2
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Export-Package: com.mountainminds.eclemma.core,
com.mountainminds.eclemma.core.analysis,
com.mountainminds.eclemma.core.launching
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.core.resources,
org.eclipse.debug.core,
org.eclipse.jdt.core,
org.eclipse.jdt.launching
Bundle-ClassPath: .,
emma.jar
Bundle-Activator: com.mountainminds.eclemma.internal.core.EclEmmaCorePlugin
Eclipse-AutoStart: true

View File

@ -0,0 +1,35 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<title>About</title>
<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
</head>
<body lang="EN-US">
<h2>About This Content</h2>
<p>
EclEmma is a free Java code coverage tool for Eclipse implemented by Marc R.
Hoffmann. It is based on <a href="http://emma.sourceforge.net/">EMMA</a>
by Vlad Roubtsov. Check <a href="http://www.eclemma.org/">http://www.eclemma.org/</a>
for updates, documentation and support.
</p>
<h3>License</h3>
<p>
The Content in this plug-in is Contributed by Mountainminds GmbH & Co. KG,
Munich. Except indicated below, the Content is provided to you under the terms
and conditions of the Eclipse Public License Version 1.0 (&quot;EPL&quot;).
A copy of the EPL is available at
<a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
</p>
<p>
The plug-in includes <a href="http://emma.sourceforge.net/">EMMA</a> by Vlad
Roubtsov which is distributed under the terms of the Common Public License
Version 1.0 (&quot;CPL&quot;). A copy of the CPL is available at
<a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
</p>
</body>
</html>

View File

@ -0,0 +1,13 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
plugin.xml,\
.options,\
plugin.properties,\
emma.jar,\
about.html
src.includes = src/,\
build.properties
javacSource = 1.3
javacTarget = 1.2

Binary file not shown.

View File

@ -0,0 +1,21 @@
#*******************************************************************************
# Copyright (c) 2006 Mountainminds GmbH & Co. KG
# This software is provided under the terms of the Eclipse Public License v1.0
# See http://www.eclipse.org/legal/epl-v10.html.
#
# $Id$
#*******************************************************************************
providerName = Mountainminds GmbH & Co. KG
pluginName = EclEmma Core
coverage = Coverage
javaDelegateName=EclEmma Java
junitDelegateName=EclEmma JUnit Test
eclipseApplicationDelegateName=EclEmma Eclipse Application
junitPluginDelegateName=EclEmma JUnit Plugin Test
osgiDelegateName=EclEmma OSGi Framework
testNgDelegateName=EclEmma TestNG
junitRAPDelegateName=EclEmma RAP JUnit Test
swtBotJunitDelegateName=EclEmma SWTBot Test

View File

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<plugin>
<extension
point="org.eclipse.core.runtime.adapters">
<factory
adaptableType="org.eclipse.jdt.core.IJavaElement"
class="com.mountainminds.eclemma.internal.core.analysis.JavaElementCoverageAdapterFactory">
<adapter type="com.mountainminds.eclemma.core.analysis.IJavaElementCoverage"/>
<adapter type="com.mountainminds.eclemma.core.analysis.ILineCoverage"/>
</factory>
<factory
adaptableType="org.eclipse.core.resources.IResource"
class="com.mountainminds.eclemma.internal.core.analysis.JavaElementCoverageAdapterFactory">
<adapter type="com.mountainminds.eclemma.core.analysis.IJavaElementCoverage"/>
<adapter type="com.mountainminds.eclemma.core.analysis.ILineCoverage"/>
</factory>
</extension>
<extension
point="org.eclipse.debug.core.launchModes">
<launchMode
label="%coverage"
mode="coverage"/>
</extension>
<extension
point="org.eclipse.debug.core.launchDelegates">
<launchDelegate
delegate="com.mountainminds.eclemma.core.launching.JavaApplicationLauncher"
id="com.mountainminds.eclemma.core.javaApplicationLauncher"
modes="coverage"
name="%javaDelegateName"
type="org.eclipse.jdt.launching.localJavaApplication"/>
<launchDelegate
delegate="com.mountainminds.eclemma.core.launching.JavaApplicationLauncher"
id="com.mountainminds.eclemma.core.junitLauncher"
modes="coverage"
name="%junitDelegateName"
type="org.eclipse.jdt.junit.launchconfig"/>
<launchDelegate
delegate="com.mountainminds.eclemma.core.launching.EclipseLauncher"
id="com.mountainminds.eclemma.core.workbenchLauncher"
modes="coverage"
name="%eclipseApplicationDelegateName"
type="org.eclipse.pde.ui.RuntimeWorkbench"/>
<launchDelegate
delegate="com.mountainminds.eclemma.core.launching.EclipseLauncher"
id="com.mountainminds.eclemma.core.junitPluginLauncher"
modes="coverage"
name="%junitPluginDelegateName"
type="org.eclipse.pde.ui.JunitLaunchConfig"/>
<launchDelegate
delegate="com.mountainminds.eclemma.core.launching.EclipseLauncher"
id="com.mountainminds.eclemma.core.equinoxLauncher"
modes="coverage"
name="%osgiDelegateName"
type="org.eclipse.pde.ui.EquinoxLauncher"/>
<launchDelegate
delegate="com.mountainminds.eclemma.core.launching.JavaApplicationLauncher"
id="com.mountainminds.eclemma.core.testNGLauncher"
modes="coverage"
name="%testNgDelegateName"
type="org.testng.eclipse.launchconfig"/>
<launchDelegate
delegate="com.mountainminds.eclemma.core.launching.EclipseLauncher"
id="com.mountainminds.eclemma.ui.RAPJUnitLauncher"
modes="coverage"
name="%junitRAPDelegateName"
type="org.eclipse.rap.ui.launch.RAPJUnitTestLauncher"/>
<launchDelegate
delegate="com.mountainminds.eclemma.core.launching.EclipseLauncher"
id="com.mountainminds.eclemma.ui.SWTBotJUnitLauncher"
modes="coverage"
name="%swtBotJunitDelegateName"
type="org.eclipse.swtbot.eclipse.ui.launcher.JunitLaunchConfig"/>
</extension>
<extension
point="org.eclipse.jdt.launching.classpathProviders">
<classpathProvider
class="com.mountainminds.eclemma.internal.core.launching.InstrumentedClasspathProvider"
id="com.mountainminds.eclemma.core.instrumentedClasspathProvider"/>
</extension>
</plugin>

View File

@ -0,0 +1,251 @@
/*******************************************************************************
* Copyright (c) 2006, 2009 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import com.mountainminds.eclemma.core.analysis.IJavaCoverageListener;
import com.mountainminds.eclemma.core.analysis.IJavaElementCoverage;
import com.mountainminds.eclemma.core.analysis.IJavaModelCoverage;
import com.mountainminds.eclemma.core.analysis.ILineCoverage;
import com.mountainminds.eclemma.core.launching.ICoverageLaunchConfigurationConstants;
import com.mountainminds.eclemma.core.launching.ICoverageLaunchInfo;
import com.mountainminds.eclemma.core.launching.ICoverageLauncher;
import com.mountainminds.eclemma.internal.core.CoverageSession;
import com.mountainminds.eclemma.internal.core.EclEmmaCorePlugin;
import com.mountainminds.eclemma.internal.core.SessionExporter;
import com.mountainminds.eclemma.internal.core.SessionImporter;
import com.mountainminds.eclemma.internal.core.instr.DefaultInstrumentationFilter;
import com.mountainminds.eclemma.internal.core.launching.CoverageLaunchInfo;
/**
* For central access to the tools provided by the coverage core plugin this
* class offers several static methods.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public final class CoverageTools {
/**
* The launch mode used for coverage sessions.
*/
public static final String LAUNCH_MODE = "coverage"; //$NON-NLS-1$
public static final int EXPORT_HTML = 0;
public static final int EXPORT_XML = 1;
public static final int EXPORT_TEXT = 2;
public static final int EXPORT_ES = 3;
/**
* Returns the global session manager.
*
* @return global session manager
*/
public static ISessionManager getSessionManager() {
return EclEmmaCorePlugin.getInstance().getSessionManager();
}
/**
* Convenience method that tries to adapt the given object to
* IJavaElementCoverage, i.e. find coverage information from the active
* session.
*
* @param object
* Object to adapt
* @return adapter or <code>null</code>
*/
public static IJavaElementCoverage getCoverageInfo(Object object) {
if (object instanceof IAdaptable) {
return (IJavaElementCoverage) ((IAdaptable) object)
.getAdapter(IJavaElementCoverage.class);
} else {
return null;
}
}
/**
* Convenience method that tries to adapt the given object to ILineCoverage,
* i.e. find line coverage information from the active session.
*
* @param object
* Object to adapt
* @return adapter or <code>null</code>
*/
public static ILineCoverage getLineCoverage(Object object) {
if (object instanceof IAdaptable) {
return (ILineCoverage) ((IAdaptable) object)
.getAdapter(ILineCoverage.class);
} else {
return null;
}
}
/**
* Returns the coverage launch info that is assoziated with the given launch.
* If no info object is assoziated with the given launch <code>null</code> is
* returned, i.e. the launch was probably not in coverage mode.
*
* @param launch
* the launch object we need coverage data for
* @return the info object or <code>null</code>
*/
public static ICoverageLaunchInfo getLaunchInfo(ILaunch launch) {
return CoverageLaunchInfo.getInfo(launch);
}
/**
* Returns a local path to the emma.jar runtime archive.
*
* @return local path to emma.jar
* @throws CoreException
* if no local version can be created
*/
public static IPath getEmmaJar() throws CoreException {
URL url = EclEmmaCorePlugin.getInstance().find(EclEmmaCorePlugin.EMMA_JAR);
try {
url = Platform.asLocalURL(url);
} catch (IOException e) {
throw new CoreException(EclEmmaStatus.NO_LOCAL_EMMAJAR_ERROR.getStatus(e));
}
return new Path(url.getPath());
}
/**
* Returns descriptors for all class files in the workspace.
*
* @return descriptors for all class files in the workspace
* @throws CoreException
*/
public static IClassFiles[] getClassFiles() throws CoreException {
return EclEmmaCorePlugin.getInstance().getAllClassFiles().getClassFiles();
}
/**
* Returns descriptors the location at the given absolute location on the
* local system.
*
* @return {@link IClassFiles} at the given location or <code>null</code> if
* not found
* @throws CoreException
*/
public static IClassFiles getClassFilesAtAbsoluteLocation(String location)
throws CoreException {
return EclEmmaCorePlugin.getInstance().getAllClassFiles()
.getAtAbsoluteLocation(location);
}
/**
* Returns descriptors for class files for the given launch configuration.
*
* @param configuration
* launch configuration to look for class files
* @param includebinaries
* flag whether binary classpath entries should be included
*
* @return descriptors for all class files
*
* @throws CoreException
*/
public static IClassFiles[] getClassFiles(ILaunchConfiguration configuration,
boolean includebinaries) throws CoreException {
ICoverageLauncher launcher = (ICoverageLauncher) configuration.getType()
.getDelegate(LAUNCH_MODE);
return launcher.getClassFiles(configuration, includebinaries);
}
/**
* Returns descriptors for class files for instrumentation as configured by
* the given launch configuration.
*
* @param configuration
* launch configuration to look for class files
* @param inplace
* flag whether instrumentation will happen inplace. In this case
* binary libraries will be excluded
*
* @return descriptors for all class for instrumentation
*
* @throws CoreException
*/
public static IClassFiles[] getClassFilesForInstrumentation(
final ILaunchConfiguration configuration, final boolean inplace)
throws CoreException {
final IClassFiles[] all = getClassFiles(configuration, !inplace);
final List selection = configuration.getAttribute(
ICoverageLaunchConfigurationConstants.ATTR_INSTRUMENTATION_PATHS,
(List) null);
if (selection != null && selection.size() > 0) {
// Classes for instrumentation are already configured:
final List filtered = new ArrayList();
for (int i = 0; i < all.length; i++) {
if (selection.contains(all[i].getLocation().toString())) {
filtered.add(all[i]);
}
}
return (IClassFiles[]) filtered.toArray(new IClassFiles[filtered.size()]);
}
// Otherwise we use a default selection:
final DefaultInstrumentationFilter filter = EclEmmaCorePlugin.getInstance()
.createDefaultIntrumentationFilter();
return filter.filter(all, configuration);
}
public static ICoverageSession createCoverageSession(String description,
IInstrumentation[] instrumentations, IPath[] coveragedatafiles,
ILaunchConfiguration launchconfiguration) {
return new CoverageSession(description, instrumentations,
coveragedatafiles, launchconfiguration);
}
public static IJavaModelCoverage getJavaModelCoverage() {
return EclEmmaCorePlugin.getInstance().getJavaCoverageLoader()
.getJavaModelCoverage();
}
public static void addJavaCoverageListener(IJavaCoverageListener l) {
EclEmmaCorePlugin.getInstance().getJavaCoverageLoader()
.addJavaCoverageListener(l);
}
public static void removeJavaCoverageListener(IJavaCoverageListener l) {
EclEmmaCorePlugin.getInstance().getJavaCoverageLoader()
.removeJavaCoverageListener(l);
}
public static ISessionExporter getExporter(ICoverageSession session) {
return new SessionExporter(session);
}
public static ISessionImporter getImporter() {
return new SessionImporter();
}
/**
* Sets a {@link ICorePreferences} instance which will be used by the EclEmma
* core to query preference settings if required.
*
* @param preferences
* callback object for preference settings
*/
public static void setPreferences(ICorePreferences preferences) {
EclEmmaCorePlugin.getInstance().setPreferences(preferences);
}
}

View File

@ -0,0 +1,158 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;
import com.mountainminds.eclemma.internal.core.CoreMessages;
import com.mountainminds.eclemma.internal.core.EclEmmaCorePlugin;
/**
* Status objects used by the core plugin.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public final class EclEmmaStatus {
public final int code;
public final int severity;
public final String message;
private EclEmmaStatus(int code, int severity, String message) {
this.code = code;
this.severity = severity;
this.message = message;
}
public IStatus getStatus() {
String m = NLS.bind(message, new Integer(code));
return new Status(severity, EclEmmaCorePlugin.ID, code, m, null);
}
public IStatus getStatus(Throwable t) {
String m = NLS.bind(message, new Integer(code));
return new Status(severity, EclEmmaCorePlugin.ID, code, m, t);
}
public IStatus getStatus(Object param1, Throwable t) {
String m = NLS.bind(message, new Integer(code), param1);
return new Status(severity, EclEmmaCorePlugin.ID, code, m, t);
}
public IStatus getStatus(Object param1) {
String m = NLS.bind(message, new Integer(code), param1);
return new Status(severity, EclEmmaCorePlugin.ID, code, m, null);
}
/**
* Info before inplace instrumentation happens.
*/
public static final EclEmmaStatus INPLACE_INSTRUMENTATION_INFO = new EclEmmaStatus(
2000, IStatus.INFO,
CoreMessages.StatusINPLACE_INSTRUMENTATION_INFO_message);
/**
* Status indicating that it was not possible to obtain a local version of the
* emma.jar file.
*/
public static final EclEmmaStatus NO_LOCAL_EMMAJAR_ERROR = new EclEmmaStatus(
5000, IStatus.ERROR, CoreMessages.StatusNO_LOCAL_EMMAJAR_ERROR_message);
/**
* Status indication that it was not possible to generate a internal id for a
* resource.
*/
public static final EclEmmaStatus ID_CREATION_ERROR = new EclEmmaStatus(
5001, IStatus.ERROR, CoreMessages.StatusID_CREATION_ERROR_message);
/**
* The requested launch type is not known.
*/
public static final EclEmmaStatus UNKOWN_LAUNCH_TYPE_ERROR = new EclEmmaStatus(
5002, IStatus.ERROR, CoreMessages.StatusUNKOWN_LAUNCH_TYPE_ERROR_message);
/**
* The coverage runtime classpath provider has been called in an invalid
* execution context, i.e. outside of <code>CoverageLauncher.launch()</code>.
*/
public static final EclEmmaStatus INVALID_CLASSPATH_PROVIDER_CONTEXT_ERROR = new EclEmmaStatus(
5003, IStatus.ERROR,
CoreMessages.StatusINVALID_CLASSPATH_PROVIDER_CONTEXT_ERROR_message);
/**
* The coverage launch info object is missing unexpectedly.
*/
public static final EclEmmaStatus MISSING_LAUNCH_INFO_ERROR = new EclEmmaStatus(
5004, IStatus.ERROR, CoreMessages.StatusMISSING_LAUNCH_INFO_ERROR_message);
/**
* Error while creating the JAR containing emma runtime properties.
*/
public static final EclEmmaStatus EMMA_PROPERTIES_CREATION_ERROR = new EclEmmaStatus(
5005, IStatus.ERROR,
CoreMessages.StatusEMMA_PROPERTIES_CREATION_ERROR_message);
/**
* Error while reading coverage data file.
*/
public static final EclEmmaStatus COVERAGEDATA_FILE_READ_ERROR = new EclEmmaStatus(
5006, IStatus.ERROR,
CoreMessages.StatusCOVERAGEDATA_FILE_READ_ERROR_message);
/**
* Error while reading meta data file.
*/
public static final EclEmmaStatus METADATA_FILE_READ_ERROR = new EclEmmaStatus(
5007, IStatus.ERROR, CoreMessages.StatusMETADATA_FILE_READ_ERROR_message);
/**
* Error while extracting source files.
*/
public static final EclEmmaStatus SOURCE_EXTRACTION_ERROR = new EclEmmaStatus(
5008, IStatus.ERROR, CoreMessages.StatusSOURCE_EXTRACTION_ERROR_message);
/**
* Error while importing external coverage session.
*/
public static final EclEmmaStatus IMPORT_ERROR = new EclEmmaStatus(
5009, IStatus.ERROR, CoreMessages.StatusIMPORT_ERROR_message);
/**
* Error while importing external coverage session.
*/
public static final EclEmmaStatus FILE_CONTAINS_NO_METADATA = new EclEmmaStatus(
5010, IStatus.ERROR, CoreMessages.StatusFILE_CONTAINS_NO_METADATA_message);
/**
* Trying to instrument instrumented class files. This status is used to issue
* an error prompt during launching.
*/
public static final EclEmmaStatus ALREADY_INSTRUMENTED_ERROR = new EclEmmaStatus(
5100, IStatus.ERROR, CoreMessages.StatusALREADY_INSTRUMENTED_ERROR_message);
/**
* No coverage data file has been created during a coverage launch. This
* status is used to issue an error prompt.
*/
public static final EclEmmaStatus NO_COVERAGE_DATA_ERROR = new EclEmmaStatus(
5101, IStatus.ERROR, CoreMessages.StatusNO_COVERAGE_DATA_ERROR_message);
/**
* No classes are selected for instrumentation. This status is used to issue
* an error prompt during launching.
*/
public static final EclEmmaStatus NO_INSTRUMENTED_CLASSES = new EclEmmaStatus(
5102, IStatus.ERROR, CoreMessages.StatusNO_INSTRUMENTED_CLASSES_message);
}

View File

@ -0,0 +1,79 @@
/*******************************************************************************
* Copyright (c) 2006, 2009 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
/**
* Instances of {@link IClassFiles} describe a folder or archive containing
* class files. Class files can be binary libraries or the compilation output of
* source folders. These class file may be instrumented for coverage analysis.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public interface IClassFiles {
/**
* This method returns <code>true</code> if the class files described by this
* instance are not compiled from a source folder.
*
* @return <code>true</code> if the class files are a binary resource only
*/
public boolean isBinary();
/**
* Returns the list of package fragment roots that belong to the class files.
* The list may have more than one entry, if several source folders share the
* same output location or if multiple library classpath entries point to the
* same location.
*
* @return list of package fragment roots
*/
public IPackageFragmentRoot[] getPackageFragmentRoots();
/**
* Returns the workspace relative path to of the class files, either a
* directory or a JAR file.
*
* @return location of the class files
*/
public IPath getLocation();
/**
* Determines the source locations that belong to the class files. If no
* source is known for this class files a empty list is returned.
*
* @return List of {@link ISourceLocation} objects
* @throws JavaModelException
* May be thrown while querying the Java model
*/
public ISourceLocation[] getSourceLocations() throws JavaModelException;
/**
* Instruments the class files contained in the folder or archive returned by
* {@link #getLocation()}. If in-place mode is enabled, the original class
* files or archives will be replaced.
*
* @param inplace
* if <code>true</code> the original class files will be overwritten
* @param monitor
* optional progress monitor
* @return {@link IInstrumentation} object describing the instrumentation
* result
* @throws CoreException
* thrown if the instrumentation process fails
*/
public IInstrumentation instrument(boolean inplace, IProgressMonitor monitor)
throws CoreException;
}

View File

@ -0,0 +1,88 @@
/*******************************************************************************
* Copyright (c) 2006, 2009 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id: $
******************************************************************************/
package com.mountainminds.eclemma.core;
/**
* Clients may implement this interface to customize the behavior of the EclEmma
* core plug-in and pass a instance to
* {@link CoverageTools#setPreferences(ICorePreferences)}. This interface
* decouples the core e.g. from the UI preferences.
*
* @author Marc R. Hoffmann
* @version $Revision: $
*/
public interface ICorePreferences {
/**
* Default behavior if no customization is set.
*/
public static final ICorePreferences DEFAULT = new ICorePreferences() {
public boolean getActivateNewSessions() {
return true;
}
public boolean getAutoRemoveSessions() {
return false;
}
public boolean getDefaultInstrumentationSourceFoldersOnly() {
return true;
}
public boolean getDefaultInstrumentationSameProjectOnly() {
return false;
}
public String getDefaultInstrumentationFilter() {
return "";//$NON-NLS-1$
}
};
/**
* Determines whether new sessions should automatically be activated.
*
* @return <code>true</code>, if sessions should be activated
*/
public boolean getActivateNewSessions();
/**
* Determines whether sessions should automatically be removed when their
* respective launch is removed from the debug environment.
*
* @return <code>true</code>, if sessions should be removed
*/
public boolean getAutoRemoveSessions();
/**
* Specification of the default instrumentation behavior: Instrument source
* folders only.
*
* @return <code>true</code>, if source folders only should be instrumented by
* default
*/
public boolean getDefaultInstrumentationSourceFoldersOnly();
/**
* Specification of the default instrumentation behavior: Instrument code in
* the same project only. This filter works only for launch configuration
* types that have a reference to a project.
*
* @return <code>true</code>, if code in the same project should be
* instrumented only
*/
public boolean getDefaultInstrumentationSameProjectOnly();
/**
* Returns a comma separated list of match strings that specifies patterns for
* class path entries to be instrumented by default.
*
* @return List of match strings
*/
public String getDefaultInstrumentationFilter();
}

View File

@ -0,0 +1,78 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.debug.core.ILaunchConfiguration;
/**
* A coverage session is the result of a coverage run (or multiple merged runs)
* or coverage data imported from an external source. It is an immutable
* container for all data necessary to
*
* <ul>
* <li>provide coverage highlighting in Java editors,</li>
* <li>populate the coverage view and</li>
* <li>export coverage reports using Emma's reporting capabilities.</li>
* </ul>
*
* This interface is not intended to be implemented by clients.
*
* @see CoverageTools#createCoverageSession(String, IInstrumentation[],
* IPath[], ILaunchConfiguration)
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public interface ICoverageSession extends IAdaptable {
/**
* Returns a readable description for this coverage session.
*
* @return readable description
*/
public String getDescription();
/**
* Returns the array of instrumentation information objects for this session.
*
* @return array of {@link IInstrumentation} used for this session
*/
public IInstrumentation[] getInstrumentations();
/**
* Returns a list of absolute paths to the Emma coverage data files that
* belong to this session.
*
* @return list of absolute paths to the Emma coverage data files
*/
public IPath[] getCoverageDataFiles();
/**
* If this session was the result of a Eclipse launch this method returns the
* respective launch configutation. Otherwise <code>null</code> is returned.
*
* @return launch configutation or <code>null</code>
*/
public ILaunchConfiguration getLaunchConfiguration();
/**
* Merges this session with the given session creating a new session with the
* given description.
*
* @param other
* Session to merge with
* @param description
* Name of the new session
* @return
* New session object merged from this and the given session
*/
public ICoverageSession merge(ICoverageSession other, String description);
}

View File

@ -0,0 +1,57 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
/**
* Instances of {@link IInstrumentation} describe a set of instrumented Java
* classes. This interface is not intended to be implemented by clients,
* instances are returned by
* {@link IClassFiles#instrument(boolean, IProgressMonitor)}.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public interface IInstrumentation {
/**
* Returns the {@link IClassFiles} object that describe the source of this
* instrumentation.
*
* @return {@link IClassFiles} object
*/
public IClassFiles getClassFiles();
/**
* Returns <code>true</code> if this instrumentation has been performed
* in-place.
*
* @return <code>true</code> if this instrumentation was in-place
*/
public boolean isInplace();
/**
* Returns the absolute path to the instrumented class files. If in-place
* instrumentation was performed, this corresponds to the location of the
* original class files.
*
* @return absolute path to the instrumented class files
*/
public IPath getOutputLocation();
/**
* Returns the absolute path to the Emma meta data file that has been written
* during instrumentation.
*
* @return absolute path to the meta data file
*/
public IPath getMetaDataFile();
}

View File

@ -0,0 +1,79 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id: $
******************************************************************************/
package com.mountainminds.eclemma.core;
import java.util.Properties;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
/**
* API for exporting sessions. This interface is not intended to be implemented
* by clients. Use {@link CoverageTools#getExporter(ICoverageSession)} to get an
* instance.
*
* @author Marc R. Hoffmann
* @version $Revision: $
*/
public interface ISessionExporter {
/** Constant for export as HTML files (value is 0). */
public static final int HTML_FORMAT = 0;
/** Constant for XML file export (value is 1). */
public static final int XML_FORMAT = 1;
/** Constant for plain text export (value is 2). */
public static final int TXT_FORMAT = 2;
/** Constant for EMMA session file export (value is 3). */
public static final int EMMA_FORMAT = 3;
/**
* Default file extensions for the different file formats. The array index
* corresponds to the format constant.
*/
public static final String[] DEFAULT_EXTENSIONS = new String[] { "html", //$NON-NLS-1$
"xml", "txt", "es" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
/**
* Sets the export format.
*
* @param format
* export format constant
*/
public void setFormat(int format);
/**
* Sets the export file name. Note that in case of HTML export this is only
* the main file, while more files are created as siblings.
*
* @param filename
* file name of export destination
*/
public void setDestination(String filename);
/**
* Sets EMMA specific report options that overwrite the default setting.
*
* @param options
* EMMA specific report options
*/
public void setReportOptions(Properties options);
/**
* A call to this method triggers the actual export process.
*
* @param monitor
* progress monitor
* @throws CoreException
* if something goes wrong during export
*/
public void export(IProgressMonitor monitor) throws CoreException;
}

View File

@ -0,0 +1,76 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
/**
* API for importing sessions. This interface is not intended to be implemented
* by clients. Use {@link CoverageTools#getImporter()} to get an instance.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public interface ISessionImporter {
/**
* Sets the description for the imported session.
*
* @param description
* textual description of the session
*/
public void setDescription(String description);
/**
* Sets the path to the coverage file to import.
*
* @param file
* coverage file to import
*/
public void setCoverageFile(String file);
/**
* Sets the list of class files that should be considered for coverage
* analysis.
*
* @param classfiles
* class files for analysis
*/
public void setClassFiles(IClassFiles[] classfiles);
/**
* Specifies whether the original file should be copied while importing.
* Otherwise the coverage file a referenced only.
*
* @param copy
* flag, whether the coverage file should be copied
*/
public void setCopy(boolean copy);
/**
* Imported session files might come with their own meta data. Here we can set
* whether this data should be used. Otherwise Meta data is extracted from the
* local class files.
*
* @param flag
* true, if external Meta data should be used
*/
public void setUseImportedMetaData(boolean flag);
/**
* A call to this method triggers the actual import process.
*
* @param monitor
* progress monitor
* @throws CoreException
* if something goes wrong during export
*/
public void importSession(IProgressMonitor monitor) throws CoreException;
}

View File

@ -0,0 +1,48 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core;
/**
* Callback interface for changes of the session manager. This interface is
* intended to be implemented by clients that want to get notifications.
*
* @see ISessionManager#addSessionListener(ISessionListener)
* @see ISessionManager#removeSessionListener(ISessionListener)
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public interface ISessionListener {
/**
* Called when a session has been added.
*
* @param addedSession
* added session
*/
public void sessionAdded(ICoverageSession addedSession);
/**
* Called when a session has been removed.
*
* @param removedSession
* removes session
*/
public void sessionRemoved(ICoverageSession removedSession);
/**
* Called when a new session has been activated or the last session has been
* removed. In this case <code>null</code> is passed as a parameter.
*
* @param session
* activated session or <code>null</code>
*/
public void sessionActivated(ICoverageSession session);
}

View File

@ -0,0 +1,134 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core;
/**
* The session manager holds a list of currently available sessions. One of the
* sessions in the list may be the active session, which is the one that is used
* to attach coverage information to Java elements.
*
* This interface is not intended to be implemented or extended by clients.
*
* @see com.mountainminds.eclemma.core.CoverageTools#getSessionManager()
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public interface ISessionManager {
/**
* Adds the given session to this session manager. If the session is already
* part of this session manager the method has no effect. If the key parameter
* is not <code>null</code> the key is internally assigned to this session
* for later access.
*
* @param session
* the new session
* @param activate
* if <code>true</code> the session will also be activated
* @param key
* key object this session will be assigned to
*/
public void addSession(ICoverageSession session, boolean activate, Object key);
/**
* Removes the given session. If the session is not in included in this
* session manager this method has no effect. If the removed session was the
* active session, the most recently added session becomes active.
*
* @param session
* session to remove
*/
public void removeSession(ICoverageSession session);
/**
* Removes the session that has been assigned to the given key. If there is no
* session for the key this method has no effect. If the removed session was
* the active session, the most recently added session becomes active.
*
* @see #addSession(ICoverageSession, boolean, Object)
* @param key
* key object for the session to remove
*/
public void removeSession(Object key);
/**
* Removes all registered sessions.
*/
public void removeAllSessions();
/**
* Returns all sessions that have been registered with this session manager.
*
* @see #addSession(ICoverageSession, boolean, Object)
* @return list of registered session
*/
public ICoverageSession[] getSessions();
/**
* Returns the session that has been assigned to the given key. If there is no
* session for the key this method returns <code>null</code>.
*
* @see #addSession(ICoverageSession, boolean, Object)
* @param key
* key object for the session
* @return session object or <code>null</code>
*/
public ICoverageSession getSession(Object key);
/**
* Activates the given session. If the session is not in included in this
* session manager this method has no effect.
*
* @param session
* session to activate
*/
public void activateSession(ICoverageSession session);
/**
* Activates the session that has been assigned to the given key. If there is
* no session for the key this method has no effect.
*
* @see #addSession(ICoverageSession, boolean, Object)
* @param key
* key object for the session to activate
*/
public void activateSession(Object key);
/**
* Returns the active session or <code>null</code> if there is no session.
*
* @return active session or <code>null</null>
*/
public ICoverageSession getActiveSession();
/**
* Triggers a reload of the active session. If there is no active session
* this method has no effect.
*/
public void refreshActiveSession();
/**
* Adds the given session listener unless it has been added before.
*
* @param listener
* session listener to add
*/
public void addSessionListener(ISessionListener listener);
/**
* Removes the given session listener. If the listener has not been added
* before this method has no effect.
*
* @param listener
* session listener to remove
*/
public void removeSessionListener(ISessionListener listener);
}

View File

@ -0,0 +1,61 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
/**
* Reference to a location where Java source code is stored. This information
* is used for Emma report generation.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public interface ISourceLocation {
/**
* Returns the absolute path to the source folder or archive.
*
* @return absolute path to the source folder or archive
*/
public IPath getPath();
/**
* Determines whether this source location points to an archive.
*
* @return <code>true</code> if this source location is an archive
*/
public boolean isArchive();
/**
* Returns the path within the source archive where package fragments are
* located. An empty path indicates that packages are located at the root of
* the source archive or folder. Returns a non-<code>null</code> value if
* and only if {@link #isArchive()} returns <code>true</code>.
*
* @return the path within the source archive, or <code>null</code> if not
* applicable
*/
public IPath getRootPath();
/**
* If this source location points to an archive, calling this method will
* extract the source files to an temporary local folder. The properties of
* this descriptor object will be updated to the new location. If the source
* files are already extracted this method does nothing.
*
* @param monitor
* progress monitor or <code>null</code>
* @throws CoreException
* Thrown if the archive content can't be extracted.
*/
public void extract(IProgressMonitor monitor) throws CoreException;
}

View File

@ -0,0 +1,54 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core.analysis;
/**
* A counter holds the total and the covered number of particular items like
* classes, methods, blocks or instructions. Counters provide canonical
* comparison of their covered/total ratios. This interface is not intended to
* be implemented or extended by clients.
*
* @see IJavaElementCoverage#getLineCounter()
* @see IJavaElementCoverage#getBlockCounter()
* @see IJavaElementCoverage#getInstructionCounter()
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public interface ICounter extends Comparable {
/**
* Returns the total count number of instrumented items.
*
* @return total count of instrumented items
*/
public long getTotalCount();
/**
* Returns the total count number of covered items.
*
* @return total count of covered items
*/
public long getCoveredCount();
/**
* Returns the total count number of missed items.
*
* @return total count of missed items
*/
public long getMissedCount();
/**
* Calculates the ratio of covered to total count items. If total count items
* is 0 this method returns NaN.
*
* @return ratio of covered to total count items
*/
public double getRatio();
}

View File

@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core.analysis;
/**
* Callback interface implemented by clients that want to be informed, when the
* current Java model coverage has changes.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public interface IJavaCoverageListener {
/**
* Called when the current coverage data has changed.
*/
public void coverageChanged();
}

View File

@ -0,0 +1,71 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core.analysis;
/**
* Coverage data for a Java model element. This interface is not intended to be
* implemented or extended by clients.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public interface IJavaElementCoverage {
/**
* Returns line coverage details if the corresponding Java element is a
* compilation unit, type or method.
*
* @return {@link ILineCoverage} object or <code>null</code>
*/
public ILineCoverage getLineCoverage();
/**
* Returns the counter for blocks.
*
* @return counter for blocks
*/
public ICounter getBlockCounter();
/**
* Returns the counter for lines.
*
* @return counter for lines
*/
public ICounter getLineCounter();
/**
* Returns the counter for methods.
*
* @return counter for methods
*/
public ICounter getMethodCounter();
/**
* Returns the counter for types.
*
* @return counter for types
*/
public ICounter getTypeCounter();
/**
* Returns the counter for instructions.
*
* @return counter for instructions
*/
public ICounter getInstructionCounter();
/**
* Returns the modification stamp of the underlying resource. This can be used
* by clients to check whether the current version of the respective resource
* is identical to the version that was used for the coverage session.
*
* @return modification stamp of the underlying resource
*/
public long getResourceModificationStamp();
}

View File

@ -0,0 +1,122 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core.analysis;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import com.mountainminds.eclemma.internal.core.analysis.Counter;
/**
* The interface for coverage information attached to the Java model. It allows
* to retrieve coverage information for any Java model element and holds lists
* of entry points.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public interface IJavaModelCoverage extends IJavaElementCoverage {
/**
* This instance is used to indicate that a coverage session is currently
* loading.
*/
public static final IJavaModelCoverage LOADING = new IJavaModelCoverage() {
public ILineCoverage getLineCoverage() {
return null;
}
public ICounter getBlockCounter() {
return Counter.COUNTER_0_0;
}
public ICounter getLineCounter() {
return Counter.COUNTER_0_0;
}
public ICounter getInstructionCounter() {
return Counter.COUNTER_0_0;
}
public ICounter getMethodCounter() {
return Counter.COUNTER_0_0;
}
public ICounter getTypeCounter() {
return Counter.COUNTER_0_0;
}
public long getResourceModificationStamp() {
return 0;
}
public IJavaProject[] getInstrumentedProjects() {
return new IJavaProject[0];
}
public IPackageFragmentRoot[] getInstrumentedPackageFragmentRoots() {
return new IPackageFragmentRoot[0];
}
public IPackageFragment[] getInstrumentedPackageFragments() {
return new IPackageFragment[0];
}
public IType[] getInstrumentedTypes() {
return new IType[0];
}
public IJavaElementCoverage getCoverageFor(IJavaElement element) {
return null;
}
};
/**
* Returns all Java projects where coverage information is available for.
*
* @return list of Java projects
*/
public IJavaProject[] getInstrumentedProjects();
/**
* Returns all package fragment roots where coverage information is available
* for.
*
* @return list of package fragment roots.
*/
public IPackageFragmentRoot[] getInstrumentedPackageFragmentRoots();
/**
* Returns all package fragments where coverage information is available for.
*
* @return list of package fragments
*/
public IPackageFragment[] getInstrumentedPackageFragments();
/**
* Returns all Java types where coverage information is available for.
*
* @return list of Java types
*/
public IType[] getInstrumentedTypes();
/**
* Returns the coverage information associated with the given Java element. If
* no information is available <code>null</code> is returned.
*
* @param element Java element to look for coverage information
* @return associated coverage information of null
*/
public IJavaElementCoverage getCoverageFor(IJavaElement element);
}

View File

@ -0,0 +1,90 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core.analysis;
/**
* For all elements that sit in a compilation unit and for compilation units
* itself individual line coverage may be described by this interface. This
* interface is not intended to be implemented or extended by clients.
*
* @see IJavaElementCoverage#getLineCoverage()
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public interface ILineCoverage extends ICounter {
/** Flag for lines that do not contain code (value is 0x00). */
public static final byte NO_CODE = 0x00;
/** Flag for lines that are not covered (value is 0x01). */
public static final byte NOT_COVERED = 0x01;
/** Flag for lines that are fully covered (value is 0x02). */
public static final byte FULLY_COVERED = 0x02;
/** Flag for lines that are partly covered (value is 0x03). */
public static final byte PARTLY_COVERED = NOT_COVERED | FULLY_COVERED;
/**
* The number of the first line coverage information is available for.
*
* @return number of the first line
*/
public int getFirstLine();
/**
* The number of the last line coverage information is available for.
*
* @return number of the last line
*/
public int getLastLine();
/**
* Returns the line number of the first entry in the array returned by
* {@link #getCoverage()}.
*
* @deprecated use {@link #getCoverage(int)} instead
*
* @return offset of the coverage data array
*/
public int getOffset();
/**
* Returns an array of coverage flags defined as constants in this interface.
* The first item of the returned array corresponds to the line returned by
* {@link #getOffset()}. Note that the length of the array may supersede the
* actual source file length. If the no line information is available the
* method returns <code>null</code>.
*
* @see #NO_CODE
* @see #NOT_COVERED
* @see #PARTLY_COVERED
* @see #FULLY_COVERED
* @deprecated use {@link #getCoverage(int)} instead
*
* @return array of coverage flags or <code>null</code>
*/
public byte[] getCoverage();
/**
* Returns the coverage flag defined as constants in this interface for the
* given line.
*
* @see #NO_CODE
* @see #NOT_COVERED
* @see #PARTLY_COVERED
* @see #FULLY_COVERED
*
* @param line
* line number
* @return status flag
*/
public byte getCoverage(int line);
}

View File

@ -0,0 +1,313 @@
/*******************************************************************************
* Copyright (c) 2006, 2009 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core.launching;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExecutableExtension;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.Launch;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate2;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
import org.eclipse.jdt.launching.IRuntimeClasspathProvider;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.osgi.util.NLS;
import com.mountainminds.eclemma.core.CoverageTools;
import com.mountainminds.eclemma.core.EclEmmaStatus;
import com.mountainminds.eclemma.core.IClassFiles;
import com.mountainminds.eclemma.internal.core.CoreMessages;
import com.mountainminds.eclemma.internal.core.DebugOptions;
import com.mountainminds.eclemma.internal.core.EclEmmaCorePlugin;
import com.mountainminds.eclemma.internal.core.instr.InstrMarker;
import com.mountainminds.eclemma.internal.core.launching.CoverageLaunchInfo;
import com.mountainminds.eclemma.internal.core.launching.InstrumentedClasspathProvider;
import com.vladium.emma.AppLoggers;
import com.vladium.emma.EMMAProperties;
/**
* Abstract base class for coverage mode launchers. Coverage launchers perform
* class instrumentation and then delegate to the corresponding launcher
* responsible for the "run" mode.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public abstract class CoverageLauncher implements ICoverageLauncher,
IExecutableExtension {
/**
* Name of the file that will EMMA pick from the classpath to reads its
* properties.
*/
protected static final String EMMA_PROPERTIES_FILE = "emma.properties"; //$NON-NLS-1$
/** Launch mode for the launch delegates used internally. */
public static final String DELEGATELAUNCHMODE = ILaunchManager.RUN_MODE;
protected String launchtype;
protected ILaunchConfigurationDelegate launchdelegate;
protected ILaunchConfigurationDelegate2 launchdelegate2;
/**
* Hook method to modify the launch configuration before it is passed on to
* the delegate launcher.
*
* @param workingcopy
* Configuration to modify
* @param info
* Info object of this launch
* @throws CoreException
* may be thrown by implementations
*/
protected void modifyConfiguration(
ILaunchConfigurationWorkingCopy workingcopy, ICoverageLaunchInfo info)
throws CoreException {
// Does nothing by default
}
/**
* Returns whether in-place instrumentation should be performed. The default
* implementation looks-up the corresponding entry in the passed launch
* configuration. Specific launchers may modify this behavior.
*
* @param configuration
* launch configuration for coverage run
* @return true, if instrumentation should be performed in-place
* @throws CoreException
* May be thrown when accessing the launch configuration
*/
protected boolean hasInplaceInstrumentation(ILaunchConfiguration configuration)
throws CoreException {
return configuration.getAttribute(
ICoverageLaunchConfigurationConstants.ATTR_INPLACE_INSTRUMENTATION,
false);
}
/**
* Creates the a JAR file including the <code>emma.properties</code> file that
* will be injected in the class path.
*
* @param configuration
* Configuration object for this launch
* @param info
* Launch Info object of this launch
* @throws CoreException
* Thrown when the JAR file cannot be created
*/
private void createPropertiesJAR(ILaunchConfiguration configuration,
ICoverageLaunchInfo info) throws CoreException {
Properties properties = new Properties();
properties.put(EMMAProperties.PROPERTY_COVERAGE_DATA_OUT_FILE, info
.getCoverageFile().toOSString());
properties.put(AppLoggers.PROPERTY_VERBOSITY_LEVEL,
DebugOptions.EMMAVERBOSITYLEVEL);
IPath jarfile = info.getPropertiesJARFile();
Manifest mf = new Manifest();
try {
JarOutputStream jar = new JarOutputStream(new FileOutputStream(jarfile
.toFile()), mf);
jar.putNextEntry(new ZipEntry(EMMA_PROPERTIES_FILE));
properties.store(jar,
"Created for launch configuration " + configuration.getName()); //$NON-NLS-1$
jar.close();
} catch (IOException e) {
throw new CoreException(EclEmmaStatus.EMMA_PROPERTIES_CREATION_ERROR
.getStatus(jarfile, e));
}
}
// IExecutableExtension interface:
public void setInitializationData(IConfigurationElement config,
String propertyName, Object data) throws CoreException {
launchtype = config.getAttribute("type"); //$NON-NLS-1$
launchdelegate = getLaunchDelegate(launchtype);
if (launchdelegate instanceof ILaunchConfigurationDelegate2) {
launchdelegate2 = (ILaunchConfigurationDelegate2) launchdelegate;
}
}
private ILaunchConfigurationDelegate getLaunchDelegate(String launchtype)
throws CoreException {
ILaunchConfigurationType type = DebugPlugin.getDefault().getLaunchManager()
.getLaunchConfigurationType(launchtype);
if (type == null) {
throw new CoreException(EclEmmaStatus.UNKOWN_LAUNCH_TYPE_ERROR
.getStatus(launchtype));
}
return type.getDelegate(DELEGATELAUNCHMODE);
}
// ILaunchConfigurationDelegate interface:
public void launch(ILaunchConfiguration configuration, String mode,
ILaunch launch, IProgressMonitor monitor) throws CoreException {
monitor.beginTask(NLS.bind(CoreMessages.Launching_task, configuration
.getName()), 2);
IRuntimeClasspathProvider provider = JavaRuntime
.getClasspathProvider(configuration);
ICoverageLaunchInfo info = CoverageTools.getLaunchInfo(launch);
if (info == null) {
// Must not happen as we should have created the launch
throw new CoreException(EclEmmaStatus.MISSING_LAUNCH_INFO_ERROR
.getStatus(null));
}
info.instrument(new SubProgressMonitor(monitor, 1),
hasInplaceInstrumentation(configuration));
if (monitor.isCanceled()) {
return;
}
createPropertiesJAR(configuration, info);
ILaunchConfigurationWorkingCopy wc = configuration.getWorkingCopy();
modifyConfiguration(wc, info);
InstrumentedClasspathProvider.enable(provider, info);
try {
launchdelegate.launch(wc, DELEGATELAUNCHMODE, launch,
new SubProgressMonitor(monitor, 1));
} finally {
InstrumentedClasspathProvider.disable();
}
monitor.done();
}
// ILaunchConfigurationDelegate2 interface:
public ILaunch getLaunch(ILaunchConfiguration configuration, String mode)
throws CoreException {
ILaunch launch = new Launch(configuration, CoverageTools.LAUNCH_MODE, null);
new CoverageLaunchInfo(launch);
return launch;
}
public boolean buildForLaunch(ILaunchConfiguration configuration,
String mode, IProgressMonitor monitor) throws CoreException {
if (launchdelegate2 == null) {
return true;
} else {
return launchdelegate2.buildForLaunch(configuration, DELEGATELAUNCHMODE,
monitor);
}
}
public boolean preLaunchCheck(ILaunchConfiguration configuration,
String mode, IProgressMonitor monitor) throws CoreException {
boolean inplace = hasInplaceInstrumentation(configuration);
if (CoverageTools.getClassFilesForInstrumentation(configuration, inplace).length == 0) {
IStatus status = EclEmmaStatus.NO_INSTRUMENTED_CLASSES.getStatus();
EclEmmaCorePlugin.getInstance().showPrompt(status, configuration);
return false;
}
if (inplace) {
// Issue an inplace instrumentation warning:
IStatus status = EclEmmaStatus.INPLACE_INSTRUMENTATION_INFO.getStatus();
if (!EclEmmaCorePlugin.getInstance().showPrompt(status, configuration)) {
return false;
}
} else {
// check whether inpace instrumentation has been performed before
if (checkForPreviousInplace(configuration)) {
IStatus status = EclEmmaStatus.ALREADY_INSTRUMENTED_ERROR.getStatus();
EclEmmaCorePlugin.getInstance().showPrompt(status, configuration);
return false;
}
}
// Then allow the delegate's veto:
if (launchdelegate2 == null) {
return true;
} else {
return launchdelegate2.preLaunchCheck(configuration, DELEGATELAUNCHMODE,
monitor);
}
}
private boolean checkForPreviousInplace(ILaunchConfiguration config)
throws CoreException {
IClassFiles[] classfiles = CoverageTools.getClassFilesForInstrumentation(
config, false);
for (int i = 0; i < classfiles.length; i++) {
if (InstrMarker.isMarked(classfiles[i].getLocation())) {
return true;
}
}
return false;
}
public boolean finalLaunchCheck(ILaunchConfiguration configuration,
String mode, IProgressMonitor monitor) throws CoreException {
if (launchdelegate2 == null) {
return true;
} else {
return launchdelegate2.finalLaunchCheck(configuration,
DELEGATELAUNCHMODE, monitor);
}
}
// ICoverageLauncher interface:
/*
* The default implemenation delegates to the classpath provider.
*/
public IClassFiles[] getClassFiles(ILaunchConfiguration configuration,
boolean includebinaries) throws CoreException {
List l = new ArrayList();
IRuntimeClasspathEntry[] entries = JavaRuntime
.computeUnresolvedRuntimeClasspath(configuration);
entries = JavaRuntime.resolveRuntimeClasspath(entries, configuration);
for (int i = 0; i < entries.length; i++) {
if (entries[i].getClasspathProperty() == IRuntimeClasspathEntry.USER_CLASSES) {
IClassFiles ic = CoverageTools
.getClassFilesAtAbsoluteLocation(entries[i].getLocation());
if (ic != null && (includebinaries || !ic.isBinary())) {
l.add(ic);
}
}
}
IClassFiles[] arr = new IClassFiles[l.size()];
return (IClassFiles[]) l.toArray(arr);
}
/**
* Internal utility to find the {@link IClassFiles} descriptor for the given
* class path location.
*
* @param location
* class path location
* @return descriptor or <code>null</code>
* @throws CoreException
* in case of internal inconsistencies
* @deprecated please user
* {@link CoverageTools#getClassFilesAtAbsoluteLocation(String)}
* instead
*/
protected IClassFiles findClassFiles(String location) throws CoreException {
return CoverageTools.getClassFilesAtAbsoluteLocation(location);
}
}

View File

@ -0,0 +1,108 @@
/*******************************************************************************
* Copyright (c) 2006, 2009 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core.launching;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import com.mountainminds.eclemma.core.CoverageTools;
import com.mountainminds.eclemma.core.IClassFiles;
import com.mountainminds.eclemma.internal.core.EclEmmaCorePlugin;
import com.mountainminds.eclemma.internal.core.EclipseVersion;
/**
* Laucher for the Eclipse runtime workbench.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class EclipseLauncher extends CoverageLauncher {
protected static final String PLUGIN_NATURE = "org.eclipse.pde.PluginNature"; //$NON-NLS-1$
/** Pre-Eclipse 3.2.0 VM arguments key */
protected static final String PRE320VMARGS = "vmargs"; //$NON-NLS-1$
protected static final String VMARGS = IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS;
public static final String BOOTPATHARG = "-Xbootclasspath/a:"; //$NON-NLS-1$
/**
* Returns the proper key for VM arguments depending on the Eclipse version
*
* @return launch configuration key for VM arguments
*/
protected String getVMArgsKey() {
boolean is320 = EclipseVersion.isGreaterOrEqualTo(EclipseVersion.V320);
return is320 ? VMARGS : PRE320VMARGS;
}
/**
* Adds the given single argument to the VM arguments. If it contains white
* spaces the argument is included in double quotes.
*
* @param workingcopy configuration to modify
* @param arg additional VM argument
* @throws CoreException may be thrown by the launch configuration
*/
protected void addVMArgument(ILaunchConfigurationWorkingCopy workingcopy, String arg) throws CoreException {
String vmargskey = getVMArgsKey();
StringBuffer sb = new StringBuffer(workingcopy.getAttribute(vmargskey, "")); //$NON-NLS-1$
if (sb.length() > 0) {
sb.append(' ');
}
if (arg.indexOf(' ') == -1) {
sb.append(arg);
} else {
sb.append('"').append(arg).append('"');
}
workingcopy.setAttribute(vmargskey, sb.toString());
}
protected boolean hasInplaceInstrumentation(ILaunchConfiguration configuration) {
// Inplace instrumentation is required for plugin launches, as we can't
// modify the classpath
return true;
}
protected void modifyConfiguration(ILaunchConfigurationWorkingCopy workingcopy,
ICoverageLaunchInfo info) throws CoreException {
StringBuffer sb = new StringBuffer(BOOTPATHARG);
sb.append(info.getPropertiesJARFile());
sb.append(File.pathSeparatorChar).append(CoverageTools.getEmmaJar().toOSString());
addVMArgument(workingcopy, sb.toString());
}
/*
* We list all source based class files of all plugins in the workspace.
*/
public IClassFiles[] getClassFiles(ILaunchConfiguration configuration, boolean includebinaries) throws CoreException {
IJavaModel model = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot());
IJavaProject[] projects = model.getJavaProjects();
List l = new ArrayList();
for (int i = 0; i < projects.length; i++) {
if (projects[i].getProject().hasNature(PLUGIN_NATURE)) {
IClassFiles[] cf = EclEmmaCorePlugin.getClassFiles(projects[i]);
for (int j = 0; j < cf.length; j++) {
if (!cf[j].isBinary()) l.add(cf[j]);
}
}
}
return (IClassFiles[]) l.toArray(new IClassFiles[0]);
}
}

View File

@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core.launching;
import com.mountainminds.eclemma.internal.core.EclEmmaCorePlugin;
/**
* Constants for coverage specific launch configuration entries.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public interface ICoverageLaunchConfigurationConstants {
/**
* This boolean attribute specifies, whether class files should be
* instrumented in-place. If unspecified inplace instrumentation is not
* performed.
*/
public static final String ATTR_INPLACE_INSTRUMENTATION = EclEmmaCorePlugin.ID
+ ".INPLACE_INSTRUMENTATION"; //$NON-NLS-1$
/**
* List of workspace relative paths for instrumentation. If unspecified all
* output locations of source folders will be instrumented.
*/
public static final String ATTR_INSTRUMENTATION_PATHS = EclEmmaCorePlugin.ID
+ ".INSTRUMENTATION_PATHS"; //$NON-NLS-1$
}

View File

@ -0,0 +1,74 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core.launching;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import com.mountainminds.eclemma.core.IInstrumentation;
/**
* Descriptor how a particular launch was instrumented. To every launch in
* "Coverage" mode an instance is attached.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public interface ICoverageLaunchInfo {
/**
* Returns the location of the coverage data file (<code>*.ec</code>) for this
* launch.
*
* @return absolute path of the coverage data file
*/
public IPath getCoverageFile();
/**
* Instruments the selected class path entries.
*
* @param monitor monitor for progress feedback and cancelation
* @param inplace if <code>true</code>, class files will be directly modified
* @throws CoreException in case of internal inconsistencies
*/
public void instrument(IProgressMonitor monitor, boolean inplace) throws CoreException;
/**
* Returns the list of locations with instrumented class path entries along
* with instumentation meta data.
*
* @return intrumentaion data for class path entries
*/
public IInstrumentation[] getInstrumentations();
/**
* Returns the instrumentation information for the class path with the given
* original path. If this class path entry has not been instrumented
* <code>null</code> is returned.
*
* @param originalpath original class path location
* @return instrumentation information or <code>null</code>
*/
public IInstrumentation getInstrumentation(String originalpath);
/**
* Return the absolute location of the JAR file that will be created to
* inject EMMA properties into the target application.
*
* @return absolute path of the EMMA properties JAR file
*/
public IPath getPropertiesJARFile();
/**
* Allow the implementation to perform internal cleanup when this info object
* is no longer required.
*/
public void dispose();
}

View File

@ -0,0 +1,39 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id: $
******************************************************************************/
package com.mountainminds.eclemma.core.launching;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate2;
import com.mountainminds.eclemma.core.IClassFiles;
/**
* The launch delegate for coverage configurations.
*
* @author Marc R. Hoffmann
* @version $Revision: $
*/
public interface ICoverageLauncher extends ILaunchConfigurationDelegate2 {
/**
* Returns all class file descriptors for the given launch configuration.
*
* @param configuration
* launch configuration to look for class files
* @param includebinaries
* flag whether binary classpath entries should be included
*
* @return descriptors for all class for instrumentation
*
* @throws CoreException
*/
public IClassFiles[] getClassFiles(ILaunchConfiguration configuration, boolean includebinaries) throws CoreException;
}

View File

@ -0,0 +1,30 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.core.launching;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import com.mountainminds.eclemma.internal.core.launching.InstrumentedClasspathProvider;
/**
* Launcher for local Java applications.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class JavaApplicationLauncher extends CoverageLauncher {
protected void modifyConfiguration(ILaunchConfigurationWorkingCopy workingcopy,
ICoverageLaunchInfo info) throws CoreException {
workingcopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH_PROVIDER,
InstrumentedClasspathProvider.ID);
}
}

View File

@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core;
import org.eclipse.osgi.util.NLS;
/**
* Text messages for the core plugin.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class CoreMessages extends NLS {
private static final String BUNDLE_NAME = "com.mountainminds.eclemma.internal.core.coremessages";//$NON-NLS-1$
public static String LaunchSessionDescription_value;
public static String InstrumentingClasses_task;
public static String InstrumentingClassesIn_task;
public static String Launching_task;
public static String AnalyzingCoverageSession_task;
public static String ExportingSession_task;
public static String ImportingSession_task;
public static String ExtractingSourceArchive_task;
public static String StatusINPLACE_INSTRUMENTATION_INFO_message;
public static String StatusNO_LOCAL_EMMAJAR_ERROR_message;
public static String StatusID_CREATION_ERROR_message;
public static String StatusUNKOWN_LAUNCH_TYPE_ERROR_message;
public static String StatusINVALID_CLASSPATH_PROVIDER_CONTEXT_ERROR_message;
public static String StatusMISSING_LAUNCH_INFO_ERROR_message;
public static String StatusEMMA_PROPERTIES_CREATION_ERROR_message;
public static String StatusCOVERAGEDATA_FILE_READ_ERROR_message;
public static String StatusMETADATA_FILE_READ_ERROR_message;
public static String StatusSOURCE_EXTRACTION_ERROR_message;
public static String StatusIMPORT_ERROR_message;
public static String StatusFILE_CONTAINS_NO_METADATA_message;
public static String StatusALREADY_INSTRUMENTED_ERROR_message;
public static String StatusNO_COVERAGE_DATA_ERROR_message;
public static String StatusNO_INSTRUMENTED_CLASSES_message;
static {
NLS.initializeMessages(BUNDLE_NAME, CoreMessages.class);
}
}

View File

@ -0,0 +1,82 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.debug.core.ILaunchConfiguration;
import com.mountainminds.eclemma.core.ICoverageSession;
import com.mountainminds.eclemma.core.IInstrumentation;
/**
* A {@link com.mountainminds.eclemma.core.ICoverageSession} implementation.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class CoverageSession extends PlatformObject implements ICoverageSession {
private final String description;
private final IInstrumentation[] instrumentations;
private final IPath[] coveragedatafiles;
private final ILaunchConfiguration launchconfiguration;
public CoverageSession(String description,
IInstrumentation[] instrumentations, IPath[] coveragedatafiles,
ILaunchConfiguration launchconfiguration) {
this.description = description;
this.instrumentations = instrumentations;
this.coveragedatafiles = coveragedatafiles;
this.launchconfiguration = launchconfiguration;
}
// ICoverageSession implementation
public String getDescription() {
return description;
}
public IInstrumentation[] getInstrumentations() {
return instrumentations;
}
public IPath[] getCoverageDataFiles() {
return this.coveragedatafiles;
}
public ILaunchConfiguration getLaunchConfiguration() {
return launchconfiguration;
}
public ICoverageSession merge(ICoverageSession other, String description) {
List i = merge(instrumentations, other.getInstrumentations());
List c = merge(coveragedatafiles, other.getCoverageDataFiles());
return new CoverageSession(description,
(IInstrumentation[]) i.toArray(new IInstrumentation[i.size()]),
(IPath[]) c.toArray(new IPath[c.size()]), launchconfiguration);
}
private List merge(Object[] arr1, Object[] arr2) {
List l = new ArrayList(Arrays.asList(arr1));
for (int i = 0; i < arr2.length; i++) {
if (!l.contains(arr2[i])) {
l.add(arr2[i]);
}
}
return l;
}
}

View File

@ -0,0 +1,252 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core;
import java.io.PrintStream;
import java.text.MessageFormat;
import org.eclipse.core.runtime.Platform;
/**
* Access to debug options and tracing facilities for this plugin.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public final class DebugOptions {
/**
* Interface for optional trace output.
*/
public interface ITracer {
/**
* Determines whether this tracer is enabled. Clients may use this method to
* avoid expensive calculation for debug output.
*
* @return <code>true</code> if the tracer is enabled
*/
public boolean isEnabled();
/**
* Prints the given debug message if the tracer is enabled.
*
* @param message
* text message for trace output
*/
public void trace(String message);
/**
* Prints the given debug message if the tracer is enabled. The parameter
* object will be inserted for the <code>{x}</code> placeholder.
*
* @param message
* text message for trace output
* @param param1
* parameter object for inserting
*/
public void trace(String message, Object param1);
/**
* Prints the given debug message if the tracer is enabled. The parameter
* object wills be inserted for the <code>{x}</code> placeholder.
*
* @param message
* text message for trace output
* @param param1
* first parameter object for inserting
* @param param2
* first parameter object for inserting
*/
public void trace(String message, Object param1, Object param2);
/**
* Prints the given debug message if the tracer is enabled. The parameter
* object wills be inserted for the <code>{x}</code> placeholder.
*
* @param message
* text message for trace output
* @param param1
* first parameter object for inserting
* @param param2
* first parameter object for inserting
* @param param3
* third parameter object for inserting
*/
public void trace(String message, Object param1, Object param2,
Object param3);
/**
* Starts a timer for the calling thread.
*/
public void startTimer();
/**
* Prints out the elapsed time since starting the timer.
*
* @param message
* identification for the timed period
*/
public void stopTimer(String message);
/**
* Start measuring heap memory usage.
*/
public void startMemoryUsage();
/**
* Print out heap memory usage since starting measurement.
*
* @param message
* identification for this memory usage output
*/
public void stopMemoryUsage(String message);
}
private static final ITracer NUL_TRACER = new ITracer() {
public boolean isEnabled() {
return false;
}
public void trace(String message) {
}
public void trace(String message, Object param1) {
}
public void trace(String message, Object param1, Object param2) {
}
public void trace(String message, Object param1, Object param2,
Object param3) {
}
public void startTimer() {
}
public void stopTimer(String message) {
}
public void startMemoryUsage() {
}
public void stopMemoryUsage(String message) {
}
};
private static class PrintStreamTracer implements ITracer {
private final PrintStream out;
private final String channel;
private final ThreadLocal starttime = new ThreadLocal();
private final ThreadLocal heapsize = new ThreadLocal();
PrintStreamTracer(String channel) {
this(channel, System.out);
}
PrintStreamTracer(String channel, PrintStream out) {
this.channel = channel;
this.out = out;
}
public boolean isEnabled() {
return true;
}
public void trace(String message) {
StringBuffer sb = new StringBuffer();
sb.append('[').append(channel).append("] ").append(message); //$NON-NLS-1$
out.println(sb);
}
private void trace(String message, Object[] params) {
trace(MessageFormat.format(message, params));
}
public void trace(String message, Object param1) {
trace(message, new Object[] { param1 });
}
public void trace(String message, Object param1, Object param2) {
trace(message, new Object[] { param1, param2 });
}
public void trace(String message, Object param1, Object param2,
Object param3) {
trace(message, new Object[] { param1, param2, param3 });
}
public void startTimer() {
starttime.set(new Long(System.currentTimeMillis()));
}
public void stopTimer(String message) {
Long start = (Long) starttime.get();
if (start == null) {
trace("Timer {0} not startet.", message); //$NON-NLS-1$
} else {
long time = System.currentTimeMillis() - start.longValue();
trace("{0} ms for {1}", new Object[] { new Long(time), message }); //$NON-NLS-1$
}
}
public void startMemoryUsage() {
Runtime rt = Runtime.getRuntime();
heapsize.set(new Long(rt.totalMemory() - rt.freeMemory()));
}
public void stopMemoryUsage(String message) {
Long start = (Long) heapsize.get();
if (start == null) {
trace("Memory usage for {0} not started.", message); //$NON-NLS-1$
} else {
Runtime rt = Runtime.getRuntime();
long bytes = rt.totalMemory() - rt.freeMemory() - start.longValue();
trace("{0} bytes for {1}", new Object[] { new Long(bytes), message }); //$NON-NLS-1$
}
}
}
private static final String KEYPREFIX_DEBUG = EclEmmaCorePlugin.ID
+ "/debug/"; //$NON-NLS-1$
private static final String KEY_EMMAVERBOSITYLEVEL = KEYPREFIX_DEBUG
+ "emmaVerbosityLevel"; //$NON-NLS-1$
private static String getOption(String key, String defaultvalue) {
String value = Platform.getDebugOption(key);
return value == null ? defaultvalue : value;
}
private static ITracer getTracer(String channel) {
String key = KEYPREFIX_DEBUG + channel;
if (Boolean.valueOf(Platform.getDebugOption(key)).booleanValue()) {
return new PrintStreamTracer(channel);
} else {
return NUL_TRACER;
}
}
public static final String EMMAVERBOSITYLEVEL = getOption(
KEY_EMMAVERBOSITYLEVEL, "silent"); //$NON-NLS-1$
public static final ITracer PERFORMANCETRACER = getTracer("performance"); //$NON-NLS-1$
public static final ITracer INSTRUMENTATIONTRACER = getTracer("instrumentation"); //$NON-NLS-1$
public static final ITracer LAUNCHINGTRACER = getTracer("launching"); //$NON-NLS-1$
public static final ITracer ANALYSISTRACER = getTracer("analysis"); //$NON-NLS-1$
}

View File

@ -0,0 +1,263 @@
/*******************************************************************************
* Copyright (c) 2006, 2009 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core;
import java.text.MessageFormat;
import java.util.Date;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchListener;
import org.eclipse.debug.core.IStatusHandler;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jdt.core.IElementChangedListener;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.osgi.framework.BundleContext;
import com.mountainminds.eclemma.core.CoverageTools;
import com.mountainminds.eclemma.core.EclEmmaStatus;
import com.mountainminds.eclemma.core.IClassFiles;
import com.mountainminds.eclemma.core.ICorePreferences;
import com.mountainminds.eclemma.core.ICoverageSession;
import com.mountainminds.eclemma.core.ISessionManager;
import com.mountainminds.eclemma.core.launching.ICoverageLaunchInfo;
import com.mountainminds.eclemma.internal.core.instr.ClassFilesStore;
import com.mountainminds.eclemma.internal.core.instr.DefaultInstrumentationFilter;
/**
* Bundle activator for the EclEmma core.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class EclEmmaCorePlugin extends Plugin {
public static final String ID = "com.mountainminds.eclemma.core"; //$NON-NLS-1$
/** Status used to trigger user prompts */
private static final IStatus PROMPT_STATUS = new Status(IStatus.INFO,
"org.eclipse.debug.ui", 200, "", null); //$NON-NLS-1$//$NON-NLS-2$
public static final IPath EMMA_JAR = new Path("/emma.jar"); //$NON-NLS-1$
private static EclEmmaCorePlugin instance;
private ICorePreferences preferences = ICorePreferences.DEFAULT;
private ISessionManager sessionManager;
private JavaCoverageLoader coverageLoader;
private StateFiles stateFiles;
private ClassFilesStore allClassFiles = null;
private ILaunchListener launchListener = new ILaunchListener() {
public void launchRemoved(ILaunch launch) {
if (preferences.getAutoRemoveSessions()) {
sessionManager.removeSession(launch);
}
}
public void launchAdded(ILaunch launch) {
}
public void launchChanged(ILaunch launch) {
}
};
private IDebugEventSetListener debugListener = new IDebugEventSetListener() {
public void handleDebugEvents(DebugEvent[] events) {
for (int i = 0; i < events.length; i++) {
DebugEvent e = events[i];
if (e.getSource() instanceof IProcess
&& e.getKind() == DebugEvent.TERMINATE) {
IProcess proc = (IProcess) e.getSource();
final ILaunch launch = proc.getLaunch();
ICoverageLaunchInfo info = CoverageTools.getLaunchInfo(launch);
if (info != null) {
IPath coveragedatafile = info.getCoverageFile();
if (checkCoverageDataFile(coveragedatafile)) {
Object[] args = new Object[] {
launch.getLaunchConfiguration().getName(), new Date() };
String description = MessageFormat.format(
CoreMessages.LaunchSessionDescription_value, args);
ICoverageSession session = new CoverageSession(description, info
.getInstrumentations(), new IPath[] { coveragedatafile },
launch.getLaunchConfiguration());
sessionManager.addSession(session, preferences
.getActivateNewSessions(), launch);
}
info.dispose();
}
}
}
}
private boolean checkCoverageDataFile(IPath path) {
boolean ok = path.toFile().exists();
if (!ok) {
try {
showPrompt(EclEmmaStatus.NO_COVERAGE_DATA_ERROR.getStatus(), path);
} catch (CoreException e) {
getLog().log(e.getStatus());
}
}
return ok;
}
};
private IElementChangedListener elementListener = new IElementChangedListener() {
public void elementChanged(ElementChangedEvent event) {
synchronized (EclEmmaCorePlugin.this) {
allClassFiles = null;
}
}
};
public void start(BundleContext context) throws Exception {
super.start(context);
sessionManager = new SessionManager();
coverageLoader = new JavaCoverageLoader(sessionManager);
stateFiles = new StateFiles(getStateLocation());
stateFiles.deleteTemporaryFiles();
DebugPlugin.getDefault().getLaunchManager().addLaunchListener(
launchListener);
DebugPlugin.getDefault().addDebugEventListener(debugListener);
JavaCore.addElementChangedListener(elementListener);
instance = this;
}
public void stop(BundleContext context) throws Exception {
instance = null;
stateFiles.deleteTemporaryFiles();
JavaCore.removeElementChangedListener(elementListener);
DebugPlugin.getDefault().removeDebugEventListener(debugListener);
DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(
launchListener);
stateFiles = null;
coverageLoader.dispose();
coverageLoader = null;
sessionManager = null;
super.stop(context);
}
public static EclEmmaCorePlugin getInstance() {
return instance;
}
public void setPreferences(ICorePreferences preferences) {
this.preferences = preferences;
}
/**
* Returns a new filter instance for default selection of instrumemted
* classes.
*
* @return new filter
*/
public DefaultInstrumentationFilter createDefaultIntrumentationFilter() {
return new DefaultInstrumentationFilter(this.preferences);
}
public ISessionManager getSessionManager() {
return sessionManager;
}
public JavaCoverageLoader getJavaCoverageLoader() {
return coverageLoader;
}
public StateFiles getStateFiles() {
return stateFiles;
}
/**
* Issues an user prompt using the statis handler registered for the given
* status.
*
* @param status
* IStatus object to find prompter for
* @param info
* addional information passed to the handler
* @return boolean result returned by the status handler
* @throws CoreException
* if the status has severity error and no handler is available
*/
public boolean showPrompt(IStatus status, Object info) throws CoreException {
IStatusHandler prompter = DebugPlugin.getDefault().getStatusHandler(
PROMPT_STATUS);
if (prompter == null) {
if (status.getSeverity() == IStatus.ERROR) {
throw new CoreException(status);
} else {
return true;
}
} else {
return ((Boolean) prompter.handleStatus(status, info)).booleanValue();
}
}
/**
* Tries to find the absolute path for the given workspace relative path.
*
* @param path
* workspace relative path to resolve
* @return absolute path
*/
public static IPath getAbsolutePath(IPath path) {
if (path.getDevice() == null) {
IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
if (res != null) {
return res.getLocation();
}
}
return path;
}
/**
* Calculates the list of IClassFiles for the given Java project. Basically
* for every separate output location a entry will be returned.
*
* @param project
* Java project to calculate IClassFiles for
* @return aArray of IClassFiles objects
* @throws JavaModelException
* thrown when a problem with the underlying Java model occures
*/
public static IClassFiles[] getClassFiles(IJavaProject project)
throws JavaModelException {
final ClassFilesStore store = new ClassFilesStore();
store.add(project);
return store.getClassFiles();
}
public ClassFilesStore getAllClassFiles() throws CoreException {
ClassFilesStore store = allClassFiles;
if (store == null) {
store = new ClassFilesStore();
store.add(JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()));
allClassFiles = store;
}
return store;
}
}

View File

@ -0,0 +1,45 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core;
import org.eclipse.core.runtime.Platform;
import org.osgi.framework.Bundle;
import org.osgi.framework.Version;
/**
* Some constants to behave version specific in some situations. Unfortunately
* this is necessary as EclEmma works on multiple Eclipse versions and relies on
* internal implementation details.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class EclipseVersion {
public static final Version CURRENT;
public static final Version V320 = new Version("3.2.0"); //$NON-NLS-1$
/**
* Checks whether the current platform version is greater or equal than the
* given version.
*
* @param version version to compare to
* @return true, if the current version is greater or equal than the given one
*/
public static boolean isGreaterOrEqualTo(Version version) {
return CURRENT.compareTo(version) >= 0;
}
static {
Bundle rt = Platform.getBundle(Platform.PI_RUNTIME);
String version = (String) rt.getHeaders().get(org.osgi.framework.Constants.BUNDLE_VERSION);
CURRENT = new Version(version);
}
}

View File

@ -0,0 +1,133 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.osgi.util.NLS;
import com.mountainminds.eclemma.core.ICoverageSession;
import com.mountainminds.eclemma.core.ISessionListener;
import com.mountainminds.eclemma.core.ISessionManager;
import com.mountainminds.eclemma.core.analysis.IJavaCoverageListener;
import com.mountainminds.eclemma.core.analysis.IJavaModelCoverage;
import com.mountainminds.eclemma.internal.core.analysis.SessionAnalyzer;
/**
* Internal utility class that loads the coverage data asynchronously, holds the
* current {@link IJavaModelCoverage} object and sends out events in case of
* changed coverage information.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class JavaCoverageLoader {
private final ISessionManager sessionManager;
private ICoverageSession activeSession;
private IJavaModelCoverage coverage;
private final List listeners = new ArrayList();
private ISessionListener sessionListener = new ISessionListener() {
public void sessionActivated(ICoverageSession session) {
activeSession = session;
// TODO Looks like this has no effect
Platform.getJobManager().cancel(LOADJOB);
if (session == null) {
coverage = null;
fireCoverageChanged();
} else {
coverage = IJavaModelCoverage.LOADING;
fireCoverageChanged();
new LoadSessionJob(activeSession).schedule();
}
}
public void sessionAdded(ICoverageSession addedSession) {
}
public void sessionRemoved(ICoverageSession removedSession) {
}
};
private static final Object LOADJOB = new Object();
private class LoadSessionJob extends Job {
private final ICoverageSession session;
public LoadSessionJob(ICoverageSession session) {
super(NLS.bind(CoreMessages.AnalyzingCoverageSession_task, session.getDescription()));
this.session = session;
}
protected IStatus run(IProgressMonitor monitor) {
IJavaModelCoverage c;
try {
c = new SessionAnalyzer().processSession(session, monitor);
} catch (CoreException e) {
return e.getStatus();
}
coverage = monitor.isCanceled() ? null : c;
fireCoverageChanged();
return Status.OK_STATUS;
}
public boolean belongsTo(Object family) {
return family == LOADJOB;
}
};
public JavaCoverageLoader(ISessionManager sessionManager) {
this.sessionManager = sessionManager;
sessionManager.addSessionListener(sessionListener);
}
public void addJavaCoverageListener(IJavaCoverageListener l) {
if (l == null)
throw new NullPointerException();
if (!listeners.contains(l)) {
listeners.add(l);
}
}
public void removeJavaCoverageListener(IJavaCoverageListener l) {
listeners.remove(l);
}
protected void fireCoverageChanged() {
// avoid concurrent modification issues
Iterator i = new ArrayList(listeners).iterator();
while (i.hasNext()) {
((IJavaCoverageListener) i.next()).coverageChanged();
}
}
public IJavaModelCoverage getJavaModelCoverage() {
return coverage;
}
public void dispose() {
sessionManager.removeSessionListener(sessionListener);
}
}

View File

@ -0,0 +1,165 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.osgi.util.NLS;
import com.mountainminds.eclemma.core.EclEmmaStatus;
import com.mountainminds.eclemma.core.ICoverageSession;
import com.mountainminds.eclemma.core.IInstrumentation;
import com.mountainminds.eclemma.core.ISessionExporter;
import com.mountainminds.eclemma.core.ISourceLocation;
import com.vladium.emma.data.DataFactory;
import com.vladium.emma.data.ICoverageData;
import com.vladium.emma.data.IMergeable;
import com.vladium.emma.data.IMetaData;
import com.vladium.emma.data.ISessionData;
import com.vladium.emma.data.SessionData;
import com.vladium.emma.report.IReportProperties;
import com.vladium.emma.report.ReportProcessor;
/**
* Implementation of ISessionExporter.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class SessionExporter implements ISessionExporter {
private static final String PROP_OUT_FILE = IReportProperties.PREFIX + IReportProperties.OUT_FILE;
private static final String PROP_OUT_ENCODING = IReportProperties.PREFIX + IReportProperties.OUT_ENCODING;
private static final String OUTPUT_ENCODING = "UTF-8"; //$NON-NLS-1$
private final ICoverageSession session;
private int format;
private String destination;
private Properties options;
public SessionExporter(ICoverageSession session) {
this.session = session;
}
public void setFormat(int format) {
this.format = format;
}
public void setDestination(String filename) {
this.destination = filename;
}
public void setReportOptions(Properties options) {
this.options = options;
}
public void export(IProgressMonitor monitor) throws CoreException {
if (format == EMMA_FORMAT) {
createSessionFile(monitor);
} else {
createReport(monitor);
}
}
private void createReport(IProgressMonitor monitor) throws CoreException {
IInstrumentation[] instrs = session.getInstrumentations();
IPath[] coveragefiles = session.getCoverageDataFiles();
monitor.beginTask(NLS.bind(CoreMessages.ExportingSession_task, session.getDescription()),
instrs.length + coveragefiles.length + 1);
List datapath = new ArrayList();
List sourcepath = new ArrayList();
for (int i = 0; i < instrs.length; i++) {
if (instrs[i].getMetaDataFile().toFile().exists()) {
datapath.add(instrs[i].getMetaDataFile().toOSString());
if (format == HTML_FORMAT) {
ISourceLocation[] srcs = instrs[i].getClassFiles().getSourceLocations();
IProgressMonitor srcmonitor = new SubProgressMonitor(monitor, 1);
srcmonitor.beginTask("", srcs.length); //$NON-NLS-1$
for (int j = 0; j < srcs.length; j++) {
srcs[j].extract(new SubProgressMonitor(srcmonitor, 1));
sourcepath.add(srcs[j].getPath().toOSString());
}
srcmonitor.done();
} else {
monitor.worked(1);
}
} else {
monitor.worked(1);
}
}
for (int i = 0; i < coveragefiles.length; i++) {
datapath.add(coveragefiles[i].toOSString());
monitor.worked(1);
}
ReportProcessor processor = ReportProcessor.create();
processor.setDataPath((String[]) datapath.toArray(new String[0]));
processor.setSourcePath((String[]) sourcepath.toArray(new String[0]));
processor.setReportTypes(new String[] { DEFAULT_EXTENSIONS[format] });
Properties props = new Properties(options);
props.setProperty(PROP_OUT_FILE, destination);
props.setProperty(PROP_OUT_ENCODING, OUTPUT_ENCODING);
processor.setPropertyOverrides(props);
processor.run();
monitor.done();
}
private void createSessionFile(IProgressMonitor monitor) throws CoreException {
IInstrumentation[] instrs = session.getInstrumentations();
IPath[] coveragefiles = session.getCoverageDataFiles();
monitor.beginTask(NLS.bind(CoreMessages.ExportingSession_task, session.getDescription()),
instrs.length + coveragefiles.length + 1);
IMergeable metadata = null;
for (int i = 0; i < instrs.length; i++) {
metadata = loadDataFile(metadata, DataFactory.TYPE_METADATA, instrs[i].getMetaDataFile());
monitor.worked(1);
}
IMergeable coveragedata = null;
for (int i = 0; i < coveragefiles.length; i++) {
coveragedata = loadDataFile(coveragedata, DataFactory.TYPE_COVERAGEDATA, coveragefiles[i]);
monitor.worked(1);
}
ISessionData sessiondata = new SessionData((IMetaData) metadata, (ICoverageData) coveragedata);
try {
DataFactory.persist(sessiondata, new File(destination), false);
} catch (IOException e) {
throw new CoreException(EclEmmaStatus.COVERAGEDATA_FILE_READ_ERROR
.getStatus(destination, e));
}
monitor.done();
}
private IMergeable loadDataFile(IMergeable data, int type, IPath path)
throws CoreException {
try {
File f = path.toFile();
if (f.exists()) {
IMergeable newdata = DataFactory.load(f)[type];
data = data == null ? newdata : data.merge(newdata);
}
return data;
} catch (IOException e) {
if (type == DataFactory.TYPE_COVERAGEDATA) {
throw new CoreException(EclEmmaStatus.COVERAGEDATA_FILE_READ_ERROR
.getStatus(path, e));
} else {
throw new CoreException(EclEmmaStatus.METADATA_FILE_READ_ERROR
.getStatus(path, e));
}
}
}
}

View File

@ -0,0 +1,142 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import com.mountainminds.eclemma.core.CoverageTools;
import com.mountainminds.eclemma.core.EclEmmaStatus;
import com.mountainminds.eclemma.core.IClassFiles;
import com.mountainminds.eclemma.core.ICoverageSession;
import com.mountainminds.eclemma.core.IInstrumentation;
import com.mountainminds.eclemma.core.ISessionImporter;
/**
* Implementation of ISessionImporter.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class SessionImporter implements ISessionImporter {
private String description;
private String coveragefile;
private IClassFiles[] classfiles;
private boolean copy;
private boolean useImportedMetaData;
public void setDescription(String description) {
this.description = description;
}
public void setCoverageFile(String file) {
this.coveragefile = file;
}
public void setClassFiles(IClassFiles[] classfiles) {
this.classfiles = classfiles;
}
public void setCopy(boolean copy) {
this.copy = copy;
}
public void setUseImportedMetaData(boolean flag) {
this.useImportedMetaData = flag;
}
public void importSession(IProgressMonitor monitor) throws CoreException {
monitor.beginTask(CoreMessages.ImportingSession_task, 2);
IInstrumentation[] instr = instrument(new SubProgressMonitor(monitor, 1));
IPath[] cfiles = new IPath[1];
cfiles[0] = createCopy(new SubProgressMonitor(monitor, 1));
ICoverageSession s = CoverageTools.createCoverageSession(description, instr, cfiles, null);
CoverageTools.getSessionManager().addSession(s, true, null);
monitor.done();
}
private IInstrumentation[] instrument(IProgressMonitor monitor) throws CoreException {
monitor.beginTask("", classfiles.length); //$NON-NLS-1$
IInstrumentation[] instr = new IInstrumentation[classfiles.length];
for (int i = 0; i < classfiles.length; i++) {
if (useImportedMetaData) {
instr[i] = new ExternalInstrumentation(classfiles[i], coveragefile);
monitor.worked(1);
} else {
instr[i] = classfiles[i].instrument(false, new SubProgressMonitor(monitor, 1));
}
}
monitor.done();
return instr;
}
private IPath createCopy(IProgressMonitor monitor) throws CoreException {
IPath file = Path.fromOSString(coveragefile);
if (copy) {
file = EclEmmaCorePlugin.getInstance().getStateFiles().getImportSessionFile(file);
File source = new File(coveragefile);
monitor.beginTask("", (int) source.length()); //$NON-NLS-1$
byte[] buffer = new byte[0x1000];
try {
InputStream in = new FileInputStream(source);
OutputStream out = new FileOutputStream(file.toFile());
int l;
while ((l = in.read(buffer)) != -1) {
out.write(buffer, 0, l);
monitor.worked(l);
}
in.close();
out.close();
} catch (IOException e) {
throw new CoreException(EclEmmaStatus.IMPORT_ERROR.getStatus(e));
}
}
monitor.done();
return file;
}
private static class ExternalInstrumentation implements IInstrumentation {
private final IClassFiles classfiles;
private final IPath metaDataFile;
ExternalInstrumentation(IClassFiles classfiles, String metaDataFile) {
this.classfiles = classfiles;
this.metaDataFile = Path.fromOSString(metaDataFile);
}
public IClassFiles getClassFiles() {
return classfiles;
}
public IPath getMetaDataFile() {
return metaDataFile;
}
public IPath getOutputLocation() {
throw new UnsupportedOperationException("Unsupported for imported sessions."); //$NON-NLS-1$
}
public boolean isInplace() {
throw new UnsupportedOperationException("Unsupported for imported sessions."); //$NON-NLS-1$
}
}
}

View File

@ -0,0 +1,150 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.mountainminds.eclemma.core.ICoverageSession;
import com.mountainminds.eclemma.core.ISessionListener;
import com.mountainminds.eclemma.core.ISessionManager;
/**
* ISessionManager implementation.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class SessionManager implements ISessionManager {
private List sessions = new ArrayList();
private Map keymap = new HashMap();
private ICoverageSession activeSession = null;
private List listeners = new ArrayList();
public void addSession(ICoverageSession session, boolean activate, Object key) {
if (session == null) throw new NullPointerException();
if (!sessions.contains(session)) {
sessions.add(session);
if (key != null) {
keymap.put(key, session);
}
fireSessionAdded(session);
if (activate) {
activeSession = session;
fireSessionActivated(session);
}
}
}
public void removeSession(ICoverageSession session) {
if (sessions.contains(session)) {
boolean sessionActivated = false;
if (session.equals(activeSession)) {
activeSession = null;
for (int i = sessions.size(); --i >= 0;) {
if (!session.equals(sessions.get(i))) {
activeSession = (ICoverageSession) sessions.get(i);
break;
}
}
sessionActivated = true;
}
sessions.remove(session);
keymap.values().remove(session);
fireSessionRemoved(session);
if (sessionActivated) {
fireSessionActivated(activeSession);
}
}
}
public void removeSession(Object key) {
removeSession(getSession(key));
}
public void removeAllSessions() {
while (!sessions.isEmpty()) {
ICoverageSession session = (ICoverageSession) sessions.remove(0);
keymap.values().remove(session);
fireSessionRemoved(session);
}
if (activeSession != null) {
activeSession = null;
fireSessionActivated(null);
}
}
public ICoverageSession[] getSessions() {
return (ICoverageSession[]) sessions.toArray(new ICoverageSession[sessions.size()]);
}
public ICoverageSession getSession(Object key) {
return (ICoverageSession) keymap.get(key);
}
public void activateSession(ICoverageSession session) {
if (sessions.contains(session) && !session.equals(activeSession)) {
activeSession = session;
fireSessionActivated(session);
}
}
public void activateSession(Object key) {
activateSession(getSession(key));
}
public ICoverageSession getActiveSession() {
return activeSession;
}
public void refreshActiveSession() {
if (activeSession != null) {
fireSessionActivated(activeSession);
}
}
public void addSessionListener(ISessionListener listener) {
if (listener == null) throw new NullPointerException();
if (!listeners.contains(listener)) {
listeners.add(listener);
}
}
public void removeSessionListener(ISessionListener listener) {
listeners.remove(listener);
}
protected void fireSessionAdded(ICoverageSession session) {
// avoid concurrent modification issues
Iterator i = new ArrayList(listeners).iterator();
while (i.hasNext()) {
((ISessionListener) i.next()).sessionAdded(session);
}
}
protected void fireSessionRemoved(ICoverageSession session) {
// avoid concurrent modification issues
Iterator i = new ArrayList(listeners).iterator();
while (i.hasNext()) {
((ISessionListener) i.next()).sessionRemoved(session);
}
}
private void fireSessionActivated(ICoverageSession session) {
// avoid concurrent modification issues
Iterator i = new ArrayList(listeners).iterator();
while (i.hasNext()) {
((ISessionListener) i.next()).sessionActivated(session);
}
}
}

View File

@ -0,0 +1,169 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import com.mountainminds.eclemma.core.EclEmmaStatus;
/**
* Internal utility to manage files in the plugin's state locations.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class StateFiles {
private static final String LAUNCHDATA_FOLDER = ".launch/"; //$NON-NLS-1$
private static final String INSTRDATA_FOLDER = ".instr/"; //$NON-NLS-1$
private static final String IMPORTDATA_FOLDER = ".import/"; //$NON-NLS-1$
private static final String SOURCE_FOLDER = ".src/"; //$NON-NLS-1$
private static final ReferenceQueue CLEANUPQUEUE = new ReferenceQueue();
private static final Set CLEANUPFILES = new HashSet();
private final IPath stateLocation;
public StateFiles(IPath stateLocation) {
this.stateLocation = stateLocation;
this.stateLocation.toFile().mkdirs();
getLaunchDataFolder().toFile().mkdirs();
getInstrDataFolder().toFile().mkdirs();
getSourceDataFolder().toFile().mkdirs();
getImportDataFolder().toFile().mkdirs();
}
public void deleteTemporaryFiles() {
deleteFiles(getLaunchDataFolder().toFile(), false);
deleteFiles(getInstrDataFolder().toFile(), false);
deleteFiles(getSourceDataFolder().toFile(), false);
deleteFiles(getImportDataFolder().toFile(), false);
}
private static void deleteFiles(File file, boolean deleteparent) {
if (file.isDirectory()) {
File[] files = file.listFiles();
for (int i = 0; files != null && i < files.length; i++) {
deleteFiles(files[i], true);
}
}
if (deleteparent) file.delete();
}
public IPath getLaunchDataFolder() {
return stateLocation.append(LAUNCHDATA_FOLDER);
}
private IPath getInstrDataFolder() {
return stateLocation.append(INSTRDATA_FOLDER);
}
public IPath getInstrDataFolder(IPath location) throws CoreException {
return getInstrDataFolder().append(getInternalId(location, false));
}
private IPath getSourceDataFolder() {
return stateLocation.append(SOURCE_FOLDER);
}
public IPath getSourceFolder(IPath location) throws CoreException {
return getSourceDataFolder().append(getInternalId(location, true));
}
private IPath getImportDataFolder() {
return stateLocation.append(IMPORTDATA_FOLDER);
}
public IPath getImportSessionFile(IPath original) throws CoreException {
IPath p = getImportDataFolder().append(getInternalId(original, true));
registerForCleanup(p);
return p;
}
private static String getInternalId(IPath location, boolean withtimestamp) throws CoreException {
long timestamp = 0;
if (withtimestamp) {
File f = location.toFile();
if (f.exists()) {
timestamp = f.lastModified();
}
}
StringBuffer sb = new StringBuffer();
try {
MessageDigest md = MessageDigest.getInstance("MD5"); //$NON-NLS-1$
md.update(location.toString().getBytes("UTF8")); //$NON-NLS-1$
md.update(Long.toHexString(timestamp).getBytes("UTF8")); //$NON-NLS-1$
byte[] sig = md.digest();
for (int i = 0; i < sig.length; i++) {
sb.append(Character.forDigit((sig[i] >> 4) & 0xf, 0x10));
sb.append(Character.forDigit(sig[i] & 0xf, 0x10));
}
} catch (NoSuchAlgorithmException e) {
throw new CoreException(EclEmmaStatus.ID_CREATION_ERROR.getStatus(e));
} catch (UnsupportedEncodingException e) {
throw new CoreException(EclEmmaStatus.ID_CREATION_ERROR.getStatus(e));
}
return sb.toString();
}
/**
* Registers the file the given path points to for deletion as soon as the
* reference to the path objects gets garbage collected. The caller must
* ensure to hold a reference to the given path object as long as the file
* is required. The file is not required to (jet) actually exist.
*
* @param file path object that points to the file
*/
public void registerForCleanup(IPath file) {
cleanupObsoleteFiles();
CLEANUPFILES.add(new CleanupFile(file));
}
private void cleanupObsoleteFiles() {
while (true) {
CleanupFile f = (CleanupFile) CLEANUPQUEUE.poll();
if (f == null) {
break;
}
CLEANUPFILES.remove(f);
f.delete();
}
}
private static class CleanupFile extends PhantomReference {
private final File file;
public CleanupFile(IPath path) {
super(path, CLEANUPQUEUE);
this.file = path.toFile();
}
public void delete() {
deleteFiles(file, true);
clear();
}
}
}

View File

@ -0,0 +1,149 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core.analysis;
import com.mountainminds.eclemma.core.analysis.ICounter;
/**
* ICounter implementations. Implementing a factory pattern allows to share
* counter instances.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public abstract class Counter implements ICounter {
/** Max counter value for which singletons are created */
private static final int SINGLETON_LIMIT = 10;
private static final Counter[][] SINGLETONS = new Counter[SINGLETON_LIMIT + 1][];
static {
for (int i = 0; i <= SINGLETON_LIMIT; i++) {
SINGLETONS[i] = new Counter[i + 1];
for (int j = 0; j <= i; j++)
SINGLETONS[i][j] = new Fix(i, j);
}
}
/** Constant for Counter with 0/0 values. */
public static final Counter COUNTER_0_0 = SINGLETONS[0][0];
/**
* Mutable version of the counter.
*/
private static class Var extends Counter {
public Var(long total, long covered) {
super(total, covered);
}
public Counter increment(int total, int covered) {
this.total += total;
this.covered += covered;
return this;
}
}
/**
* Immutable version of the counter.
*/
private static class Fix extends Counter {
public Fix(long total, long covered) {
super(total, covered);
}
public Counter increment(int total, int covered) {
return getInstance(this.total + total, this.covered + covered);
}
}
/**
* Factory method to retrieve a counter with the given number of items.
*
* @param total
* total number of items
* @param covered
* covered number of items
* @return counter instance
*/
public static Counter getInstance(long total, long covered) {
if (total <= SINGLETON_LIMIT && covered <= total) {
return SINGLETONS[(int) total][(int) covered];
} else {
return new Var(total, covered);
}
}
protected long total;
protected long covered;
protected Counter(long total, long covered) {
this.total = total;
this.covered = covered;
}
/**
* Returns a counter with incremented values. It is up to the implementation
* whether this conter instance is modified or a new instance is returned.
*
* @param total
* number of additional total items
* @param covered
* number of additional covered items
* @return counter instance with incremented values
*/
public abstract Counter increment(int total, int covered);
// ICounter implementation
public long getTotalCount() {
return total;
}
public long getCoveredCount() {
return covered;
}
public long getMissedCount() {
return total - covered;
}
public double getRatio() {
return (double) covered / (double) total;
}
public int compareTo(Object obj) {
ICounter counter = (ICounter) obj;
return Double.compare(getRatio(), counter.getRatio());
}
public boolean equals(Object obj) {
if (obj instanceof ICounter) {
ICounter counter = (ICounter) obj;
return getTotalCount() == counter.getTotalCount()
&& getCoveredCount() == counter.getCoveredCount();
} else {
return false;
}
}
public int hashCode() {
long t = getTotalCount();
long c = 17 * getCoveredCount();
return (int) (t ^ (t >>> 32) ^ c ^ (c >>> 32));
}
public String toString() {
StringBuffer b = new StringBuffer("Counter["); //$NON-NLS-1$
b.append(getCoveredCount());
b.append('/').append(getTotalCount());
b.append(']');
return b.toString();
}
}

View File

@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core.analysis;
import org.eclipse.jdt.core.IJavaElement;
/**
* This internal interface may be implemented by coverage objects. It allows
* binding its children lazily to the corresponding Java model elements.
*
* children lazily to t
* @author Marc R. Hoffmann
* @version $Revision$
*/
public interface ILazyBinding {
/**
* Called to bind the children of this coverage object lazily to the
* corresponding Java model elements.
*
* @param element the Java element corresponding to this coverage object
* @param modelcoverage the coverage object for the Java model itself
*/
public void resolve(IJavaElement element, JavaModelCoverage modelcoverage);
}

View File

@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core.analysis;
import org.eclipse.jdt.core.IType;
/**
* Callback used by {@link TypeTraverser} to report traversed types.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public interface ITypeVisitor {
/**
* Called for every type.
*
* @param type
* Java model handle
* @param binaryname
* VM name of the type (e.g. <code>java/util/Map$Entry</code>)
*/
public void visit(IType type, String binaryname);
/**
* Called after all types have been visited.
*/
public void done();
}

View File

@ -0,0 +1,130 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core.analysis;
import org.eclipse.core.resources.IResource;
import com.mountainminds.eclemma.core.analysis.ICounter;
import com.mountainminds.eclemma.core.analysis.IJavaElementCoverage;
import com.mountainminds.eclemma.core.analysis.ILineCoverage;
/**
* IJavaElementCoverage implementation.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class JavaElementCoverage implements IJavaElementCoverage {
private Counter typeCounter;
private Counter methodCounter;
private Counter blockCounter;
private Counter lineCounter;
private Counter instructionsCounter;
private final JavaElementCoverage parent;
private final Lines lines;
private final long modificationStamp;
public JavaElementCoverage(JavaElementCoverage parent, boolean haslines,
long stamp) {
this.parent = parent;
typeCounter = Counter.COUNTER_0_0;
methodCounter = Counter.COUNTER_0_0;
blockCounter = Counter.COUNTER_0_0;
instructionsCounter = Counter.COUNTER_0_0;
lineCounter = haslines ? null : Counter.COUNTER_0_0;
modificationStamp = stamp;
this.lines = haslines ? new Lines() : null;
}
public JavaElementCoverage(JavaElementCoverage parent, boolean haslines,
IResource resource) {
this(parent, haslines, resource == null ? 0 : resource
.getModificationStamp());
}
public void addBlock(int instructions, int[] lines, boolean covered) {
addBlock(instructions, lines, covered, 0, 0);
}
private void addBlock(int instructions, int[] lines, boolean covered,
int totalLineDelta, int coveredLineDelta) {
blockCounter = blockCounter.increment(1, covered ? 1 : 0);
instructionsCounter = instructionsCounter.increment(instructions,
covered ? instructions : 0);
if (this.lines == null || lines == null) {
if (lineCounter != null) {
lineCounter = lineCounter.increment(totalLineDelta, coveredLineDelta);
}
if (parent != null) {
parent.addBlock(instructions, lines, covered, totalLineDelta,
coveredLineDelta);
}
} else {
long totalDelta = this.lines.getTotalCount();
long coveredDelta = this.lines.getCoveredCount();
this.lines.addLines(lines, covered);
if (parent != null) {
totalDelta = this.lines.getTotalCount() - totalDelta;
coveredDelta = this.lines.getCoveredCount() - coveredDelta;
parent.addBlock(instructions, lines, covered, (int) totalDelta,
(int) coveredDelta);
}
}
}
public void addMethod(boolean covered) {
methodCounter = methodCounter.increment(1, covered ? 1 : 0);
if (parent != null) {
parent.addMethod(covered);
}
}
public void addType(boolean covered) {
typeCounter = typeCounter.increment(1, covered ? 1 : 0);
if (parent != null) {
parent.addType(covered);
}
}
// IJavaElementCoverage implementation:
public ICounter getBlockCounter() {
return blockCounter;
}
public ICounter getLineCounter() {
if (lines == null) {
return lineCounter;
} else {
return lines;
}
}
public ICounter getInstructionCounter() {
return instructionsCounter;
}
public ILineCoverage getLineCoverage() {
return lines;
}
public ICounter getMethodCounter() {
return methodCounter;
}
public ICounter getTypeCounter() {
return typeCounter;
}
public long getResourceModificationStamp() {
return modificationStamp;
}
}

View File

@ -0,0 +1,56 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core.analysis;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.jdt.core.IJavaElement;
import com.mountainminds.eclemma.core.CoverageTools;
import com.mountainminds.eclemma.core.analysis.IJavaElementCoverage;
import com.mountainminds.eclemma.core.analysis.IJavaModelCoverage;
import com.mountainminds.eclemma.core.analysis.ILineCoverage;
/**
* This factory adapts IResource and IJavaElement objects to the corresponding
* coverage information of the current session. The factory is hooked into the
* workbench through the extension point
* <code>org.eclipse.core.runtime.adapters</code>.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class JavaElementCoverageAdapterFactory implements IAdapterFactory {
public Object getAdapter(Object object, Class adapterType) {
// if the object is a IResource find the corresponding IJavaElement
if (object instanceof IResource) {
object = ((IResource) object).getAdapter(IJavaElement.class);
if (object == null) {
return null;
}
}
// then find the coverage information from the current session
IJavaModelCoverage mc = CoverageTools.getJavaModelCoverage();
if (mc == null) {
return null;
} else {
IJavaElementCoverage coverage = mc.getCoverageFor((IJavaElement) object);
if (coverage != null && ILineCoverage.class.equals(adapterType)) {
return coverage.getLineCoverage();
} else {
return coverage;
}
}
}
public Class[] getAdapterList() {
return new Class[] { IJavaElementCoverage.class, ILineCoverage.class };
}
}

View File

@ -0,0 +1,107 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core.analysis;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import com.mountainminds.eclemma.core.analysis.IJavaElementCoverage;
import com.mountainminds.eclemma.core.analysis.IJavaModelCoverage;
/**
* The IJavaModelCoverage implementation maps Java elements to its corresponding
* coverage data objects.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class JavaModelCoverage extends JavaElementCoverage implements
IJavaModelCoverage {
/** Maps Java elements to coverage objects */
private final Map coveragemap = new HashMap();
/** List of all IJavaProject objects with coverage information attached */
private final List projects = new ArrayList();
/** List of all IPackageFragmentRoot objects with coverage information attached */
private final List fragmentroots = new ArrayList();
/** List of all IPackageFragment objects with coverage information attached */
private final List fragments = new ArrayList();
/** List of all IType objects with coverage information attached */
private final List types = new ArrayList();
public JavaModelCoverage() {
super(null, false, 0);
}
public void put(IJavaElement element, IJavaElementCoverage coverage) {
coveragemap.put(element, coverage);
switch (element.getElementType()) {
case IJavaElement.JAVA_PROJECT:
projects.add(element);
break;
case IJavaElement.PACKAGE_FRAGMENT_ROOT:
fragmentroots.add(element);
break;
case IJavaElement.PACKAGE_FRAGMENT:
fragments.add(element);
break;
case IJavaElement.TYPE:
types.add(element);
break;
}
}
// IJavaModelCoverage interface
public IJavaProject[] getInstrumentedProjects() {
IJavaProject[] arr = new IJavaProject[projects.size()];
return (IJavaProject[]) projects.toArray(arr);
}
public IPackageFragmentRoot[] getInstrumentedPackageFragmentRoots() {
IPackageFragmentRoot[] arr = new IPackageFragmentRoot[fragmentroots.size()];
return (IPackageFragmentRoot[]) fragmentroots.toArray(arr);
}
public IPackageFragment[] getInstrumentedPackageFragments() {
IPackageFragment[] arr = new IPackageFragment[fragments.size()];
return (IPackageFragment[]) fragments.toArray(arr);
}
public IType[] getInstrumentedTypes() {
IType[] arr = new IType[types.size()];
return (IType[]) types.toArray(arr);
}
public IJavaElementCoverage getCoverageFor(IJavaElement element) {
IJavaElementCoverage c = (IJavaElementCoverage) coveragemap.get(element);
// Currently lazy binding is for methods only:
if (c == null && element.getElementType() == IJavaElement.METHOD) {
IJavaElement parent = element.getParent();
Object parentcoverage = getCoverageFor(parent);
if (parentcoverage instanceof ILazyBinding) {
((ILazyBinding) parentcoverage).resolve(parent, this);
}
c = (IJavaElementCoverage) coveragemap.get(element);
}
return c;
}
}

View File

@ -0,0 +1,134 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core.analysis;
import com.mountainminds.eclemma.core.analysis.ILineCoverage;
/**
* ILineCoverage implementation.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class Lines extends Counter implements ILineCoverage {
/**
* We always increase the size of the coverage array by multiples of this
* constant. Larger values will require more memory, a lower value will lead
* to repeated memory allocation and copy operations.
*/
private static final int BLOCK_INCREMENT = 64;
/** Array of flags for each line */
private byte[] coverage = null;
private int firstline = 0;
private int lastline = 0;
private int offset = 0;
protected Lines() {
super(0, 0);
}
private int getBlockAlignedOffset(int line) {
return line - (line % BLOCK_INCREMENT);
}
private int getBlockAlignedSize(int size) {
return size + BLOCK_INCREMENT - (size % BLOCK_INCREMENT);
}
/**
* Updates the firstline and lastline property. If the given line falls
* outside the coverage array the array is increased accordingly.
*
* @param line
* line number to check
*/
private void ensureCapacity(int line) {
if (coverage == null) {
firstline = line;
lastline = line;
offset = getBlockAlignedOffset(line);
coverage = new byte[BLOCK_INCREMENT];
return;
}
if (firstline > line) {
firstline = line;
if (offset > line) {
int newoffset = getBlockAlignedOffset(line);
byte[] newcoverage = new byte[coverage.length + offset - newoffset];
System.arraycopy(coverage, 0, newcoverage, offset - newoffset,
coverage.length);
offset = newoffset;
coverage = newcoverage;
}
return;
}
if (lastline < line) {
lastline = line;
if (line - offset >= coverage.length) {
byte[] newcoverage = new byte[getBlockAlignedSize(line - offset)];
System.arraycopy(coverage, 0, newcoverage, 0, coverage.length);
coverage = newcoverage;
}
}
}
public void addLines(int lines[], boolean isCovered) {
for (int i = 0; i < lines.length; i++) {
int line = lines[i];
ensureCapacity(line);
int idx = line - offset;
switch (coverage[idx]) {
case NO_CODE:
total++;
if (isCovered)
covered++;
break;
case NOT_COVERED:
if (isCovered)
covered++;
break;
}
coverage[idx] |= isCovered ? FULLY_COVERED : NOT_COVERED;
}
}
public Counter increment(int total, int covered) {
throw new UnsupportedOperationException();
}
// ILineCoverage interface:
public byte[] getCoverage() {
return coverage;
}
public int getFirstLine() {
return firstline;
}
public int getLastLine() {
return lastline;
}
public int getOffset() {
return offset;
}
public byte getCoverage(int line) {
if (coverage == null || line < firstline || line > lastline) {
return NO_CODE;
}
return coverage[line - offset];
}
}

View File

@ -0,0 +1,113 @@
/*******************************************************************************
* Copyright (c) 2006, 2009 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id: $
******************************************************************************/
package com.mountainminds.eclemma.internal.core.analysis;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
/**
* Internal utility to select methods by their binary signature. For performance
* optimization matching is performed in two steps, where the first step should
* quickly identify methods in most situations: Identification by name and
* parameter count. Only if the first step does fails to identify a method
* unambiguously the parameter types are resolved in a second step.
*
* @author Marc R. Hoffmann
* @version $Revision: $
*/
public class MethodLocator {
/** Special value to identify ambiguous entries in {@link #indexParamCount} */
private static final Object AMBIGUOUS = new Object();
/** Index on methods by name and parameter count. */
private final Map indexParamCount = new HashMap();
/** Index on methods by name and parameter signature. */
private final Map indexParamSignature = new HashMap();
private final IType type;
/**
* Initializes a new locator for method search within the given type.
*
* @param type
* type to search methods in
* @throws JavaModelException
*/
public MethodLocator(final IType type) throws JavaModelException {
this.type = type;
final IMethod[] methods = type.getMethods();
for (int i = 0; i < methods.length; i++) {
addToIndex(methods[i]);
}
}
/**
* Searches for the method with the given binary name.
*
* @param name
* binary method name
* @param signature
* binary method signature
* @return method or <code>null</code>
*/
public IMethod findMethod(String name, String signature) {
if (name.equals("<init>")) { //$NON-NLS-1$
name = type.getElementName();
}
final Object value = indexParamCount.get(createParamCountKey(name,
signature));
if (value == AMBIGUOUS) {
return (IMethod) indexParamSignature.get(createParamSignatureKey(name,
signature));
}
return (IMethod) value;
}
private void addToIndex(final IMethod method) throws JavaModelException {
final String paramCountKey = createParamCountKey(method);
final Object existing = indexParamCount.get(paramCountKey);
if (existing == null) {
indexParamCount.put(paramCountKey, method);
return;
}
if (existing != AMBIGUOUS) {
indexParamCount.put(paramCountKey, AMBIGUOUS);
final IMethod m = (IMethod) existing;
indexParamSignature.put(createParamSignatureKey(m), m);
}
indexParamSignature.put(createParamSignatureKey(method), method);
}
private String createParamCountKey(final IMethod method) {
return method.getElementName() + "@" + method.getParameterTypes().length; //$NON-NLS-1$
}
private String createParamCountKey(final String name,
final String fullSignature) {
return name + "@" + Signature.getParameterCount(fullSignature); //$NON-NLS-1$
}
private String createParamSignatureKey(final IMethod method)
throws JavaModelException {
return method.getElementName() + "#" //$NON-NLS-1$
+ SignatureResolver.getParameters(method);
}
private String createParamSignatureKey(final String name,
final String fullSignature) {
return name + "#" + SignatureResolver.getParameters(fullSignature); //$NON-NLS-1$
}
}

View File

@ -0,0 +1,210 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core.analysis;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.osgi.util.NLS;
import com.mountainminds.eclemma.core.EclEmmaStatus;
import com.mountainminds.eclemma.core.ICoverageSession;
import com.mountainminds.eclemma.core.IInstrumentation;
import com.mountainminds.eclemma.core.analysis.IJavaModelCoverage;
import com.mountainminds.eclemma.internal.core.CoreMessages;
import com.mountainminds.eclemma.internal.core.DebugOptions;
import com.mountainminds.eclemma.internal.core.DebugOptions.ITracer;
import com.mountainminds.eclemma.internal.core.analysis.TypeCoverage.UnboundMethodCoverage;
import com.vladium.emma.data.ClassDescriptor;
import com.vladium.emma.data.DataFactory;
import com.vladium.emma.data.ICoverageData;
import com.vladium.emma.data.IMergeable;
import com.vladium.emma.data.IMetaData;
import com.vladium.emma.data.MethodDescriptor;
import com.vladium.emma.data.ICoverageData.DataHolder;
/**
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class SessionAnalyzer {
private static final ITracer TRACER = DebugOptions.ANALYSISTRACER;
private static final ITracer PERFORMANCE = DebugOptions.PERFORMANCETRACER;
private JavaModelCoverage modelcoverage;
public IJavaModelCoverage processSession(ICoverageSession session, IProgressMonitor monitor)
throws CoreException {
PERFORMANCE.startTimer();
PERFORMANCE.startMemoryUsage();
modelcoverage = new JavaModelCoverage();
IPath[] coveragefiles = session.getCoverageDataFiles();
IInstrumentation[] instrumentations = session.getInstrumentations();
monitor.beginTask(NLS.bind(CoreMessages.AnalyzingCoverageSession_task, session.getDescription()),
coveragefiles.length + instrumentations.length);
ICoverageData coveragedata = null;
for (int i = 0; i < coveragefiles.length && !monitor.isCanceled(); i++) {
coveragedata = processCoveragedataFile(coveragedata, coveragefiles[i]);
monitor.worked(1);
}
for (int i = 0; i < instrumentations.length && !monitor.isCanceled(); i++) {
processMetadataFile(coveragedata, instrumentations[i],
new SubProgressMonitor(monitor, 1));
}
monitor.done();
PERFORMANCE.stopTimer("loading " + session.getDescription()); //$NON-NLS-1$
PERFORMANCE.stopMemoryUsage("loading " + session.getDescription()); //$NON-NLS-1$
return modelcoverage;
}
private ICoverageData processCoveragedataFile(ICoverageData coveragedata,
IPath path) throws CoreException {
try {
File f = path.toFile();
if (f.exists()) {
IMergeable data = DataFactory.load(f)[DataFactory.TYPE_COVERAGEDATA];
if (coveragedata == null) {
coveragedata = (ICoverageData) data;
} else {
coveragedata = (ICoverageData) coveragedata.merge(data);
}
}
return coveragedata;
} catch (IOException e) {
throw new CoreException(EclEmmaStatus.COVERAGEDATA_FILE_READ_ERROR
.getStatus(path, e));
}
}
private void processMetadataFile(ICoverageData coveragedata, IInstrumentation instrumentation,
IProgressMonitor monitor) throws CoreException {
IPath metadatafile = instrumentation.getMetaDataFile();
File f = metadatafile.toFile();
if (f.exists()) {
IMetaData metadata;
try {
metadata = (IMetaData) DataFactory.load(f)[DataFactory.TYPE_METADATA];
} catch (IOException e) {
throw new CoreException(EclEmmaStatus.METADATA_FILE_READ_ERROR.getStatus(
metadatafile, e));
}
if (metadata == null) {
throw new CoreException(EclEmmaStatus.FILE_CONTAINS_NO_METADATA.getStatus(
metadatafile));
}
IPackageFragmentRoot[] roots = instrumentation.getClassFiles().getPackageFragmentRoots();
TypeTraverser jep = new TypeTraverser(roots);
jep.process(new TypeVisitor(metadata, coveragedata), monitor);
}
}
private class TypeVisitor implements ITypeVisitor {
private final ICoverageData coveragedata;
private final Map descriptors;
TypeVisitor(IMetaData metadata, ICoverageData coveragedata) {
this.coveragedata = coveragedata;
this.descriptors = new HashMap();
for (Iterator i = metadata.iterator(); i.hasNext(); ) {
ClassDescriptor cd = (ClassDescriptor) i.next();
descriptors.put(cd.getClassVMName(), cd);
}
}
public void visit(IType type, String vmname) {
ClassDescriptor descriptor = (ClassDescriptor) descriptors.remove(vmname);
if (descriptor != null) {
DataHolder data = coveragedata == null ? null : coveragedata.getCoverage(descriptor);
if (data != null && data.m_stamp != descriptor.getStamp()) {
TRACER.trace("Invalid meta data signature for {0}.", descriptor.getClassVMName()); //$NON-NLS-1$
} else {
TypeCoverage typecoverage = (TypeCoverage) getCoverage(type, true);
IResource resource = type.getResource();
typecoverage.addType(data != null);
MethodDescriptor[] methods = descriptor.getMethods();
UnboundMethodCoverage[] ubcoverage = new UnboundMethodCoverage[methods.length];
boolean[][] covered = data == null ? null : data.m_coverage;
for (int i = 0; i < methods.length; i++) {
ubcoverage[i] = processMethodCoverage(methods[i], covered == null ? null : covered[i], typecoverage, resource);
}
typecoverage.setUnboundMethods(ubcoverage);
}
}
}
public void done() {
// dump what's left
for (Iterator i = descriptors.keySet().iterator(); i.hasNext(); ) {
TRACER.trace("Instrumented type {0} has not been processed.", i.next()); //$NON-NLS-1$
}
}
}
private boolean isMethodCovered(boolean[] blocks) {
for (int i = 0; blocks != null && i < blocks.length; i++) {
if (blocks[i]) return true;
}
return false;
}
private UnboundMethodCoverage processMethodCoverage(MethodDescriptor descriptor, boolean[] covered, JavaElementCoverage parentcoverage, IResource resource) {
JavaElementCoverage coverage = new JavaElementCoverage(parentcoverage, descriptor.hasLineNumberInfo(), resource);
coverage.addMethod(isMethodCovered(covered));
int[] blocksizes = descriptor.getBlockSizes();
if (blocksizes != null) {
int blockcount = blocksizes.length;
int[][] blocklines = descriptor.getBlockMap();
for (int i = 0; i < blockcount; i++) {
coverage.addBlock(blocksizes[i], blocklines == null ? null : blocklines[i],
covered == null ? false : covered[i]);
}
}
return new UnboundMethodCoverage(descriptor.getName(), descriptor.getDescriptor(), coverage);
}
private JavaElementCoverage getCoverage(IJavaElement element, boolean haslines) {
if (element == null)
return null;
JavaElementCoverage c = (JavaElementCoverage) modelcoverage.getCoverageFor(element);
if (c == null) {
switch (element.getElementType()) {
case IJavaElement.JAVA_MODEL:
c = modelcoverage;
break;
case IJavaElement.JAVA_PROJECT:
case IJavaElement.PACKAGE_FRAGMENT_ROOT:
case IJavaElement.PACKAGE_FRAGMENT:
c = new JavaElementCoverage(getCoverage(element.getParent(), false), false, element.getResource());
break;
case IJavaElement.TYPE:
c = new TypeCoverage(getCoverage(element.getParent(), haslines), haslines, element.getResource());
break;
default:
c = new JavaElementCoverage(getCoverage(element.getParent(), haslines), haslines, element.getResource());
break;
}
modelcoverage.put(element, c);
}
return c;
}
}

View File

@ -0,0 +1,157 @@
/*******************************************************************************
* Copyright (c) 2006, 2009 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id: $
******************************************************************************/
package com.mountainminds.eclemma.internal.core.analysis;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeParameter;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
/**
* Utility to get a resolved binary signature from a given method.
*
* @author Marc R. Hoffmann
* @version $Revision: $
*/
public final class SignatureResolver {
private static final String EMPTY = ""; //$NON-NLS-1$
private static final String OBJECT = "Ljava/lang/Object;"; //$NON-NLS-1$
private static final char SLASH = '/';
/**
* Extracts the parameter part from the given signature, i.e. the substring
* contained in braces.
*
* @param signature
* method signature
* @return parameter part only
*/
public static String getParameters(final String signature) {
final int pos = signature.lastIndexOf(')');
// avoid String instances for methods without parameters
return pos == 1 ? EMPTY : signature.substring(1, pos);
}
/**
* Extracts the resolved binary parameters from the given method
*
* @param method
* method to resolve
* @return binary parameter specification
*/
public static String getParameters(final IMethod method)
throws JavaModelException {
if (method.isBinary()) {
return getParameters(method.getSignature());
}
final StringBuffer buffer = new StringBuffer();
final String[] parameterTypes = method.getParameterTypes();
for (int i = 0; i < parameterTypes.length; i++) {
resolveArrayParameterType(method, parameterTypes[i], buffer);
}
return buffer.toString();
}
private static final void resolveArrayParameterType(final IMethod method,
final String parameterType, final StringBuffer result)
throws JavaModelException {
final int arrayCount = Signature.getArrayCount(parameterType);
for (int i = 0; i < arrayCount; i++) {
result.append(Signature.C_ARRAY);
}
resolveParameterType(method, parameterType.substring(arrayCount), result);
}
private static final void resolveParameterType(final IMethod method,
final String parameterType, final StringBuffer result)
throws JavaModelException {
final char kind = parameterType.charAt(0);
switch (kind) {
case Signature.C_UNRESOLVED:
final String identifier = parameterType.substring(1, parameterType
.length() - 1);
if (resolveType(method.getDeclaringType(), identifier, result)) {
return;
}
if (resolveTypeParameter(method, identifier, result)) {
return;
}
break;
}
result.append(parameterType);
}
private static final boolean resolveType(final IType scope,
final String identifier, final StringBuffer result)
throws JavaModelException {
final String[][] types = scope.resolveType(Signature
.getTypeErasure(identifier));
if (types == null || types.length != 1) {
return false;
}
result.append(Signature.C_RESOLVED);
final String qualifier = types[0][0];
if (qualifier.length() > 0) {
replace(qualifier, Signature.C_DOT, SLASH, result);
result.append(SLASH);
}
replace(types[0][1], Signature.C_DOT, Signature.C_DOLLAR, result);
result.append(Signature.C_SEMICOLON);
return true;
}
private static final boolean resolveTypeParameter(final IMethod method,
final String identifier, final StringBuffer result)
throws JavaModelException {
IType type = method.getDeclaringType();
if (resolveTypeParameter(type, method.getTypeParameters(), identifier,
result)) {
return true;
}
while (type != null) {
if (resolveTypeParameter(type, type.getTypeParameters(), identifier,
result)) {
return true;
}
type = type.getDeclaringType();
}
return false;
}
private static final boolean resolveTypeParameter(final IType context,
final ITypeParameter[] typeParameters, final String identifier,
final StringBuffer result) throws JavaModelException {
for (int i = 0; i < typeParameters.length; i++) {
final ITypeParameter p = typeParameters[i];
if (identifier.equals(p.getElementName())) {
final String[] bounds = p.getBounds();
if (bounds.length == 0) {
result.append(OBJECT);
return true;
} else {
return resolveType(context, bounds[0], result);
}
}
}
return false;
}
private static final void replace(final String source, final char oldChar,
final char newChar, final StringBuffer result) {
final int len = source.length();
for (int i = 0; i < len; i++) {
final char c = source.charAt(i);
result.append(c == oldChar ? newChar : c);
}
}
}

View File

@ -0,0 +1,86 @@
/*******************************************************************************
* Copyright (c) 2006, 2009 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core.analysis;
import org.eclipse.core.resources.IResource;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import com.mountainminds.eclemma.core.analysis.IJavaElementCoverage;
import com.mountainminds.eclemma.internal.core.DebugOptions;
import com.mountainminds.eclemma.internal.core.DebugOptions.ITracer;
/**
* Coverage for types elements.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class TypeCoverage extends JavaElementCoverage implements ILazyBinding {
private static final ITracer TRACER = DebugOptions.ANALYSISTRACER;
public static class UnboundMethodCoverage {
final String name;
final String signature;
final IJavaElementCoverage coverage;
UnboundMethodCoverage(String name, String signature,
IJavaElementCoverage coverage) {
this.name = name;
this.signature = signature;
this.coverage = coverage;
}
}
private UnboundMethodCoverage[] ubmethods;
public TypeCoverage(JavaElementCoverage parent, boolean haslines, long stamp) {
super(parent, haslines, stamp);
ubmethods = null;
}
public TypeCoverage(JavaElementCoverage parent, boolean haslines,
IResource resource) {
super(parent, haslines, resource);
ubmethods = null;
}
public void setUnboundMethods(UnboundMethodCoverage[] ubmethods) {
this.ubmethods = ubmethods;
}
public void resolve(IJavaElement element, JavaModelCoverage modelcoverage) {
if (ubmethods != null) {
final IType type = (IType) element;
final MethodLocator locator;
try {
locator = new MethodLocator(type);
for (int i = 0; i < ubmethods.length; i++) {
final String name = ubmethods[i].name;
final String signature = ubmethods[i].signature;
final IMethod method = locator.findMethod(name, signature);
if (method != null) {
modelcoverage.put(method, ubmethods[i].coverage);
} else {
TRACER
.trace(
"Method not found in Java model: {0}.{1}{2}", type.getFullyQualifiedName(), name, signature); //$NON-NLS-1$
}
}
} catch (JavaModelException e) {
TRACER.trace("Error while creating method locator for {0}: {1}", type //$NON-NLS-1$
.getFullyQualifiedName(), e);
}
ubmethods = null;
}
}
}

View File

@ -0,0 +1,219 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core.analysis;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import com.mountainminds.eclemma.internal.core.DebugOptions;
import com.mountainminds.eclemma.internal.core.DebugOptions.ITracer;
/**
* Internal utility class for traversal of all types within a list of package
* fragment roots.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class TypeTraverser {
private static final ITracer TRACER = DebugOptions.ANALYSISTRACER;
private final IPackageFragmentRoot[] roots;
/**
* Creates a traverser for the given list of package fragment roots.
*
* @param roots
* list of package fragment roots for traversal
*/
public TypeTraverser(IPackageFragmentRoot[] roots) {
this.roots = roots;
}
/**
* Processes all types and methods reporting all types found to the given
* {@link ITypeVisitor} instance.
*
* @param visitor
* type visitor
* @param monitor
* progress monitor to report progress and allow cancelation
* @throws JavaModelException
* thrown by the underlying Java model
*/
public void process(ITypeVisitor visitor, IProgressMonitor monitor)
throws JavaModelException {
monitor.beginTask("", roots.length); //$NON-NLS-1$
for (int i = 0; i < roots.length && !monitor.isCanceled(); i++) {
processPackageFragmentRoot(visitor, roots[i], new SubProgressMonitor(
monitor, 1));
}
visitor.done();
monitor.done();
}
private void processPackageFragmentRoot(ITypeVisitor visitor,
IPackageFragmentRoot root, IProgressMonitor monitor)
throws JavaModelException {
if (isOnClasspath(root)) {
IJavaElement[] fragments = root.getChildren();
monitor.beginTask("", fragments.length); //$NON-NLS-1$
for (int i = 0; i < fragments.length && !monitor.isCanceled(); i++) {
IPackageFragment fragment = (IPackageFragment) fragments[i];
IProgressMonitor submonitor = new SubProgressMonitor(monitor, 1);
processPackageFragment(visitor, fragment, submonitor);
}
} else {
TRACER.trace("Package fragment root {0} not on classpath.", //$NON-NLS-1$
root.getPath());
}
monitor.done();
}
/**
* This methods checks whether the given package fragment root is still on the
* classpath. This check is required as the user might change the classpath
* and old coverage sessions afterwards (SF #1836551).
*
* @param root package fragment root
* @return true, if the classpath entry still exists
* @throws JavaModelException
*/
private boolean isOnClasspath(IPackageFragmentRoot root)
throws JavaModelException {
IPath path = root.getPath();
IJavaProject project = root.getJavaProject();
return project.findPackageFragmentRoot(path) != null;
}
private void processPackageFragment(ITypeVisitor visitor,
IPackageFragment fragment, IProgressMonitor monitor)
throws JavaModelException {
switch (fragment.getKind()) {
case IPackageFragmentRoot.K_SOURCE:
ICompilationUnit[] units = fragment.getCompilationUnits();
monitor.beginTask("", units.length); //$NON-NLS-1$
for (int i = 0; i < units.length && !monitor.isCanceled(); i++) {
processCompilationUnit(visitor, units[i], monitor);
monitor.worked(1);
}
break;
case IPackageFragmentRoot.K_BINARY:
IClassFile[] classfiles = fragment.getClassFiles();
monitor.beginTask("", classfiles.length); //$NON-NLS-1$
for (int i = 0; i < classfiles.length && !monitor.isCanceled(); i++) {
processClassFile(visitor, classfiles[i], monitor);
monitor.worked(1);
}
break;
}
monitor.done();
}
private void processCompilationUnit(ITypeVisitor visitor,
ICompilationUnit unit, IProgressMonitor monitor)
throws JavaModelException {
IType[] types = unit.getTypes();
for (int i = 0; i < types.length && !monitor.isCanceled(); i++) {
IType type = types[i];
processType(visitor, new BinaryTypeName(type), type, monitor);
}
}
private void processClassFile(ITypeVisitor visitor, IClassFile file,
IProgressMonitor monitor) throws JavaModelException {
IType type = file.getType();
processType(visitor, new BinaryTypeName(type), type, monitor);
}
private void processType(ITypeVisitor visitor, BinaryTypeName btn,
IType type, IProgressMonitor monitor) throws JavaModelException {
String binaryname = btn.toString();
monitor.subTask(binaryname);
visitor.visit(type, binaryname);
IJavaElement[] children = type.getChildren();
for (int i = 0; i < children.length && !monitor.isCanceled(); i++) {
IJavaElement child = children[i];
switch (child.getElementType()) {
case IJavaElement.TYPE:
IType nestedtype = (IType) child;
processType(visitor, btn.nest(nestedtype), nestedtype, monitor);
break;
case IJavaElement.METHOD:
case IJavaElement.INITIALIZER:
case IJavaElement.FIELD:
processAnonymousInnerTypes(visitor, btn, (IMember) child, monitor);
break;
}
}
}
private void processAnonymousInnerTypes(ITypeVisitor visitor,
BinaryTypeName btn, IMember member, IProgressMonitor monitor)
throws JavaModelException {
IJavaElement[] types = member.getChildren();
for (int i = 0; i < types.length && !monitor.isCanceled(); i++) {
IType type = (IType) types[i];
processType(visitor, btn.nest(type), type, monitor);
}
}
/**
* Internal utility to calculate binary names of nested classes.
*/
private static class BinaryTypeName {
private static class Ctr {
private int i = 0;
public int inc() {
return ++i;
}
}
private final String rootname;
private final String typename;
private final Ctr ctr;
private BinaryTypeName(String rootname, String typename, Ctr ctr) {
this.rootname = rootname;
this.typename = typename;
this.ctr = ctr;
}
public BinaryTypeName(IType roottype) {
this.rootname = roottype.getFullyQualifiedName().replace('.', '/');
this.typename = this.rootname;
this.ctr = new Ctr();
}
public BinaryTypeName nest(IType type) throws JavaModelException {
if (type.isAnonymous()) {
return new BinaryTypeName(rootname, rootname + '$' + ctr.inc(), ctr);
} else {
return new BinaryTypeName(rootname, typename + '$' + type.getElementName(), ctr);
}
}
public String toString() {
return typename;
}
}
}

View File

@ -0,0 +1,33 @@
#*******************************************************************************
# Copyright (c) 2006 Mountainminds GmbH & Co. KG
# This software is provided under the terms of the Eclipse Public License v1.0
# See http://www.eclipse.org/legal/epl-v10.html.
#
# $Id$
#*******************************************************************************
# English messages for the core plug-in.
LaunchSessionDescription_value={0} ({1,date,medium} {1,time,medium})
InstrumentingClasses_task=Instrumenting classes
InstrumentingClassesIn_task=Instrumenting classes in {0}
Launching_task=Launching {0}
AnalyzingCoverageSession_task=Analyzing coverage session {0}
ExportingSession_task=Exporting coverage session {0}
ImportingSession_task=Importing coverage session
ExtractingSourceArchive_task=Extracting source archive {0}
StatusINPLACE_INSTRUMENTATION_INFO_message=Code will be instrumented inplace. (code {0})
StatusNO_LOCAL_EMMAJAR_ERROR_message=No local emma.jar available (code {0}).
StatusID_CREATION_ERROR_message=Error while creating internal id (code {0}).
StatusUNKOWN_LAUNCH_TYPE_ERROR_message=Unknown launch type {1} (code {0}).
StatusINVALID_CLASSPATH_PROVIDER_CONTEXT_ERROR_message=Invalid execution context for coverage runtime classpath provider (code {0}).
StatusMISSING_LAUNCH_INFO_ERROR_message=Coverage launch info object is missing (code {0}).
StatusEMMA_PROPERTIES_CREATION_ERROR_message=Error while creating emma properties archive at {1} (code {0}).
StatusCOVERAGEDATA_FILE_READ_ERROR_message=Error while reading coverage data file {1} (code {0}).
StatusMETADATA_FILE_READ_ERROR_message=Error while reading meta data file {1} (code {0}).
StatusSOURCE_EXTRACTION_ERROR_message=Error while extracting source archive {1} (code {0}).
StatusIMPORT_ERROR_message=Error while importing coverage session (code {0}).
StatusFILE_CONTAINS_NO_METADATA_message=File {1} does not contain meta data (code {0}).
StatusALREADY_INSTRUMENTED_ERROR_message=Trying to instrument instrumented class files (code {0}).
StatusNO_COVERAGE_DATA_ERROR_message=No coverage file has been created during coverage launch. Make sure that EMMA is not already configured within your project (code {0}).
StatusNO_INSTRUMENTED_CLASSES_message=No classes are selected for instrumentation (code {0}).

View File

@ -0,0 +1,157 @@
/*******************************************************************************
* Copyright (c) 2006, 2009 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core.instr;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.osgi.util.NLS;
import com.mountainminds.eclemma.core.IClassFiles;
import com.mountainminds.eclemma.core.IInstrumentation;
import com.mountainminds.eclemma.core.ISourceLocation;
import com.mountainminds.eclemma.internal.core.CoreMessages;
import com.mountainminds.eclemma.internal.core.DebugOptions;
import com.mountainminds.eclemma.internal.core.EclEmmaCorePlugin;
import com.mountainminds.eclemma.internal.core.DebugOptions.ITracer;
import com.vladium.emma.AppLoggers;
import com.vladium.emma.instr.InstrProcessor;
import com.vladium.emma.instr.InstrProcessor.OutMode;
/**
* Implementation of IClassFiles.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class ClassFiles implements IClassFiles {
private static final ITracer PERFORMANCE = DebugOptions.PERFORMANCETRACER;
private static final String METADATAFILE_EXT = "em"; //$NON-NLS-1$
private final IPackageFragmentRoot[] roots;
private final IPath location;
private final boolean binary;
/**
* Create a new instance containing a single package fragment root with the
* given class file location.
*
* @param root
* package fragment root
* @param location
* location of the class files
* @throws JavaModelException
* thrown when a problem with the underlying Java model occures
*/
public ClassFiles(IPackageFragmentRoot root, IPath location)
throws JavaModelException {
this(new IPackageFragmentRoot[] { root }, location,
root.getKind() == IPackageFragmentRoot.K_BINARY);
}
private ClassFiles(IPackageFragmentRoot[] roots, IPath location,
boolean binary) {
this.roots = roots;
this.location = location;
this.binary = binary;
}
/**
* Creates a new ClassFiles instance with the given package fragment root
* added. Mixing source and binary package fragment roots will result in an
* exception.
*
* @param root
* the package fragment root to add
* @return new instance
* @throws JavaModelException
* thrown when a problem with the underlying Java model occures
*/
public ClassFiles addRoot(IPackageFragmentRoot root)
throws JavaModelException {
IPackageFragmentRoot[] newroots = new IPackageFragmentRoot[roots.length + 1];
System.arraycopy(roots, 0, newroots, 0, roots.length);
newroots[roots.length] = root;
return new ClassFiles(newroots, location, binary
&& root.getKind() == IPackageFragmentRoot.K_BINARY);
}
public String toString() {
final StringBuffer sb = new StringBuffer(getClass().getName());
sb.append("[").append(location).append("]"); //$NON-NLS-1$//$NON-NLS-2$
return sb.toString();
}
// IClassFiles implementation
public boolean isBinary() {
return binary;
}
public IPackageFragmentRoot[] getPackageFragmentRoots() {
return roots;
}
public IPath getLocation() {
return location;
}
public ISourceLocation[] getSourceLocations() throws JavaModelException {
List l = new ArrayList();
for (int i = 0; i < roots.length; i++) {
ISourceLocation location = SourceLocation.findLocation(roots[i]);
if (location != null) {
l.add(location);
}
}
ISourceLocation[] array = new ISourceLocation[l.size()];
return (ISourceLocation[]) l.toArray(array);
}
public IInstrumentation instrument(boolean inplace, IProgressMonitor monitor)
throws CoreException {
PERFORMANCE.startTimer();
monitor.beginTask(NLS.bind(CoreMessages.InstrumentingClassesIn_task,
location), 1);
IPath outputlocation = EclEmmaCorePlugin.getInstance().getStateFiles()
.getInstrDataFolder(location);
outputlocation.toFile().mkdirs();
IPath metadatafile = outputlocation.addFileExtension(METADATAFILE_EXT);
if (inplace) {
InstrMarker.mark(location);
outputlocation = EclEmmaCorePlugin.getAbsolutePath(location);
}
InstrProcessor processor = InstrProcessor.create();
processor.setInstrPath(new String[] { EclEmmaCorePlugin.getAbsolutePath(
location).toOSString() }, true);
processor.setInstrOutDir(outputlocation.toOSString());
processor.setMetaOutFile(metadatafile.toOSString());
processor.setMetaOutMerge(Boolean.TRUE);
processor.setOutMode(inplace ? OutMode.OUT_MODE_OVERWRITE
: OutMode.OUT_MODE_COPY);
Properties props = new Properties();
props.put(AppLoggers.PROPERTY_VERBOSITY_LEVEL,
DebugOptions.EMMAVERBOSITYLEVEL);
processor.setPropertyOverrides(props);
processor.run();
monitor.done();
PERFORMANCE.stopTimer("instrumenting " + location); //$NON-NLS-1$
return new Instrumentation(this, inplace, outputlocation, metadatafile);
}
}

View File

@ -0,0 +1,124 @@
/*******************************************************************************
* Copyright (c) 2006, 2009 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id: ClassFiles.java 519 2009-01-28 20:09:45Z mtnminds $
******************************************************************************/
package com.mountainminds.eclemma.internal.core.instr;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import com.mountainminds.eclemma.core.IClassFiles;
import com.mountainminds.eclemma.internal.core.EclEmmaCorePlugin;
/**
* Support for creation and access for {@link IClassFiles} objects.
*
* @author Marc R. Hoffmann
* @version $Revision: $
*/
public class ClassFilesStore {
private final Map locationIndex = new HashMap();
/**
* Adds the given package fragment root.
*
* @param root
* package fragment root to add
* @throws JavaModelException
* might be thrown by the underlying Java model
*/
public void add(IPackageFragmentRoot root) throws JavaModelException {
final IPath location = getClassFileLocation(root);
final String absolute = EclEmmaCorePlugin.getAbsolutePath(location)
.toOSString();
ClassFiles classfiles = (ClassFiles) locationIndex.get(absolute);
if (classfiles == null) {
classfiles = new ClassFiles(root, location);
} else {
classfiles = classfiles.addRoot(root);
}
locationIndex.put(absolute, classfiles);
}
/**
* Adds all class files of the given Java project.
*
* @param javaProject
* Java project to add
* @throws JavaModelException
* might be thrown by the underlying Java model
*/
public void add(IJavaProject javaProject) throws JavaModelException {
final IPackageFragmentRoot[] roots = javaProject.getPackageFragmentRoots();
for (int i = 0; i < roots.length; i++) {
add(roots[i]);
}
}
/**
* Adds all class files of all projects of the Java model.
*
* @param javaModel
* Java model to add
* @throws JavaModelException
* might be thrown by the underlying Java model
*/
public void add(IJavaModel javaModel) throws JavaModelException {
final IJavaProject[] javaProjects = javaModel.getJavaProjects();
for (int i = 0; i < javaProjects.length; i++) {
add(javaProjects[i]);
}
}
/**
* Returns all contained {@link IClassFiles} objects.
*
* @return
*/
public IClassFiles[] getClassFiles() {
final List l = new ArrayList(locationIndex.values());
return (IClassFiles[]) l.toArray(new IClassFiles[l.size()]);
}
/**
* Returns the {@link IClassFiles} object with the given absolute location on
* the local file system.
*
* @param location
* absolute location
* @return {@link IClassFiles} object or <code>null</code>
*
*/
public IClassFiles getAtAbsoluteLocation(String location) {
return (IClassFiles) locationIndex.get(location);
}
private static IPath getClassFileLocation(IPackageFragmentRoot root)
throws JavaModelException {
IPath path;
if (root.getKind() == IPackageFragmentRoot.K_SOURCE) {
IClasspathEntry entry = root.getRawClasspathEntry();
path = entry.getOutputLocation();
if (path == null) {
path = root.getJavaProject().getOutputLocation();
}
} else {
path = root.getPath();
}
return path;
}
}

View File

@ -0,0 +1,127 @@
/*******************************************************************************
* Copyright (c) 2006 ,2009 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id: $
******************************************************************************/
package com.mountainminds.eclemma.internal.core.instr;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.launching.JavaRuntime;
import com.mountainminds.eclemma.core.IClassFiles;
import com.mountainminds.eclemma.core.ICorePreferences;
/**
* Utility to retrieve the list of {@link IClassFiles} that will be instrumented
* by default.
*
* @author Marc R. Hoffmann
* @version $Revision: $
*/
public class DefaultInstrumentationFilter {
private final ICorePreferences preferences;
/**
* Creates a new filter based on the given preferences.
*
* @param preferences
* call-back to retrieve current settings from.
*/
public DefaultInstrumentationFilter(final ICorePreferences preferences) {
this.preferences = preferences;
}
/**
* Returns a filtered copy of the given {@link IClassFiles} array.
*
* @param classfiles
* {@link IClassFiles} to filter
* @param configuration
* context information
* @return filtered list
* @throws CoreException
* may occur when accessing the Java model
*/
public IClassFiles[] filter(final IClassFiles[] classfiles,
final ILaunchConfiguration configuration) throws CoreException {
final List list = new ArrayList(Arrays.asList(classfiles));
if (preferences.getDefaultInstrumentationSourceFoldersOnly()) {
sourceFoldersOnly(list);
}
if (preferences.getDefaultInstrumentationSameProjectOnly()) {
sameProjectOnly(list, configuration);
}
String filter = preferences.getDefaultInstrumentationFilter();
if (filter != null && filter.length() > 0) {
matchingPathsOnly(list, filter);
}
return (IClassFiles[]) list.toArray(new IClassFiles[list.size()]);
}
private void sourceFoldersOnly(final List list) {
for (final Iterator i = list.iterator(); i.hasNext();) {
final IClassFiles c = (IClassFiles) i.next();
if (c.isBinary()) {
i.remove();
}
}
}
private void sameProjectOnly(final List list,
final ILaunchConfiguration configuration) throws CoreException {
final IJavaProject javaProject = JavaRuntime.getJavaProject(configuration);
if (javaProject != null) {
for (final Iterator i = list.iterator(); i.hasNext();) {
if (!isSameProject((IClassFiles) i.next(), javaProject)) {
i.remove();
}
}
}
}
private boolean isSameProject(final IClassFiles classfiles,
final IJavaProject javaProject) {
final IPackageFragmentRoot[] roots = classfiles.getPackageFragmentRoots();
for (int i = 0; i < roots.length; i++) {
if (javaProject.equals(roots[i].getJavaProject())) {
return true;
}
}
return false;
}
private void matchingPathsOnly(final List list, final String filter) {
final String[] matchStrings = filter.split(","); //$NON-NLS-1$
for (final Iterator i = list.iterator(); i.hasNext();) {
if (!isPathMatch((IClassFiles) i.next(), matchStrings)) {
i.remove();
}
}
}
private boolean isPathMatch(final IClassFiles classfiles,
final String[] matchStrings) {
final IPackageFragmentRoot[] roots = classfiles.getPackageFragmentRoots();
for (int i = 0; i < roots.length; i++) {
final String path = roots[i].getPath().toString();
for (int j = 0; j < matchStrings.length; j++) {
if (path.indexOf(matchStrings[j]) != -1) {
return true;
}
}
}
return false;
}
}

View File

@ -0,0 +1,76 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id: $
******************************************************************************/
package com.mountainminds.eclemma.internal.core.instr;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Date;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
/**
* Static utilities to mark instrumented output folders. The mark created as a
* special file in the output directory, which will be deleted during a clean
* build.
*
* @author Marc R. Hoffmann
* @version $Revision: $
*/
public class InstrMarker {
private static final String MARKERFILE = ".emma_instrumented"; //$NON-NLS-1$
/**
* Sets a mark on the given output folder.
*
* @param path
* workspace relative path of the output folder
* @throws CoreException
* Thrown when creating the marker file fails
*/
public static void mark(IPath path) throws CoreException {
IFolder folder = getFolder(path);
if (folder != null) {
IFile marker = folder.getFile(MARKERFILE);
if (!marker.exists()) {
marker.create(getMarkerContent(), true, null);
marker.setDerived(true);
}
}
}
/**
* Checks whether the given output folder has an instrumentation mark.
*
* @param path
* workspace relative path of the output folder
* @return <code>true</true> if the mark exists
*/
public static boolean isMarked(IPath path) {
IFolder folder = getFolder(path);
return folder == null ? false : folder.getFile(MARKERFILE).exists();
}
private static IFolder getFolder(IPath path) {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IResource res = root.findMember(path);
return res instanceof IFolder ? (IFolder) res : null;
}
private static InputStream getMarkerContent() {
String text = "Class files instrumented at " + new Date(); //$NON-NLS-1$
return new ByteArrayInputStream(text.getBytes());
}
}

View File

@ -0,0 +1,64 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core.instr;
import org.eclipse.core.runtime.IPath;
import com.mountainminds.eclemma.core.IClassFiles;
import com.mountainminds.eclemma.core.IInstrumentation;
/**
* Implementation of {@link IInstrumentation}.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class Instrumentation implements IInstrumentation {
private final IClassFiles classfiles;
private final boolean inplace;
private final IPath outputlocation;
private final IPath metadatafile;
public Instrumentation(IClassFiles classfiles, boolean inplace,
IPath outputlocation, IPath metadatafile) {
this.classfiles = classfiles;
this.inplace = inplace;
this.outputlocation = outputlocation;
this.metadatafile = metadatafile;
}
public boolean isInplace() {
return inplace;
}
public IClassFiles getClassFiles() {
return classfiles;
}
public IPath getOutputLocation() {
return outputlocation;
}
public IPath getMetaDataFile() {
return metadatafile;
}
public boolean equals(Object obj) {
if (obj instanceof IInstrumentation) {
return metadatafile.equals(((IInstrumentation) obj).getMetaDataFile());
} else {
return false;
}
}
public int hashCode() {
return metadatafile.hashCode();
}
}

View File

@ -0,0 +1,132 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core.instr;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.osgi.util.NLS;
import com.mountainminds.eclemma.core.EclEmmaStatus;
import com.mountainminds.eclemma.core.ISourceLocation;
import com.mountainminds.eclemma.internal.core.CoreMessages;
import com.mountainminds.eclemma.internal.core.EclEmmaCorePlugin;
/**
* Implementation of {@link ISourceLocation}.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class SourceLocation implements ISourceLocation {
private static final String JAVA_EXT = ".java"; //$NON-NLS-1$
public static ISourceLocation findLocation(IPackageFragmentRoot root)
throws JavaModelException {
if (root.getKind() == IPackageFragmentRoot.K_SOURCE) {
IPath path = EclEmmaCorePlugin.getAbsolutePath(root.getPath());
return new SourceLocation(path, new Path(
IPackageFragmentRoot.DEFAULT_PACKAGEROOT_PATH));
} else {
IPath path = root.getSourceAttachmentPath();
if (path != null) {
path = EclEmmaCorePlugin.getAbsolutePath(path);
return new SourceLocation(path, root.getSourceAttachmentRootPath());
} else {
return null;
}
}
}
public static ISourceLocation[] findLocations(IPackageFragmentRoot[] roots)
throws JavaModelException {
List l = new ArrayList();
for (int i = 0; i < roots.length; i++) {
ISourceLocation loc = findLocation(roots[i]);
if (loc != null) {
l.add(loc);
}
}
return (ISourceLocation[]) l.toArray(new ISourceLocation[l.size()]);
}
private IPath path;
private IPath rootpath;
/**
* Creates a source location for the given path and root path.
*
* @param path
* @param rootpath
*/
public SourceLocation(IPath path, IPath rootpath) {
this.path = path;
this.rootpath = rootpath;
}
public IPath getPath() {
return path;
}
public IPath getRootPath() {
return rootpath;
}
public boolean isArchive() {
return path.toFile().isFile();
}
public void extract(IProgressMonitor monitor) throws CoreException {
if (isArchive()) {
monitor.beginTask(NLS.bind(CoreMessages.ExtractingSourceArchive_task, path), 1);
String prefix = rootpath == null ? "" : rootpath.toString(); //$NON-NLS-1$
byte[] buffer = new byte[0x1000];
IPath srcfolder = EclEmmaCorePlugin.getInstance().getStateFiles().getSourceFolder(path);
if (!srcfolder.toFile().exists()) {
try {
ZipInputStream zip = new ZipInputStream(new FileInputStream(path.toFile()));
while (true) {
ZipEntry entry = zip.getNextEntry();
if (entry == null) break;
if (!entry.isDirectory() && entry.getName().startsWith(prefix) && entry.getName().endsWith(JAVA_EXT)) {
IPath path = srcfolder.append(entry.getName().substring(prefix.length()));
path.removeLastSegments(1).toFile().mkdirs();
OutputStream out = new FileOutputStream(path.toFile());
int len;
while ((len = zip.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
out.close();
}
zip.closeEntry();
}
zip.close();
} catch (IOException e) {
throw new CoreException(EclEmmaStatus.SOURCE_EXTRACTION_ERROR.getStatus(path, e));
}
}
path = srcfolder;
rootpath = null;
}
monitor.done();
}
}

View File

@ -0,0 +1,127 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core.launching;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.osgi.util.NLS;
import com.mountainminds.eclemma.core.CoverageTools;
import com.mountainminds.eclemma.core.IClassFiles;
import com.mountainminds.eclemma.core.IInstrumentation;
import com.mountainminds.eclemma.core.launching.ICoverageLaunchInfo;
import com.mountainminds.eclemma.internal.core.CoreMessages;
import com.mountainminds.eclemma.internal.core.EclEmmaCorePlugin;
import com.mountainminds.eclemma.internal.core.StateFiles;
/**
* Implementation of {@link ICoverageLaunchInfo}.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class CoverageLaunchInfo implements ICoverageLaunchInfo {
private static int idcounter = (int) System.currentTimeMillis();
private static final Map instances = new WeakHashMap();
private final String id;
private final ILaunchConfiguration configuration;
private IPath coveragefile;
private IPath propertiesjarfile;
private final List instrumentations;
private final Map instrumentationpaths;
public CoverageLaunchInfo(ILaunch launch) {
id = Integer.toHexString(idcounter++);
instances.put(id, this);
configuration = launch.getLaunchConfiguration();
StateFiles statefiles = EclEmmaCorePlugin.getInstance().getStateFiles();
IPath base = statefiles.getLaunchDataFolder().append(id);
coveragefile = base.addFileExtension("ec"); //$NON-NLS-1$
statefiles.registerForCleanup(coveragefile);
propertiesjarfile = base.addFileExtension("jar"); //$NON-NLS-1$
statefiles.registerForCleanup(propertiesjarfile);
instrumentations = new ArrayList();
instrumentationpaths = new HashMap();
instances.put(launch, this);
}
/**
* Returns the coverage launch info that is assoziated with the given launch.
* If no info object is assoziated with the given launch <code>null</code>
* is returned.
*
* @param launch
* the launch object we need coverage data for
* @return the info data object or <code>null</code>
*/
public static ICoverageLaunchInfo getInfo(ILaunch launch) {
return (ICoverageLaunchInfo) instances.get(launch);
}
// ICoverageLaunchInfo interface
public IPath getCoverageFile() {
return coveragefile;
}
public IPath getPropertiesJARFile() {
return propertiesjarfile;
}
public void instrument(IProgressMonitor monitor, boolean inplace) throws CoreException {
instrumentations.clear();
instrumentationpaths.clear();
IClassFiles[] classfiles = CoverageTools.getClassFilesForInstrumentation(
configuration, inplace);
monitor.beginTask(CoreMessages.InstrumentingClasses_task,
classfiles.length);
for (int i = 0; i < classfiles.length; i++) {
if (monitor.isCanceled()) {
return;
}
monitor.subTask(NLS.bind(CoreMessages.InstrumentingClassesIn_task, classfiles[i].getLocation()));
addInstrumentation(classfiles[i].instrument(inplace, new SubProgressMonitor(monitor, 1)));
}
monitor.done();
}
private void addInstrumentation(IInstrumentation instrumentation) {
instrumentations.add(instrumentation);
IPath orig = EclEmmaCorePlugin.getAbsolutePath(instrumentation.getClassFiles().getLocation());
instrumentationpaths.put(orig.toOSString(), instrumentation);
}
public IInstrumentation[] getInstrumentations() {
IInstrumentation[] a = new IInstrumentation[instrumentations.size()];
return (IInstrumentation[]) instrumentations.toArray(a);
}
public IInstrumentation getInstrumentation(String originalpath) {
return (IInstrumentation) instrumentationpaths.get(originalpath);
}
public void dispose() {
// TODO check why this is still necessary, someone seems to hold a reference
// to the launch objects.
coveragefile = null;
propertiesjarfile = null;
}
}

View File

@ -0,0 +1,119 @@
/*******************************************************************************
* Copyright (c) 2006 Mountainminds GmbH & Co. KG
* This software is provided under the terms of the Eclipse Public License v1.0
* See http://www.eclipse.org/legal/epl-v10.html.
*
* $Id$
******************************************************************************/
package com.mountainminds.eclemma.internal.core.launching;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
import org.eclipse.jdt.launching.IRuntimeClasspathProvider;
import org.eclipse.jdt.launching.JavaRuntime;
import com.mountainminds.eclemma.core.CoverageTools;
import com.mountainminds.eclemma.core.EclEmmaStatus;
import com.mountainminds.eclemma.core.IInstrumentation;
import com.mountainminds.eclemma.core.launching.ICoverageLaunchInfo;
import com.mountainminds.eclemma.internal.core.DebugOptions;
import com.mountainminds.eclemma.internal.core.DebugOptions.ITracer;
/**
* Class path provider used internally to inject instrumented classes and the
* Emma runtime.
*
* @author Marc R. Hoffmann
* @version $Revision$
*/
public class InstrumentedClasspathProvider implements IRuntimeClasspathProvider {
public static final String ID = "com.mountainminds.eclemma.core.instrumentedClasspathProvider"; //$NON-NLS-1$
private static final ITracer TRACER = DebugOptions.LAUNCHINGTRACER;
private static final ThreadLocal originalClasspathProvider = new ThreadLocal();
private static final ThreadLocal launchInfo = new ThreadLocal();
public static void enable(
IRuntimeClasspathProvider originalClasspathProvider,
ICoverageLaunchInfo launchInfo) {
InstrumentedClasspathProvider.originalClasspathProvider.set(originalClasspathProvider);
InstrumentedClasspathProvider.launchInfo.set(launchInfo);
}
public static void disable() {
InstrumentedClasspathProvider.originalClasspathProvider.set(null);
InstrumentedClasspathProvider.launchInfo.set(null);
}
private static IRuntimeClasspathProvider getOriginalClasspathProvider()
throws CoreException {
Object obj = originalClasspathProvider.get();
if (obj == null) {
throw new CoreException(EclEmmaStatus.INVALID_CLASSPATH_PROVIDER_CONTEXT_ERROR.getStatus(null));
}
return (IRuntimeClasspathProvider) obj;
}
private static ICoverageLaunchInfo getLaunchInfo() throws CoreException {
Object obj = launchInfo.get();
if (obj == null) {
throw new CoreException(EclEmmaStatus.INVALID_CLASSPATH_PROVIDER_CONTEXT_ERROR.getStatus(null));
}
return (ICoverageLaunchInfo) obj;
}
// IRuntimeClasspathProvider implementation
public IRuntimeClasspathEntry[] computeUnresolvedClasspath(
ILaunchConfiguration configuration) throws CoreException {
IRuntimeClasspathEntry[] entries = getOriginalClasspathProvider().computeUnresolvedClasspath(
configuration);
TRACER.trace("computeUnresolvedClasspath() -> {0}", Arrays.asList(entries)); //$NON-NLS-1$
return entries;
}
public IRuntimeClasspathEntry[] resolveClasspath(
IRuntimeClasspathEntry[] entries, ILaunchConfiguration configuration)
throws CoreException {
TRACER.trace("resolveClasspath()"); //$NON-NLS-1$
ICoverageLaunchInfo info = getLaunchInfo();
entries = getOriginalClasspathProvider().resolveClasspath(entries, configuration);
List newentries = new ArrayList();
boolean emmartinserted = false;
for (int i = 0; i < entries.length; i++) {
if (entries[i].getClasspathProperty() == IRuntimeClasspathEntry.USER_CLASSES) {
TRACER.trace("Resolved classpath entry: {0}", entries[i].getLocation()); //$NON-NLS-1$
IInstrumentation instr = info.getInstrumentation(entries[i].getLocation());
if (instr != null) {
TRACER.trace("Found instrumented classes for {0}", entries[i].getLocation()); //$NON-NLS-1$
if (!emmartinserted) {
addEmmaRuntime(info, newentries);
emmartinserted = true;
}
if (!instr.isInplace()) {
newentries.add(JavaRuntime.newArchiveRuntimeClasspathEntry(instr.getOutputLocation()));
}
}
}
newentries.add(entries[i]);
}
IRuntimeClasspathEntry[] arr = new IRuntimeClasspathEntry[newentries.size()];
return (IRuntimeClasspathEntry[]) newentries.toArray(arr);
}
protected void addEmmaRuntime(ICoverageLaunchInfo info, List entries) throws CoreException {
IPath propertiesjarpath = info.getPropertiesJARFile();
entries.add(0, JavaRuntime.newArchiveRuntimeClasspathEntry(propertiesjarpath));
entries.add(0, JavaRuntime.newArchiveRuntimeClasspathEntry(CoverageTools.getEmmaJar()));
}
}

Some files were not shown because too many files have changed in this diff Show More