Browse Source

Generate an Eclipse IP log with jgit eclipse-iplog

The new plugin contains the bulk of the logic to scan a Git repository,
and query IPZilla, in order to produce an XML formatted IP log for the
requested revision of any Git based project.  This plugin is suitable
for embedding into a servlet container, or into the Eclipse workbench.

The command line pgm package knows how to invoke this plugin through
the eclipse-iplog subcommand, permitting storage of the resulting
log as a local XML file.

Change-Id: If01d9d98d07096db6980292bd5f91618c55d00be
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
tags/v0.7.0
Shawn O. Pearce 14 years ago
parent
commit
1e48c338dc
31 changed files with 2884 additions and 9 deletions
  1. 33
    0
      .eclipse_iplog
  2. 7
    0
      org.eclipse.jgit.iplog/.classpath
  3. 2
    0
      org.eclipse.jgit.iplog/.gitignore
  4. 28
    0
      org.eclipse.jgit.iplog/.project
  5. 3
    0
      org.eclipse.jgit.iplog/.settings/org.eclipse.core.resources.prefs
  6. 3
    0
      org.eclipse.jgit.iplog/.settings/org.eclipse.core.runtime.prefs
  7. 334
    0
      org.eclipse.jgit.iplog/.settings/org.eclipse.jdt.core.prefs
  8. 61
    0
      org.eclipse.jgit.iplog/.settings/org.eclipse.jdt.ui.prefs
  9. 3
    0
      org.eclipse.jgit.iplog/.settings/org.eclipse.pde.core.prefs
  10. 21
    0
      org.eclipse.jgit.iplog/META-INF/MANIFEST.MF
  11. 5
    0
      org.eclipse.jgit.iplog/build.properties
  12. 2
    0
      org.eclipse.jgit.iplog/plugin.properties
  13. 99
    0
      org.eclipse.jgit.iplog/pom.xml
  14. 161
    0
      org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/CQ.java
  15. 127
    0
      org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/CSV.java
  16. 205
    0
      org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/Committer.java
  17. 98
    0
      org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/Contributor.java
  18. 281
    0
      org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/IPZillaQuery.java
  19. 604
    0
      org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/IpLogGenerator.java
  20. 199
    0
      org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/IpLogMeta.java
  21. 119
    0
      org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/Project.java
  22. 124
    0
      org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/SimpleCookieManager.java
  23. 112
    0
      org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/SingleContribution.java
  24. 22
    0
      org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/gsql_query.txt
  25. 2
    0
      org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/sample_gerrit_committers
  26. 1
    0
      org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
  27. 3
    0
      org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin
  28. 7
    1
      org.eclipse.jgit.pgm/pom.xml
  29. 119
    0
      org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/eclipse/Iplog.java
  30. 98
    0
      org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/eclipse/Ipzilla.java
  31. 1
    8
      pom.xml

+ 33
- 0
.eclipse_iplog View File

@@ -0,0 +1,33 @@
[project "technology.jgit"]
name = JGit
license = Eclipse Distribution License v1.0

[CQ "3454"]
description = args4j Version: 2.0.12
license = BSD License
use = unmodified binary
state = approved

[CQ "3565"]
description = Java Servlet API Version: 2.5 (PB CQ2075)
license = Apache License, 2.0
use = unmodified binary
state = approved

[CQ "3654"]
description = JSch Version: 0.1.41 (PB CQ3040)
license = New BSD license
use = unmodified binary
state = approved

[CQ "3655"]
description = Junit Version: 3.8.2 (PB CQ2206)
license = Common Public License 1.0
use = unmodified binary
state = approved

[CQ "3448"]
description = JGit
license = EDL or BSD (TBD)
state = awaiting_analysis


+ 7
- 0
org.eclipse.jgit.iplog/.classpath View File

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

+ 2
- 0
org.eclipse.jgit.iplog/.gitignore View File

@@ -0,0 +1,2 @@
/bin
/target

+ 28
- 0
org.eclipse.jgit.iplog/.project View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.jgit.iplog</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.jdt.core.javanature</nature>
<nature>org.eclipse.pde.PluginNature</nature>
</natures>
</projectDescription>

+ 3
- 0
org.eclipse.jgit.iplog/.settings/org.eclipse.core.resources.prefs View File

@@ -0,0 +1,3 @@
#Mon Aug 11 16:46:23 PDT 2008
eclipse.preferences.version=1
encoding/<project>=UTF-8

+ 3
- 0
org.eclipse.jgit.iplog/.settings/org.eclipse.core.runtime.prefs View File

@@ -0,0 +1,3 @@
#Mon Mar 24 18:55:50 EDT 2008
eclipse.preferences.version=1
line.separator=\n

+ 334
- 0
org.eclipse.jgit.iplog/.settings/org.eclipse.jdt.core.prefs View File

@@ -0,0 +1,334 @@
#Fri Oct 02 18:44:57 PDT 2009
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.5
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.doc.comment.support=enabled
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=warning
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=warning
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=error
org.eclipse.jdt.core.compiler.problem.invalidJavadoc=error
org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
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=error
org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
org.eclipse.jdt.core.compiler.problem.unusedImport=error
org.eclipse.jdt.core.compiler.problem.unusedLabel=error
org.eclipse.jdt.core.compiler.problem.unusedLocal=error
org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error
org.eclipse.jdt.core.compiler.source=1.5
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=1
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=false
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_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=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_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=tab
org.eclipse.jdt.core.formatter.tabulation.size=4
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true

+ 61
- 0
org.eclipse.jgit.iplog/.settings/org.eclipse.jdt.ui.prefs View File

@@ -0,0 +1,61 @@
#Sat Oct 31 14:52:59 PDT 2009
eclipse.preferences.version=1
editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
formatter_profile=_JGit Format
formatter_settings_version=11
org.eclipse.jdt.ui.ignorelowercasenames=true
org.eclipse.jdt.ui.importorder=java;javax;org;com;
org.eclipse.jdt.ui.ondemandthreshold=99
org.eclipse.jdt.ui.staticondemandthreshold=99
org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates/>
sp_cleanup.add_default_serial_version_id=true
sp_cleanup.add_generated_serial_version_id=false
sp_cleanup.add_missing_annotations=false
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=false
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=false
sp_cleanup.never_use_blocks=false
sp_cleanup.never_use_parentheses_in_expressions=true
sp_cleanup.on_save_use_additional_actions=true
sp_cleanup.organize_imports=false
sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
sp_cleanup.remove_private_constructors=true
sp_cleanup.remove_trailing_whitespaces=true
sp_cleanup.remove_trailing_whitespaces_all=true
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
sp_cleanup.remove_unnecessary_casts=false
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

+ 3
- 0
org.eclipse.jgit.iplog/.settings/org.eclipse.pde.core.prefs View File

@@ -0,0 +1,3 @@
#Sat Oct 31 18:40:07 PDT 2009
eclipse.preferences.version=1
resolve.requirebundle=false

+ 21
- 0
org.eclipse.jgit.iplog/META-INF/MANIFEST.MF View File

@@ -0,0 +1,21 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %plugin_name
Bundle-SymbolicName: org.eclipse.jgit.iplog
Bundle-Version: 0.6.0.qualifier
Bundle-Vendor: %provider_name
Bundle-Localization: plugin
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Import-Package: org.eclipse.jgit.diff;version="0.6.0",
org.eclipse.jgit.dircache;version="0.6.0",
org.eclipse.jgit.errors;version="0.6.0",
org.eclipse.jgit.lib;version="0.6.0",
org.eclipse.jgit.revplot;version="0.6.0",
org.eclipse.jgit.revwalk;version="0.6.0",
org.eclipse.jgit.revwalk.filter;version="0.6.0",
org.eclipse.jgit.transport;version="0.6.0",
org.eclipse.jgit.treewalk;version="0.6.0",
org.eclipse.jgit.treewalk.filter;version="0.6.0",
org.eclipse.jgit.util;version="0.6.0"
Export-package: org.eclipse.jgit.iplog;version="0.6.0"

+ 5
- 0
org.eclipse.jgit.iplog/build.properties View File

@@ -0,0 +1,5 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
plugin.properties

+ 2
- 0
org.eclipse.jgit.iplog/plugin.properties View File

@@ -0,0 +1,2 @@
plugin_name=JGit IP Log Generator (Incubation)
provider_name=Eclipse.org

+ 99
- 0
org.eclipse.jgit.iplog/pom.xml View File

@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009-2010, Google Inc.
Copyright (C) 2008, Imran M Yousuf <imyousuf@smartitengineering.com>
and other copyright owners as documented in the project's IP log.

This program and the accompanying materials are made available
under the terms of the Eclipse Distribution License v1.0 which
accompanies this distribution, is reproduced below, and is
available at http://www.eclipse.org/org/documents/edl-v10.php

All rights reserved.

Redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following
conditions are met:

- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

- Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.

- Neither the name of the Eclipse Foundation, Inc. nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior
written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
<version>0.6.0-SNAPSHOT</version>
</parent>

<artifactId>org.eclipse.jgit.iplog</artifactId>
<name>JGit - Eclipse IP Log Generator</name>

<description>
Creates an IP log for Git based projects.
</description>

<properties>
<translate-qualifier/>
</properties>

<dependencies>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>

<build>
<sourceDirectory>src/</sourceDirectory>

<resources>
<resource>
<directory>.</directory>
<includes>
<include>plugin.properties</include>
</includes>
</resource>
</resources>

<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${bundle-manifest}</manifestFile>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>

+ 161
- 0
org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/CQ.java View File

@@ -0,0 +1,161 @@
/*
* Copyright (C) 2010, Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.eclipse.jgit.iplog;

import java.util.Comparator;

/**
* A contribution questionnaire stored in IPzilla.
*
* @see <a href="http://wiki.eclipse.org/IPzilla">IPzilla - Eclipsepedia</a>
* @see <a href="https://dev.eclipse.org/ipzilla/">IPzilla - Login</a>
*/
class CQ {
/** Sorts CQs by their unique number. */
static final Comparator<CQ> COMPARATOR = new Comparator<CQ>() {
public int compare(CQ a, CQ b) {
int cmp = state(a) - state(b);
if (cmp == 0)
cmp = compare(a.getID(), b.getID());
return cmp;
}

private int state(CQ a) {
if ("approved".equals(a.getState()))
return 1;
return 50;
}

private int compare(long a, long b) {
return a < b ? -1 : a == b ? 0 : 1;
}
};

private final long id;

private String description;

private String license;

private String use;

private String state;

private String comments;

/**
* @param id
*/
CQ(final long id) {
this.id = id;
}

/** @return unique id number of the contribution questionnaire. */
long getID() {
return id;
}

/** @return short description of this CQ record. */
String getDescription() {
return description;
}

void setDescription(String description) {
this.description = description;
}

/** @return the license the contribution is under. */
String getLicense() {
return license;
}

void setLicense(String license) {
this.license = license;
}

/** @return how this code is used by the project, e.g. "unmodified binary". */
String getUse() {
return use;
}

void setUse(String use) {
this.use = use;
}

/** @return TODO find out what state is */
String getState() {
return state;
}

void setState(String state) {
this.state = state;
}

/** @return any additional comments about this particular CQ. */
String getComments() {
return comments;
}

void setComments(String comments) {
this.comments = comments;
}

@Override
public int hashCode() {
return (int) getID();
}

@Override
public boolean equals(Object other) {
if (other instanceof CQ) {
return ((CQ) other).getID() == getID();
}
return false;
}

@Override
public String toString() {
return "CQ " + getID();
}
}

+ 127
- 0
org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/CSV.java View File

@@ -0,0 +1,127 @@
/*
* Copyright (C) 2010, Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.eclipse.jgit.iplog;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/** A crude CSV file parser. */
class CSV {
private final BufferedReader in;

private List<String> columns;

CSV(BufferedReader br) throws IOException {
in = br;
columns = readLine();
}

Map<String, String> next() throws IOException {
List<String> row = readLine();
if (columns == null || row == null)
return null;

Map<String, String> r = new LinkedHashMap<String, String>();
for (int col = 0; col < columns.size(); col++)
r.put(columns.get(col), row.get(col));
return r;
}

private List<String> readLine() throws IOException {
String line = in.readLine();
if (line == null || line.length() == 0)
return null;

ArrayList<String> row;
if (columns != null)
row = new ArrayList<String>(columns.size());
else
row = new ArrayList<String>();

int p = 0;
while (p < line.length()) {
if (line.charAt(p) == '"') {
p++; // skip the opening quote.

StringBuilder b = new StringBuilder();
SCAN: while (p < line.length()) {
char c = line.charAt(p);
switch (c) {
case '"':
p++;
break SCAN;

case '\\':
b.append(line.charAt(p + 1));
p += 2;
break;

default:
b.append(c);
p++;
break;
}
}
if (p < line.length() && line.charAt(p) != ',')
throw new IOException("CSV parsing error: " + line);
row.add(b.toString());
p++; // skip the trailing comma (if present)

} else if (line.charAt(p) == ',') {
row.add("");
p++;

} else {
int comma = line.indexOf(',', p);
row.add(line.substring(p, comma));
p = comma + 1;
}
}
return row;
}
}

+ 205
- 0
org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/Committer.java View File

@@ -0,0 +1,205 @@
/*
* Copyright (C) 2010, Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.eclipse.jgit.iplog;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/** A project committer. */
class Committer {
/** Sorts committers by their name first name, then last name. */
static final Comparator<Committer> COMPARATOR = new Comparator<Committer>() {
public int compare(Committer a, Committer b) {
int cmp = a.firstName.compareTo(b.firstName);
if (cmp == 0)
cmp = a.lastName.compareTo(b.lastName);
return cmp;
}
};

private final String id;

private String firstName;

private String lastName;

private String affiliation;

private boolean hasCommits;

private String comments;

private final Set<String> emailAddresses = new HashSet<String>();

private final List<ActiveRange> active = new ArrayList<ActiveRange>(2);

/**
* @param id
* unique identity of the committer
*/
Committer(String id) {
this.id = id;
}

/** @return unique identity of this committer in the foundation database. */
String getID() {
return id;
}

/** @return first name of the committer; their given name. */
String getFirstName() {
return firstName;
}

void setFirstName(String firstName) {
this.firstName = firstName;
}

/** @return last name of the committer; their surname or family name. */
String getLastName() {
return lastName;
}

void setLastName(String lastName) {
this.lastName = lastName;
}

/** @return the organization the committer is affiliated with. */
String getAffiliation() {
return affiliation;
}

void setAffiliation(String affiliation) {
this.affiliation = affiliation;
}

/** @return true if this committer is still an active member of the project. */
boolean isActive() {
if (active.isEmpty())
return false;
ActiveRange last = active.get(active.size() - 1);
return last.end == null;
}

/** @return true if this committer has commits in the project. */
boolean hasCommits() {
return hasCommits;
}

void setHasCommits(boolean hasCommits) {
this.hasCommits = hasCommits;
}

/** @return any additional comments about this committer. */
String getComments() {
return comments;
}

void setComments(String comments) {
this.comments = comments;
}

void addEmailAddress(String email) {
emailAddresses.add(email);
}

void addActiveRange(ActiveRange r) {
active.add(r);
Collections.sort(active, new Comparator<ActiveRange>() {
public int compare(ActiveRange a, ActiveRange b) {
return a.begin.compareTo(b.begin);
}
});
}

/**
* @param when
* @return true if the event occurred while an active committer.
*/
boolean inRange(Date when) {
for (ActiveRange ar : active) {
if (ar.contains(when))
return true;
}
return false;
}

@Override
public String toString() {
return "Committer " + getFirstName() + " " + getLastName();
}

/** Date period during which the committer was active. */
static class ActiveRange {
private final Date begin;

private final Date end;

/**
* @param begin
* @param end
*/
ActiveRange(Date begin, Date end) {
this.begin = begin;
this.end = end;
}

/**
* @param when
* @return true if {@code when} is within this date span.
*/
boolean contains(Date when) {
if (when.compareTo(begin) < 0)
return false;
if (end == null)
return true;
return when.compareTo(end) < 0;
}
}
}

+ 98
- 0
org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/Contributor.java View File

@@ -0,0 +1,98 @@
/*
* Copyright (C) 2010, Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.eclipse.jgit.iplog;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/** A project contributor (non-committer). */
class Contributor {
/** Sorts contributors by their name first name, then last name. */
static final Comparator<Contributor> COMPARATOR = new Comparator<Contributor>() {
public int compare(Contributor a, Contributor b) {
return a.name.compareTo(b.name);
}
};

private final String id;

private final String name;

private final List<SingleContribution> contributions = new ArrayList<SingleContribution>();

/**
* @param name
*/
Contributor(String id, String name) {
this.id = id;
this.name = name;
}

/** @return unique identity of this contributor in the foundation database. */
String getID() {
return id;
}

/** @return name of the contributor. */
String getName() {
return name;
}

/** @return all known contributions. */
Collection<SingleContribution> getContributions() {
return Collections.unmodifiableCollection(contributions);
}

void add(SingleContribution bug) {
contributions.add(bug);
}

@Override
public String toString() {
return "Contributor " + getName();
}
}

+ 281
- 0
org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/IPZillaQuery.java View File

@@ -0,0 +1,281 @@
/*
* Copyright (C) 2010, Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.eclipse.jgit.iplog;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.CookieHandler;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.eclipse.jgit.util.HttpSupport;

/** A crude interface to query IPzilla. */
class IPZillaQuery {
private static final String RE_EPL = "^.*(Eclipse Public License|EPL).*$";

private final URL base;

private final String username;

private final String password;

private final ProxySelector proxySelector = ProxySelector.getDefault();

IPZillaQuery(URL base, String username, String password) {
this.base = base;
this.username = username;
this.password = password;
}

Set<CQ> getCQs(Collection<Project> projects) throws IOException {
try {
login();
Set<CQ> cqs = new HashSet<CQ>();
for (Project project : projects)
cqs.addAll(queryOneProject(project));
return cqs;
} finally {
// Kill the IPzilla session and log us out from there.
logout();
}
}

private Set<CQ> queryOneProject(Project project) throws IOException {
Map<String, String> p = new LinkedHashMap<String, String>();
p.put("bugidtype", "include");
p.put("chfieldto", "Now");
p.put("component", project.getID());
p.put("field-1-0-0", "component");
p.put("type-1-0-0", "anyexact");
p.put("value-1-0-0", project.getID());
p.put("ctype", "csv");

StringBuilder req = new StringBuilder();
for (Map.Entry<String, String> e : p.entrySet()) {
if (req.length() > 0)
req.append('&');
req.append(URLEncoder.encode(e.getKey(), "UTF-8"));
req.append('=');
req.append(URLEncoder.encode(e.getValue(), "UTF-8"));
}
URL csv = new URL(new URL(base, "buglist.cgi").toString() + "?" + req);

req = new StringBuilder();
for (String name : new String[] { "bug_severity", "bug_status",
"resolution", "short_desc", "cf_license", "keywords" }) {
if (req.length() > 0)
req.append("%20");
req.append(name);
}
setCookie(csv, "COLUMNLIST", req.toString());

HttpURLConnection conn = open(csv);
if (HttpSupport.response(conn) != HttpURLConnection.HTTP_OK) {
throw new IOException("Query " + csv + " failed: "
+ conn.getResponseCode() + " " + conn.getResponseMessage());
}

BufferedReader br = reader(conn);
try {
Set<CQ> cqs = new HashSet<CQ>();
CSV in = new CSV(br);
Map<String, String> row;
while ((row = in.next()) != null) {
CQ cq = parseOneCQ(row);
if (cq != null)
cqs.add(cq);
}
return cqs;
} finally {
br.close();
}
}

private BufferedReader reader(HttpURLConnection conn)
throws UnsupportedEncodingException, IOException {
String encoding = conn.getContentEncoding();
InputStream in = conn.getInputStream();
if (encoding != null && !encoding.equals(""))
return new BufferedReader(new InputStreamReader(in, encoding));
return new BufferedReader(new InputStreamReader(in));
}

private void login() throws MalformedURLException,
UnsupportedEncodingException, ConnectException, IOException {
final URL login = new URL(base, "index.cgi");
StringBuilder req = new StringBuilder();
req.append("Bugzilla_login=");
req.append(URLEncoder.encode(username, "UTF-8"));
req.append('&');
req.append("Bugzilla_password=");
req.append(URLEncoder.encode(password, "UTF-8"));
byte[] reqbin = req.toString().getBytes("UTF-8");

HttpURLConnection c = open(login);
c.setDoOutput(true);
c.setFixedLengthStreamingMode(reqbin.length);
c.setRequestProperty(HttpSupport.HDR_CONTENT_TYPE,
"application/x-www-form-urlencoded");
OutputStream out = c.getOutputStream();
out.write(reqbin);
out.close();

if (HttpSupport.response(c) != HttpURLConnection.HTTP_OK) {
throw new IOException("Login as " + username + " to " + login
+ " failed: " + c.getResponseCode() + " "
+ c.getResponseMessage());
}
}

private void logout() throws MalformedURLException, ConnectException,
IOException {
HttpSupport.response(open(new URL(base, "relogin.cgi")));
}

private HttpURLConnection open(URL url) throws ConnectException,
IOException {
Proxy proxy = HttpSupport.proxyFor(proxySelector, url);
HttpURLConnection c = (HttpURLConnection) url.openConnection(proxy);
c.setUseCaches(false);
return c;
}

private void setCookie(URL url, String name, String value)
throws IOException {
Map<String, List<String>> cols = new HashMap<String, List<String>>();
cols.put("Set-Cookie", Collections.singletonList(name + "=" + value));
try {
CookieHandler.getDefault().put(url.toURI(), cols);
} catch (URISyntaxException e) {
IOException err = new IOException("Invalid URI format:" + url);
err.initCause(e);
throw err;
}
}

private CQ parseOneCQ(Map<String, String> row) {
long id = Long.parseLong(row.get("bug_id"));
String state = row.get("bug_severity");
String bug_status = row.get("bug_status");
String resolution = row.get("resolution");
String short_desc = row.get("short_desc");
String license = row.get("cf_license");

Set<String> keywords = new TreeSet<String>();
for (String w : row.get("keywords").split(", *"))
keywords.add(w);

// Skip any CQs that were not accepted.
//
if ("closed".equalsIgnoreCase(state)
|| "rejected".equalsIgnoreCase(state)
|| "withdrawn".equalsIgnoreCase(state))
return null;

// Skip any CQs under the EPL without nonepl keyword
// Skip any CQs with the EPL keyword
//
if (!keywords.contains("nonepl") && license.matches(RE_EPL))
return null;
if (keywords.contains("epl"))
return null;

// Work around CQs that were closed in the wrong state.
//
if ("new".equalsIgnoreCase(state)
|| "under_review".equalsIgnoreCase(state)
|| state.startsWith("awaiting_")) {
if ("RESOLVED".equalsIgnoreCase(bug_status)
|| "CLOSED".equalsIgnoreCase(bug_status)) {
if ("FIXED".equalsIgnoreCase(resolution))
state = "approved";
else
return null;
}
}

StringBuilder use = new StringBuilder();
for (String n : new String[] { "unmodified", "modified", "source",
"binary" }) {
if (keywords.contains(n)) {
if (use.length() > 0)
use.append(' ');
use.append(n);
}
}
if (keywords.contains("sourceandbinary")) {
if (use.length() > 0)
use.append(' ');
use.append("source & binary");
}

CQ cq = new CQ(id);
cq.setDescription(short_desc);
cq.setLicense(license);
cq.setState(state);
if (use.length() > 0)
cq.setUse(use.toString().trim());
return cq;
}
}

+ 604
- 0
org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/IpLogGenerator.java View File

@@ -0,0 +1,604 @@
/*
* Copyright (C) 2010, Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.eclipse.jgit.iplog;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.eclipse.jgit.diff.Edit;
import org.eclipse.jgit.diff.EditList;
import org.eclipse.jgit.diff.MyersDiff;
import org.eclipse.jgit.diff.RawText;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.iplog.Committer.ActiveRange;
import org.eclipse.jgit.lib.BlobBasedConfig;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.MutableObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.WindowCursor;
import org.eclipse.jgit.revwalk.FooterKey;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.NameConflictTreeWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.eclipse.jgit.util.RawParseUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
* Creates an Eclipse IP log in XML format.
*
* @see <a href="http://www.eclipse.org/projects/xml/iplog.xsd">IP log XSD</a>
*/
public class IpLogGenerator {
private static final String IPLOG_NS = "http://www.eclipse.org/projects/xml/iplog";

private static final String IPLOG_PFX = "iplog:";

private static final String INDENT = "{http://xml.apache.org/xslt}indent-amount";

private static final FooterKey BUG = new FooterKey("Bug");

/** Projects indexed by their ID string, e.g. {@code technology.jgit}. */
private final Map<String, Project> projects = new TreeMap<String, Project>();

/** Known committers, indexed by their foundation ID. */
private final Map<String, Committer> committersById = new HashMap<String, Committer>();

/** Known committers, indexed by their email address. */
private final Map<String, Committer> committersByEmail = new HashMap<String, Committer>();

/** Discovered contributors. */
private final Map<String, Contributor> contributorsByName = new HashMap<String, Contributor>();

/** All known CQs matching the projects we care about. */
private final Set<CQ> cqs = new HashSet<CQ>();

/** Root commits which were scanned to gather project data. */
private final Set<RevCommit> commits = new HashSet<RevCommit>();

private String characterEncoding = "UTF-8";

private Repository db;

private RevWalk rw;

private NameConflictTreeWalk tw;

private final WindowCursor curs = new WindowCursor();

private final MutableObjectId idbuf = new MutableObjectId();

private Document doc;

/** Create an empty generator. */
public IpLogGenerator() {
// Do nothing.
}

/**
* Set the character encoding used to write the output file.
*
* @param encodingName
* the character set encoding name.
*/
public void setCharacterEncoding(String encodingName) {
characterEncoding = encodingName;
}

/**
* Scan a Git repository's history to compute the changes within it.
*
* @param repo
* the repository to scan.
* @param startCommit
* commit the IP log is needed for.
* @param version
* symbolic label for the version.
* @throws IOException
* the repository cannot be read.
* @throws ConfigInvalidException
* the {@code .eclipse_iplog} file present at the top level of
* {@code startId} is not a valid configuration file.
*/
public void scan(Repository repo, RevCommit startCommit, String version)
throws IOException, ConfigInvalidException {
try {
db = repo;
rw = new RevWalk(db);
tw = new NameConflictTreeWalk(db);

RevCommit c = rw.parseCommit(startCommit);

loadEclipseIpLog(version, c);
loadCommitters(repo);
scanProjectCommits(c);
commits.add(c);
} finally {
WindowCursor.release(curs);
db = null;
rw = null;
tw = null;
}
}

private void loadEclipseIpLog(String version, RevCommit commit)
throws IOException, ConfigInvalidException {
TreeWalk log = TreeWalk.forPath(db, IpLogMeta.IPLOG_CONFIG_FILE, commit
.getTree());
if (log == null)
return;

IpLogMeta meta = new IpLogMeta();
try {
meta.loadFrom(new BlobBasedConfig(null, db, log.getObjectId(0)));
} catch (ConfigInvalidException e) {
throw new ConfigInvalidException("Configuration file "
+ log.getPathString() + " in commit " + commit.name()
+ " is invalid", e);
}

for (Project p : meta.getProjects()) {
p.setVersion(version);
projects.put(p.getName(), p);
}
cqs.addAll(meta.getCQs());
}

private void loadCommitters(Repository repo) throws IOException {
SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
File list = new File(repo.getDirectory(), "gerrit_committers");
BufferedReader br = new BufferedReader(new FileReader(list));
String line;

while ((line = br.readLine()) != null) {
String[] field = line.trim().split(" *\\| *");
String user = field[1];
String name = field[2];
String email = field[3];
Date begin = parseDate(dt, field[4]);
Date end = parseDate(dt, field[5]);

if (user.startsWith("username:"))
user = user.substring("username:".length());

Committer who = committersById.get(user);
if (who == null) {
who = new Committer(user);
int sp = name.indexOf(' ');
if (0 < sp) {
who.setFirstName(name.substring(0, sp).trim());
who.setLastName(name.substring(sp + 1).trim());
} else {
who.setFirstName(name);
who.setLastName(null);
}
committersById.put(who.getID(), who);
}

who.addEmailAddress(email);
who.addActiveRange(new ActiveRange(begin, end));
committersByEmail.put(email, who);
}
}

private Date parseDate(SimpleDateFormat dt, String value)
throws IOException {
if ("NULL".equals(value) || "".equals(value) || value == null)
return null;
int dot = value.indexOf('.');
if (0 < dot)
value = value.substring(0, dot);
try {
return dt.parse(value);
} catch (ParseException e) {
IOException err = new IOException("Invalid date: " + value);
err.initCause(e);
throw err;
}
}

private void scanProjectCommits(RevCommit start) throws IOException {
rw.reset();
rw.markStart(start);

RevCommit commit;
while ((commit = rw.next()) != null) {
final PersonIdent author = commit.getAuthorIdent();
final Date when = author.getWhen();

Committer who = committersByEmail.get(author.getEmailAddress());
if (who != null && who.inRange(when)) {
// Commit was written by the committer while they were
// an active committer on the project.
//
who.setHasCommits(true);
continue;
}

// Commit from a non-committer contributor.
//
final int cnt = commit.getParentCount();
if (2 <= cnt) {
// Avoid a pointless merge attributed to a non-committer.
// Skip this commit if every file matches at least one
// of the parent commits exactly, if so then the blame
// for code in that file can be fully passed onto that
// parent and this non-committer isn't responsible.
//
tw.setFilter(TreeFilter.ANY_DIFF);
tw.setRecursive(true);

RevTree[] trees = new RevTree[1 + cnt];
trees[0] = commit.getTree();
for (int i = 0; i < cnt; i++)
trees[i + 1] = commit.getParent(i).getTree();
tw.reset(trees);

boolean matchAll = true;
while (tw.next()) {
boolean matchOne = false;
for (int i = 1; i <= cnt; i++) {
if (tw.getRawMode(0) == tw.getRawMode(i)
&& tw.idEqual(0, i)) {
matchOne = true;
break;
}
}
if (!matchOne) {
matchAll = false;
break;
}
}
if (matchAll)
continue;
}

Contributor contributor = contributorsByName.get(author.getName());
if (contributor == null) {
String id = author.getEmailAddress();
String name = author.getName();
contributor = new Contributor(id, name);
contributorsByName.put(name, contributor);
}

String id = commit.name();
String subj = commit.getShortMessage();
SingleContribution item = new SingleContribution(id, when, subj);

List<String> bugs = commit.getFooterLines(BUG);
if (1 == bugs.size()) {
item.setBugID(bugs.get(0));

} else if (2 <= bugs.size()) {
StringBuilder tmp = new StringBuilder();
for (String bug : bugs) {
if (tmp.length() > 0)
tmp.append(",");
tmp.append(bug);
}
item.setBugID(tmp.toString());
}

if (2 <= cnt) {
item.setSize("(merge)");
contributor.add(item);
continue;
}

int addedLines = 0;
if (1 == cnt) {
final RevCommit parent = commit.getParent(0);
tw.setFilter(TreeFilter.ANY_DIFF);
tw.setRecursive(true);
tw.reset(new RevTree[] { parent.getTree(), commit.getTree() });
while (tw.next()) {
if (tw.getFileMode(1).getObjectType() != Constants.OBJ_BLOB)
continue;

byte[] oldImage;
if (tw.getFileMode(0).getObjectType() == Constants.OBJ_BLOB)
oldImage = openBlob(0);
else
oldImage = new byte[0];

EditList edits = new MyersDiff(new RawText(oldImage),
new RawText(openBlob(1))).getEdits();
for (Edit e : edits)
addedLines += e.getEndB() - e.getBeginB();
}

} else { // no parents, everything is an addition
tw.setFilter(TreeFilter.ALL);
tw.setRecursive(true);
tw.reset(commit.getTree());
while (tw.next()) {
if (tw.getFileMode(0).getObjectType() == Constants.OBJ_BLOB) {
byte[] buf = openBlob(0);
for (int ptr = 0; ptr < buf.length;) {
ptr += RawParseUtils.nextLF(buf, ptr);
addedLines++;
}
}
}
}

if (addedLines < 0)
throw new IOException("Incorrectly scanned " + commit.name());
if (1 == addedLines)
item.setSize("+1 line");
else
item.setSize("+" + addedLines + " lines");
contributor.add(item);
}
}

private byte[] openBlob(int side) throws IOException {
tw.getObjectId(idbuf, side);
ObjectLoader ldr = db.openObject(curs, idbuf);
if (ldr == null)
throw new MissingObjectException(idbuf.copy(), Constants.OBJ_BLOB);
return ldr.getCachedBytes();
}

/**
* Dump the scanned information into an XML file.
*
* @param out
* the file stream to write to. The caller is responsible for
* closing the stream upon completion.
* @throws IOException
* the stream cannot be written.
*/
public void writeTo(OutputStream out) throws IOException {
try {
TransformerFactory factory = TransformerFactory.newInstance();
Transformer s = factory.newTransformer();
s.setOutputProperty(OutputKeys.ENCODING, characterEncoding);
s.setOutputProperty(OutputKeys.METHOD, "xml");
s.setOutputProperty(OutputKeys.INDENT, "yes");
s.setOutputProperty(INDENT, "2");
s.transform(new DOMSource(toXML()), new StreamResult(out));
} catch (ParserConfigurationException e) {
IOException err = new IOException("Cannot serialize XML");
err.initCause(e);
throw err;

} catch (TransformerConfigurationException e) {
IOException err = new IOException("Cannot serialize XML");
err.initCause(e);
throw err;

} catch (TransformerException e) {
IOException err = new IOException("Cannot serialize XML");
err.initCause(e);
throw err;
}
}

private Document toXML() throws ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
doc = factory.newDocumentBuilder().newDocument();

Element root = createElement("iplog");
doc.appendChild(root);

if (projects.size() == 1) {
Project soleProject = projects.values().iterator().next();
root.setAttribute("name", soleProject.getID());
}

Set<String> licenses = new TreeSet<String>();
for (Project project : sort(projects, Project.COMPARATOR)) {
root.appendChild(createProject(project));
licenses.addAll(project.getLicenses());
}
for (RevCommit c : sort(commits))
root.appendChild(createCommitMeta(c));
for (String name : sort(licenses))
root.appendChild(createLicense(name));

if (!cqs.isEmpty())
appendBlankLine(root);
for (CQ cq : sort(cqs, CQ.COMPARATOR))
root.appendChild(createCQ(cq));

if (!committersByEmail.isEmpty())
appendBlankLine(root);
for (Committer committer : sort(committersById, Committer.COMPARATOR))
root.appendChild(createCommitter(committer));

for (Contributor c : sort(contributorsByName, Contributor.COMPARATOR)) {
appendBlankLine(root);
root.appendChild(createContributor(c));
}

return doc;
}

private void appendBlankLine(Element root) {
root.appendChild(doc.createTextNode("\n\n "));
}

private Element createProject(Project p) {
Element project = createElement("project");
required(project, "id", p.getID());
required(project, "name", p.getName());
optional(project, "comments", p.getComments());
optional(project, "version", p.getVersion());
return project;
}

private Element createCommitMeta(RevCommit c) {
Element meta = createElement("meta");
required(meta, "key", "git-commit");
required(meta, "value", c.name());
return meta;
}

private Element createLicense(String name) {
Element license = createElement("license");
required(license, "id", name);
optional(license, "description", null);
optional(license, "comments", null);
return license;
}

private Element createCQ(CQ cq) {
Element r = createElement("cq");
required(r, "id", Long.toString(cq.getID()));
required(r, "description", cq.getDescription());
optional(r, "license", cq.getLicense());
optional(r, "use", cq.getUse());
optional(r, "state", cq.getState());
optional(r, "comments", cq.getComments());
return r;
}

private Element createCommitter(Committer who) {
Element r = createElement("committer");
required(r, "id", who.getID());
required(r, "firstName", who.getFirstName());
required(r, "lastName", who.getLastName());
optional(r, "affiliation", who.getAffiliation());
required(r, "active", Boolean.toString(who.isActive()));
required(r, "hasCommits", Boolean.toString(who.hasCommits()));
optional(r, "comments", who.getComments());
return r;
}

private Element createContributor(Contributor c) {
Element r = createElement("contributor");
required(r, "id", c.getID());
required(r, "name", c.getName());

for (SingleContribution s : sort(c.getContributions(),
SingleContribution.COMPARATOR))
r.appendChild(createContribution(s));

return r;
}

private Element createContribution(SingleContribution s) {
Element r = createElement("bug");
required(r, "id", s.getID());
optional(r, "bug-id", s.getBugID());
required(r, "size", s.getSize());
required(r, "type", "A"); // assume attachment type
required(r, "created", format(s.getCreated()));
required(r, "summary", s.getSummary());
return r;
}

private String format(Date created) {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(created);
}

private Element createElement(String name) {
return doc.createElementNS(IPLOG_NS, IPLOG_PFX + name);
}

private void required(Element r, String name, String value) {
if (value == null)
value = "";
r.setAttribute(name, value);
}

private void optional(Element r, String name, String value) {
if (value != null && value.length() > 0)
r.setAttribute(name, value);
}

private static <T, Q extends Comparator<T>> Iterable<T> sort(
Collection<T> objs, Q cmp) {
ArrayList<T> sorted = new ArrayList<T>(objs);
Collections.sort(sorted, cmp);
return sorted;
}

private static <T, Q extends Comparator<T>> Iterable<T> sort(
Map<?, T> objs, Q cmp) {
return sort(objs.values(), cmp);
}

@SuppressWarnings("unchecked")
private static <T extends Comparable> Iterable<T> sort(Collection<T> objs) {
ArrayList<T> sorted = new ArrayList<T>(objs);
Collections.sort(sorted);
return sorted;
}
}

+ 199
- 0
org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/IpLogMeta.java View File

@@ -0,0 +1,199 @@
/*
* Copyright (C) 2010, Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.eclipse.jgit.iplog;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileBasedConfig;
import org.eclipse.jgit.lib.LockFile;

/**
* Manages the {@code .eclipse_iplog} file in a project.
*/
public class IpLogMeta {
/** Default name of the {@code .eclipse_iplog} file. */
public static final String IPLOG_CONFIG_FILE = ".eclipse_iplog";

private static final String S_PROJECT = "project";

private static final String S_CQ = "CQ";

private static final String K_NAME = "name";

private static final String K_COMMENTS = "comments";

private static final String K_LICENSE = "license";

private static final String K_DESCRIPTION = "description";

private static final String K_USE = "use";

private static final String K_STATE = "state";

private List<Project> projects = new ArrayList<Project>();

private Set<CQ> cqs = new HashSet<CQ>();

List<Project> getProjects() {
return projects;
}

Set<CQ> getCQs() {
return cqs;
}

void loadFrom(Config cfg) {
projects.clear();
cqs.clear();

for (String id : cfg.getSubsections(S_PROJECT)) {
String name = cfg.getString(S_PROJECT, id, K_NAME);
Project project = new Project(id, name);
project.setComments(cfg.getString(S_PROJECT, id, K_COMMENTS));

for (String license : cfg.getStringList(S_PROJECT, id, K_LICENSE))
project.addLicense(license);
projects.add(project);
}

for (String id : cfg.getSubsections(S_CQ)) {
CQ cq = new CQ(Long.parseLong(id));
cq.setDescription(cfg.getString(S_CQ, id, K_DESCRIPTION));
cq.setLicense(cfg.getString(S_CQ, id, K_LICENSE));
cq.setUse(cfg.getString(S_CQ, id, K_USE));
cq.setState(cfg.getString(S_CQ, id, K_STATE));
cq.setComments(cfg.getString(S_CQ, id, K_COMMENTS));
cqs.add(cq);
}
}

/**
* Query the Eclipse Foundation's IPzilla database for CQ records.
* <p>
* Updates the local {@code .eclipse_iplog} configuration file with current
* information by deleting CQs which are no longer relevant, and adding or
* updating any CQs which currently exist in the database.
*
* @param file
* local file to update with current CQ records.
* @param base
* base https:// URL of the IPzilla server.
* @param username
* username to login to IPzilla as. Must be a Bugzilla username
* of someone authorized to query the project's IPzilla records.
* @param password
* password for {@code username}.
* @throws IOException
* IPzilla cannot be queried, or the local file cannot be read
* from or written to.
* @throws ConfigInvalidException
* the local file cannot be read, as it is not a valid
* configuration file format.
*/
public void syncCQs(File file, URL base, String username, String password)
throws IOException, ConfigInvalidException {
if (!file.getParentFile().exists())
file.getParentFile().mkdirs();

LockFile lf = new LockFile(file);
if (!lf.lock())
throw new IOException("Cannot lock " + file);
try {
FileBasedConfig cfg = new FileBasedConfig(file);
cfg.load();
loadFrom(cfg);

IPZillaQuery ipzilla = new IPZillaQuery(base, username, password);
Set<CQ> current = ipzilla.getCQs(projects);

for (CQ cq : sort(current, CQ.COMPARATOR)) {
String id = Long.toString(cq.getID());

set(cfg, S_CQ, id, K_DESCRIPTION, cq.getDescription());
set(cfg, S_CQ, id, K_LICENSE, cq.getLicense());
set(cfg, S_CQ, id, K_USE, cq.getUse());
set(cfg, S_CQ, id, K_STATE, cq.getState());
set(cfg, S_CQ, id, K_COMMENTS, cq.getComments());
}

for (CQ cq : cqs) {
if (!current.contains(cq))
cfg.unsetSection(S_CQ, Long.toString(cq.getID()));
}

lf.write(Constants.encode(cfg.toText()));
if (!lf.commit())
throw new IOException("Cannot write " + file);
} finally {
lf.unlock();
}
}

private static void set(Config cfg, String section, String subsection,
String key, String value) {
if (value == null || "".equals(value))
cfg.unset(section, subsection, key);
else
cfg.setString(section, subsection, key, value);
}

private static <T, Q extends Comparator<T>> Iterable<T> sort(
Collection<T> objs, Q cmp) {
ArrayList<T> sorted = new ArrayList<T>(objs);
Collections.sort(sorted, cmp);
return sorted;
}
}

+ 119
- 0
org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/Project.java View File

@@ -0,0 +1,119 @@
/*
* Copyright (C) 2010, Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.eclipse.jgit.iplog;

import java.util.Collections;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

/** Description of a project. */
class Project {
/** Sorts projects by unique identities. */
static final Comparator<Project> COMPARATOR = new Comparator<Project>() {
public int compare(Project a, Project b) {
return a.getID().compareTo(b.getID());
}
};

private final String id;

private final String name;

private String comments;

private final Set<String> licenses = new TreeSet<String>();

private String version;

/**
* @param id
* @param name
*/
Project(String id, String name) {
this.id = id;
this.name = name;
}

/** @return unique identity of this project. */
String getID() {
return id;
}

/** @return name of this project. */
String getName() {
return name;
}

/** @return any additional comments about this project. */
String getComments() {
return comments;
}

void setComments(String comments) {
this.comments = comments;
}

/** @return the licenses this project is released under. */
Set<String> getLicenses() {
return Collections.unmodifiableSet(licenses);
}

void addLicense(String licenseName) {
licenses.add(licenseName);
}

String getVersion() {
return version;
}

void setVersion(String v) {
version = v;
}

@Override
public String toString() {
return "Project " + getID() + " (" + getName() + ")";
}
}

+ 124
- 0
org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/SimpleCookieManager.java View File

@@ -0,0 +1,124 @@
/*
* Copyright (C) 2010, Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.eclipse.jgit.iplog;

import java.io.IOException;
import java.net.CookieHandler;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Dumb implementation of a CookieManager for the JRE.
* <p>
* Cookies are keyed only by the host name in the URI. Cookie attributes like
* domain and path are ignored to simplify the implementation.
* <p>
* If we are running on Java 6 or later we should favor using the standard
* {@code java.net.CookieManager} class instead.
*/
public class SimpleCookieManager extends CookieHandler {
private Map<String, Map<String, String>> byHost = new HashMap<String, Map<String, String>>();

@Override
public Map<String, List<String>> get(URI uri,
Map<String, List<String>> requestHeaders) throws IOException {
String host = hostOf(uri);

Map<String, String> map = byHost.get(host);
if (map == null || map.isEmpty())
return requestHeaders;

Map<String, List<String>> r = new HashMap<String, List<String>>();
r.putAll(requestHeaders);
StringBuilder buf = new StringBuilder();
for (Map.Entry<String, String> e : map.entrySet()) {
if (buf.length() > 0)
buf.append("; ");
buf.append(e.getKey());
buf.append('=');
buf.append(e.getValue());
}
r.put("Cookie", Collections.singletonList(buf.toString()));
return Collections.unmodifiableMap(r);
}

@Override
public void put(URI uri, Map<String, List<String>> responseHeaders)
throws IOException {
List<String> list = responseHeaders.get("Set-Cookie");
if (list == null || list.isEmpty()) {
return;
}

String host = hostOf(uri);
Map<String, String> map = byHost.get(host);
if (map == null) {
map = new HashMap<String, String>();
byHost.put(host, map);
}

for (String hdr : list) {
String attributes[] = hdr.split(";");
String nameValue = attributes[0].trim();
int eq = nameValue.indexOf('=');
String name = nameValue.substring(0, eq);
String value = nameValue.substring(eq + 1);

map.put(name, value);
}
}

private String hostOf(URI uri) {
StringBuilder key = new StringBuilder();
key.append(uri.getScheme());
key.append(':');
key.append(uri.getHost());
if (0 < uri.getPort())
key.append(':' + uri.getPort());
return key.toString();
}
}

+ 112
- 0
org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/SingleContribution.java View File

@@ -0,0 +1,112 @@
/*
* Copyright (C) 2010, Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.eclipse.jgit.iplog;

import java.util.Comparator;
import java.util.Date;

/** A single contribution by a {@link Contributor}. */
class SingleContribution {
/** Sorts contributors by their name first name, then last name. */
public static final Comparator<SingleContribution> COMPARATOR = new Comparator<SingleContribution>() {
public int compare(SingleContribution a, SingleContribution b) {
return a.created.compareTo(b.created);
}
};

private final String id;

private String summary;

private Date created;

private String bugId;

private String size;

/**
* @param id
* @param created
* @param summary
*/
SingleContribution(String id, Date created, String summary) {
this.id = id;
this.summary = summary;
this.created = created;
}

/** @return unique identity of the contribution. */
String getID() {
return id;
}

/** @return date the contribution was created. */
Date getCreated() {
return created;
}

/** @return summary of the contribution. */
String getSummary() {
return summary;
}

/** @return Bugzilla bug id */
String getBugID() {
return bugId;
}

void setBugID(String id) {
if (id.startsWith("https://bugs.eclipse.org/"))
id = id.substring("https://bugs.eclipse.org/".length());
bugId = id;
}

String getSize() {
return size;
}

void setSize(String sz) {
size = sz;
}
}

+ 22
- 0
org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/gsql_query.txt View File

@@ -0,0 +1,22 @@
# Query for Gerrit Code Review gsql to produce the .git/gerrit_committers
# file for a project. Needing to do this manually is a horrible hack.

SELECT a.account_id,
u.external_id,
a.full_name,
b.email_address,
r.added_on,
r.removed_on
FROM accounts a,
account_external_ids b,
account_groups g,
account_group_members_audit r,
account_external_ids u
WHERE a.account_id = b.account_id
AND b.email_address IS NOT NULL
AND r.account_id = a.account_id
AND r.group_id = g.group_id
AND u.account_id = a.account_id
AND u.external_id like 'username:%'
AND g.name = 'technology.jgit-committers'
ORDER BY a.full_name, r.added_on;

+ 2
- 0
org.eclipse.jgit.iplog/src/org/eclipse/jgit/iplog/sample_gerrit_committers View File

@@ -0,0 +1,2 @@
1 | username:spearce | Shawn Pearce | sop@google.com | 2009-09-29 16:47:03.0 | NULL
1 | username:spearce | Shawn Pearce | spearce@spearce.org | 2009-09-29 16:47:03.0 | NULL

+ 1
- 0
org.eclipse.jgit.pgm/META-INF/MANIFEST.MF View File

@@ -18,6 +18,7 @@ Import-Package: org.eclipse.jgit.awtui,
org.eclipse.jgit.treewalk,
org.eclipse.jgit.treewalk.filter,
org.eclipse.jgit.util,
org.eclipse.jgit.iplog,
org.kohsuke.args4j,
org.kohsuke.args4j.spi
Bundle-ActivationPolicy: lazy

+ 3
- 0
org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin View File

@@ -30,3 +30,6 @@ org.eclipse.jgit.pgm.debug.ShowCacheTree
org.eclipse.jgit.pgm.debug.ShowCommands
org.eclipse.jgit.pgm.debug.ShowDirCache
org.eclipse.jgit.pgm.debug.WriteDirCache

org.eclipse.jgit.pgm.eclipse.Iplog
org.eclipse.jgit.pgm.eclipse.Ipzilla

+ 7
- 1
org.eclipse.jgit.pgm/pom.xml View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009, Google Inc.
Copyright (C) 2009-2010, Google Inc.
and other copyright owners as documented in the project's IP log.

This program and the accompanying materials are made available
@@ -72,6 +72,12 @@
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.iplog</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ui</artifactId>

+ 119
- 0
org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/eclipse/Iplog.java View File

@@ -0,0 +1,119 @@
/*
* Copyright (C) 2010, Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.eclipse.jgit.pgm.eclipse;

import java.io.File;
import java.io.OutputStream;
import java.net.CookieHandler;

import org.eclipse.jgit.iplog.IpLogGenerator;
import org.eclipse.jgit.iplog.SimpleCookieManager;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.LockFile;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.pgm.Command;
import org.eclipse.jgit.pgm.TextBuiltin;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevTag;
import org.eclipse.jgit.revwalk.RevWalk;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;

@Command(name = "eclipse-iplog", common = false, usage = "Produce an Eclipse IP log")
class Iplog extends TextBuiltin {
@Option(name = "--version", aliases = { "-r" }, metaVar = "VERSION", usage = "Symbolic version for the project")
private String version;

@Option(name = "--output", aliases = { "-o" }, metaVar = "FILE", usage = "Output file")
private File output;

@Argument(index = 0, metaVar = "COMMIT|TAG")
private ObjectId commitId;

@Override
protected void run() throws Exception {
if (CookieHandler.getDefault() == null)
CookieHandler.setDefault(new SimpleCookieManager());

final IpLogGenerator log = new IpLogGenerator();

if (commitId == null) {
System.err.println("warning: No commit given on command line,"
+ " assuming " + Constants.HEAD);
commitId = db.resolve(Constants.HEAD);
}

final RevWalk rw = new RevWalk(db);
final RevObject start = rw.parseAny(commitId);
if (version == null && start instanceof RevTag)
version = ((RevTag) start).getTagName();
else if (version == null)
throw die(start.name() + " is not a tag, --version is required");

log.scan(db, rw.parseCommit(start), version);

if (output != null) {
if (!output.getParentFile().exists())
output.getParentFile().mkdirs();
LockFile lf = new LockFile(output);
if (!lf.lock())
throw die("Cannot lock " + output);
try {
OutputStream os = lf.getOutputStream();
try {
log.writeTo(os);
} finally {
os.close();
}
if (!lf.commit())
throw die("Cannot write " + output);
} finally {
lf.unlock();
}
} else {
log.writeTo(System.out);
System.out.flush();
}
}
}

+ 98
- 0
org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/eclipse/Ipzilla.java View File

@@ -0,0 +1,98 @@
/*
* Copyright (C) 2010, Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.eclipse.jgit.pgm.eclipse;

import java.io.File;
import java.net.Authenticator;
import java.net.CookieHandler;
import java.net.PasswordAuthentication;
import java.net.URL;

import org.eclipse.jgit.iplog.IpLogMeta;
import org.eclipse.jgit.iplog.SimpleCookieManager;
import org.eclipse.jgit.pgm.Command;
import org.eclipse.jgit.pgm.TextBuiltin;
import org.kohsuke.args4j.Option;

@Command(name = "eclipse-ipzilla", common = false, usage = "Synchronize IPZilla data")
class Ipzilla extends TextBuiltin {
@Option(name = "--url", metaVar = "URL", usage = "IPZilla URL")
private String url = "https://dev.eclipse.org/ipzilla/";

@Option(name = "--username", metaVar = "USER", usage = "IPZilla Username")
private String username;

@Option(name = "--password", metaVar = "PASS", usage = "IPZilla Password")
private String password;

@Option(name = "--file", aliases = { "-f" }, metaVar = "FILE", usage = "Input/output file")
private File output;

@Override
protected void run() throws Exception {
if (CookieHandler.getDefault() == null)
CookieHandler.setDefault(new SimpleCookieManager());

final URL ipzilla = new URL(url);
if (username == null) {
final PasswordAuthentication auth = Authenticator
.requestPasswordAuthentication(ipzilla.getHost(), //
null, //
ipzilla.getPort(), //
ipzilla.getProtocol(), //
"IPZilla Password", //
ipzilla.getProtocol(), //
ipzilla, //
Authenticator.RequestorType.SERVER);
username = auth.getUserName();
password = new String(auth.getPassword());
}

if (output == null)
output = new File(db.getWorkDir(), IpLogMeta.IPLOG_CONFIG_FILE);

IpLogMeta meta = new IpLogMeta();
meta.syncCQs(output, ipzilla, username, password);
}
}

+ 1
- 8
pom.xml View File

@@ -130,18 +130,10 @@
<maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format>
<bundle-manifest>${project.build.directory}/META-INF/MANIFEST.MF</bundle-manifest>

<jsch-CQ>CQ 3493</jsch-CQ>
<jsch-version>0.1.41</jsch-version>

<junit-CQ>CQ 3589</junit-CQ>
<junit-version>3.8.2</junit-version>

<args4j-CQ>CQ 3454</args4j-CQ>
<args4j-version>2.0.12</args4j-version>

<servlet-api-CQ>CQ 3565</servlet-api-CQ>
<servlet-api-version>2.5</servlet-api-version>

<jetty-version>7.0.1.v20091125</jetty-version>
</properties>

@@ -329,6 +321,7 @@
<module>org.eclipse.jgit</module>
<module>org.eclipse.jgit.ui</module>
<module>org.eclipse.jgit.http.server</module>
<module>org.eclipse.jgit.iplog</module>
<module>org.eclipse.jgit.pgm</module>
<module>org.eclipse.jgit.junit</module>


Loading…
Cancel
Save