diff --git a/BUCK b/BUCK index 1deab2fe3..22ab59291 100644 --- a/BUCK +++ b/BUCK @@ -45,6 +45,23 @@ genrule( visibility = ['PUBLIC'], ) +java_library( + name = 'jgit-lfs-server', + exported_deps = [ + ':jgit', + ':jgit-lfs', + '//org.eclipse.jgit.lfs.server:jgit-lfs-server' + ], + visibility = ['PUBLIC'], +) + +genrule( + name = 'jgit-lfs-server_src', + cmd = 'ln -s $(location //org.eclipse.jgit.lfs.server:jgit-lfs-server_src) $OUT', + out = 'jgit-lfs-server_src.zip', + visibility = ['PUBLIC'], +) + java_library( name = 'junit', exported_deps = [ diff --git a/lib/BUCK b/lib/BUCK index 524612bde..2421b407a 100644 --- a/lib/BUCK +++ b/lib/BUCK @@ -123,3 +123,12 @@ maven_jar( artifact = 'hamcrest-core', version = '1.3', ) + +maven_jar( + name = 'gson', + bin_sha1 = 'a60a5e993c98c864010053cb901b7eab25306568', + src_sha1 = 'a6dc5db8a12928e583bd3f23e72d3ab611ecd58f', + group = 'com.google.code.gson', + artifact = 'gson', + version = '2.2.4', +) diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java index ce04bdf2c..c36c29762 100644 --- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java +++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java @@ -104,6 +104,15 @@ public class AppServer { private final TestRequestLog log; public AppServer() { + this(0); + } + + /** + * @param port + * the http port number + * @since 4.2 + */ + public AppServer(int port) { server = new Server(); HttpConfiguration http_config = new HttpConfiguration(); @@ -113,7 +122,7 @@ public class AppServer { connector = new ServerConnector(server, new HttpConnectionFactory(http_config)); - connector.setPort(0); + connector.setPort(port); try { final InetAddress me = InetAddress.getByName("localhost"); connector.setHost(me.getHostAddress()); diff --git a/org.eclipse.jgit.lfs.server.test/.classpath b/org.eclipse.jgit.lfs.server.test/.classpath new file mode 100644 index 000000000..2fdcc94f1 --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.eclipse.jgit.lfs.server.test/.gitignore b/org.eclipse.jgit.lfs.server.test/.gitignore new file mode 100644 index 000000000..4dc009173 --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/.gitignore @@ -0,0 +1,2 @@ +/target +/bin diff --git a/org.eclipse.jgit.lfs.server.test/.project b/org.eclipse.jgit.lfs.server.test/.project new file mode 100644 index 000000000..e3a4748e9 --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/.project @@ -0,0 +1,34 @@ + + + org.eclipse.jgit.lfs.server.test + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.api.tools.apiAnalysisBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.pde.api.tools.apiAnalysisNature + + diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 000000000..4824b8026 --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.core.runtime.prefs new file mode 100644 index 000000000..5a0ad22d2 --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.core.runtime.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +line.separator=\n diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..dcc0d3a0f --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,398 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled +org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.7 +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.comparingIdentical=error +org.eclipse.jdt.core.compiler.problem.deadCode=error +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.explicitlyClosedAutoCloseable=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled +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.includeNullInfoFromAsserts=enabled +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.missingDefaultCase=ignore +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error +org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore +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.missingJavadocTagsMethodTypeParameters=disabled +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +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.nonnullParameterAnnotationDropped=warning +org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error +org.eclipse.jdt.core.compiler.problem.nullReference=error +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=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.potentiallyUnclosedCloseable=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=error +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=error +org.eclipse.jdt.core.compiler.problem.unusedLabel=error +org.eclipse.jdt.core.compiler.problem.unusedLocal=error +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=warning +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error +org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error +org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=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.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=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_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=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_on_off_tags=true +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..c336cce6e --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,61 @@ +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=_JGit Format +formatter_settings_version=12 +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= +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_missing_override_annotations_interface_methods=false +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=true +sp_cleanup.format_source_code_changes_only=true +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 diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.mylyn.tasks.ui.prefs new file mode 100644 index 000000000..3dec4d97c --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.mylyn.tasks.ui.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +project.repository.kind=bugzilla +project.repository.url=https\://bugs.eclipse.org/bugs diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.mylyn.team.ui.prefs new file mode 100644 index 000000000..ce7a0f047 --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.mylyn.team.ui.prefs @@ -0,0 +1,2 @@ +commit.comment.template=${task.description} \n\nBug\: ${task.key} +eclipse.preferences.version=1 diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.pde.api.tools.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.pde.api.tools.prefs new file mode 100644 index 000000000..d585687d5 --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.pde.api.tools.prefs @@ -0,0 +1,93 @@ +ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error +ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error +ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error +ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error +ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error +API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error +API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error +API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error +API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error +CLASS_ELEMENT_TYPE_ADDED_METHOD=Error +CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error +CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error +CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error +CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error +CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error +CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error +CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error +CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error +CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error +CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error +CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error +CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error +CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error +CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error +CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error +CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error +CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error +ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error +ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error +ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error +ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error +ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error +ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error +FIELD_ELEMENT_TYPE_ADDED_VALUE=Error +FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error +FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error +FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error +FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error +FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error +FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error +FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error +FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error +FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error +ILLEGAL_EXTEND=Warning +ILLEGAL_IMPLEMENT=Warning +ILLEGAL_INSTANTIATE=Warning +ILLEGAL_OVERRIDE=Warning +ILLEGAL_REFERENCE=Warning +INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error +INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error +INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error +INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error +INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error +INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error +INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error +INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error +INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error +INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error +INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error +INVALID_JAVADOC_TAG=Ignore +INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Error +LEAK_EXTEND=Warning +LEAK_FIELD_DECL=Warning +LEAK_IMPLEMENT=Warning +LEAK_METHOD_PARAM=Warning +LEAK_METHOD_RETURN_TYPE=Warning +METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error +METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error +METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error +METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error +METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error +METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error +METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error +METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error +METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error +METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error +TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error +TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error +TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error +TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error +TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error +TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error +UNUSED_PROBLEM_FILTERS=Warning +automatically_removed_unused_problem_filters=false +eclipse.preferences.version=1 +incompatible_api_component_version=Error +incompatible_api_component_version_include_major_without_breaking_change=Disabled +incompatible_api_component_version_include_minor_without_api_change=Disabled +invalid_since_tag_version=Error +malformed_since_tag=Error +missing_since_tag=Error +report_api_breakage_when_major_version_incremented=Disabled +report_resolution_errors_api_component=Warning diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.pde.core.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 000000000..923c37fb8 --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +resolve.requirebundle=false diff --git a/org.eclipse.jgit.lfs.server.test/BUCK b/org.eclipse.jgit.lfs.server.test/BUCK new file mode 100644 index 000000000..47ed9c3d5 --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/BUCK @@ -0,0 +1,34 @@ +TEST_BASE = ['tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java'] +TESTS = glob(['tst/**/*.java'], + excludes = TEST_BASE +) + +for t in TESTS: + n = t[len('tst/'):len(t)-len('.java')].replace('/', '.') + java_test( + name = n, + labels = ['lfs-server'], + srcs = [t] + TEST_BASE, + deps = [ + '//org.eclipse.jgit.lfs.test:helpers', + '//org.eclipse.jgit:jgit', + '//org.eclipse.jgit.junit:junit', + '//org.eclipse.jgit.junit.http:junit-http', + '//org.eclipse.jgit.lfs:jgit-lfs', + '//org.eclipse.jgit.lfs.server:jgit-lfs-server', + '//lib:hamcrest-core', + '//lib:hamcrest-library', + '//lib:httpcore', + '//lib:httpcomponents', + '//lib:junit', + '//lib/jetty:http', + '//lib/jetty:io', + '//lib/jetty:server', + '//lib/jetty:servlet', + '//lib/jetty:security', + '//lib/jetty:util', + '//lib:servlet-api', + ], + source_under_test = ['//org.eclipse.jgit.lfs.server:jgit-lfs-server'], + vm_args = ['-Xmx256m', '-Dfile.encoding=UTF-8'], + ) diff --git a/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF new file mode 100644 index 000000000..d263c3a69 --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF @@ -0,0 +1,38 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %plugin_name +Bundle-SymbolicName: org.eclipse.jgit.lfs.server.test +Bundle-Version: 4.3.0.qualifier +Bundle-Vendor: %provider_name +Bundle-Localization: plugin +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Import-Package: javax.servlet;version="[3.1.0,4.0.0)", + javax.servlet.http;version="[3.1.0,4.0.0)", + org.apache.http;version="[4.3.0,5.0.0)", + org.apache.http.client;version="[4.3.0,5.0.0)", + org.apache.http.client.methods;version="[4.3.0,5.0.0)", + org.apache.http.entity;version="[4.3.0,5.0.0)", + org.apache.http.impl.client;version="[4.3.0,5.0.0)", + org.eclipse.jetty.continuation;version="[9.0.0,10.0.0)", + org.eclipse.jetty.http;version="[9.0.0,10.0.0)", + org.eclipse.jetty.io;version="[9.0.0,10.0.0)", + org.eclipse.jetty.security;version="[9.0.0,10.0.0)", + org.eclipse.jetty.security.authentication;version="[9.0.0,10.0.0)", + org.eclipse.jetty.server;version="[9.0.0,10.0.0)", + org.eclipse.jetty.server.handler;version="[9.0.0,10.0.0)", + org.eclipse.jetty.server.nio;version="[9.0.0,10.0.0)", + org.eclipse.jetty.servlet;version="[9.0.0,10.0.0)", + org.eclipse.jetty.util;version="[9.0.0,10.0.0)", + org.eclipse.jetty.util.component;version="[9.0.0,10.0.0)", + org.eclipse.jetty.util.log;version="[9.0.0,10.0.0)", + org.eclipse.jetty.util.security;version="[9.0.0,10.0.0)", + org.eclipse.jetty.util.thread;version="[9.0.0,10.0.0)", + org.eclipse.jgit.junit.http;version="[4.3.0,4.4.0)", + org.eclipse.jgit.lfs.lib;version="[4.3.0,4.4.0)", + org.eclipse.jgit.lfs.server.fs;version="[4.3.0,4.4.0)", + org.eclipse.jgit.lfs.test;version="[4.3.0,4.4.0)", + org.eclipse.jgit.util;version="[4.3.0,4.4.0)", + org.hamcrest.core;version="[1.1.0,2.0.0)", + org.junit;version="[4.0.0,5.0.0)", + org.junit.runner;version="[4.0.0,5.0.0)", + org.junit.runners;version="[4.0.0,5.0.0)" diff --git a/org.eclipse.jgit.lfs.server.test/build.properties b/org.eclipse.jgit.lfs.server.test/build.properties new file mode 100644 index 000000000..9ffa0caf7 --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/build.properties @@ -0,0 +1,5 @@ +source.. = tst/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.properties diff --git a/org.eclipse.jgit.lfs.server.test/plugin.properties b/org.eclipse.jgit.lfs.server.test/plugin.properties new file mode 100644 index 000000000..4a8e6425f --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/plugin.properties @@ -0,0 +1,2 @@ +plugin_name=JGit LFS Server Tests +provider_name=Eclipse JGit diff --git a/org.eclipse.jgit.lfs.server.test/pom.xml b/org.eclipse.jgit.lfs.server.test/pom.xml new file mode 100644 index 000000000..15461aa0e --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/pom.xml @@ -0,0 +1,146 @@ + + + + + 4.0.0 + + + org.eclipse.jgit + org.eclipse.jgit-parent + 4.3.0-SNAPSHOT + + + org.eclipse.jgit.lfs.server.test + JGit - LFS Server Tests + + + Tests for the LFS server. + + + + + junit + junit + test + + + + org.eclipse.jgit + org.eclipse.jgit + ${project.version} + test + + + + org.eclipse.jgit + org.eclipse.jgit.lfs.server + ${project.version} + test + + + + org.eclipse.jgit + org.eclipse.jgit.lfs.test + ${project.version} + test + + + + org.eclipse.jgit + org.eclipse.jgit.junit.http + ${project.version} + test + + + + org.eclipse.jgit + org.eclipse.jgit.junit + ${project.version} + test + + + + org.eclipse.jetty + jetty-servlet + test + + + + org.apache.httpcomponents + httpclient + 4.3.6 + + + + + tst/ + + + + tst-rsrc/ + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + + + maven-surefire-plugin + + -Djava.io.tmpdir=${project.build.directory} -Xmx300m + + + + + diff --git a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/DownloadTest.java b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/DownloadTest.java new file mode 100644 index 000000000..6c4f3cbb9 --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/DownloadTest.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2015, Matthias Sohn + * 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.lfs.server.fs; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.text.MessageFormat; + +import org.apache.http.client.ClientProtocolException; +import org.eclipse.jgit.lfs.lib.AnyLongObjectId; +import org.eclipse.jgit.lfs.test.LongObjectIdTestUtils; +import org.eclipse.jgit.util.FileUtils; +import org.junit.Test; + +public class DownloadTest extends LfsServerTest { + + @Test + public void testDownload() throws Exception { + String TEXT = "test"; + AnyLongObjectId id = putContent(TEXT); + Path f = Paths.get(getTempDirectory().toString(), "download"); + long len = getContent(id, f); + assertEquals(TEXT.length(), len); + FileUtils.delete(f.toFile(), FileUtils.RETRY); + } + + @Test + public void testDownloadInvalidPathInfo() + throws ClientProtocolException, IOException { + String TEXT = "test"; + AnyLongObjectId id = putContent(TEXT); + Path f = Paths.get(getTempDirectory().toString(), "download"); + try { + getContent(id.name().substring(0, 60), f); + fail("expected RuntimeException"); + } catch (RuntimeException e) { + assertEquals("Status: 400 Bad Request", + e.getMessage()); + } + } + + @Test + public void testDownloadInvalidId() + throws ClientProtocolException, IOException { + String TEXT = "test"; + AnyLongObjectId id = putContent(TEXT); + Path f = Paths.get(getTempDirectory().toString(), "download"); + try { + getContent(id.name().replace('f', 'z'), f); + fail("expected RuntimeException"); + } catch (RuntimeException e) { + assertEquals("Status: 400 Bad Request", + e.getMessage()); + } + } + + @Test + public void testDownloadNotFound() + throws ClientProtocolException, IOException { + String TEXT = "test"; + AnyLongObjectId id = LongObjectIdTestUtils.hash(TEXT); + Path f = Paths.get(getTempDirectory().toString(), "download"); + try { + getContent(id, f); + fail("expected RuntimeException"); + } catch (RuntimeException e) { + assertEquals("Status: 404 Not Found", + e.getMessage()); + } + } + + @SuppressWarnings("boxing") + @Test + public void testLargeFileDownload() throws Exception { + Path f = Paths.get(getTempDirectory().toString(), "largeRandomFile"); + long expectedLen = createPseudoRandomContentFile(f, 5 * MiB); + AnyLongObjectId id = putContent(f); + Path f2 = Paths.get(getTempDirectory().toString(), "download"); + long start = System.nanoTime(); + long len = getContent(id, f2); + System.out.println( + MessageFormat.format("dowloaded 10 MiB random data in {0}ms", + (System.nanoTime() - start) / 1e6)); + assertEquals(expectedLen, len); + FileUtils.delete(f.toFile(), FileUtils.RETRY); + + } +} diff --git a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java new file mode 100644 index 000000000..8c266d483 --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2015, Matthias Sohn + * 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.lfs.server.fs; + +import static org.junit.Assert.assertEquals; + +import java.io.BufferedInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.channels.Channels; +import java.nio.channels.FileChannel; +import java.nio.channels.ReadableByteChannel; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.security.DigestInputStream; +import java.security.SecureRandom; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.StatusLine; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.InputStreamEntity; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jgit.junit.http.AppServer; +import org.eclipse.jgit.lfs.lib.AnyLongObjectId; +import org.eclipse.jgit.lfs.lib.Constants; +import org.eclipse.jgit.lfs.lib.LongObjectId; +import org.eclipse.jgit.lfs.test.LongObjectIdTestUtils; +import org.eclipse.jgit.util.FileUtils; +import org.junit.After; +import org.junit.Before; + +@SuppressWarnings("restriction") +public abstract class LfsServerTest { + + private static final long timeout = /* 10 sec */ 10 * 1000; + + protected static final int MiB = 1024 * 1024; + + /** In-memory application server; subclass must start. */ + protected AppServer server; + + private Path tmp; + + private Path dir; + + protected FileLfsRepository repository; + + protected FileLfsServlet servlet; + + public LfsServerTest() { + super(); + } + + public Path getTempDirectory() { + return tmp; + } + + public Path getDir() { + return dir; + } + + @Before + public void setup() throws Exception { + tmp = Files.createTempDirectory("jgit_test_"); + server = new AppServer(); + ServletContextHandler app = server.addContext("/lfs"); + dir = Paths.get(tmp.toString(), "lfs"); + this.repository = new FileLfsRepository(null, dir); + servlet = new FileLfsServlet(repository, timeout); + app.addServlet(new ServletHolder(servlet), "/objects/*"); + server.setUp(); + } + + @After + public void tearDown() throws Exception { + server.tearDown(); + FileUtils.delete(tmp.toFile(), FileUtils.RECURSIVE | FileUtils.RETRY); + } + + protected AnyLongObjectId putContent(String s) + throws IOException, ClientProtocolException { + AnyLongObjectId id = LongObjectIdTestUtils.hash(s); + return putContent(id, s); + } + + protected AnyLongObjectId putContent(AnyLongObjectId id, String s) + throws ClientProtocolException, IOException { + try (CloseableHttpClient client = HttpClientBuilder.create().build()) { + HttpEntity entity = new StringEntity(s, + ContentType.APPLICATION_OCTET_STREAM); + String hexId = id.name(); + HttpPut request = new HttpPut( + server.getURI() + "/lfs/objects/" + hexId); + request.setEntity(entity); + try (CloseableHttpResponse response = client.execute(request)) { + StatusLine statusLine = response.getStatusLine(); + int status = statusLine.getStatusCode(); + if (status >= 400) { + throw new RuntimeException("Status: " + status + ". " + + statusLine.getReasonPhrase()); + } + } + return id; + } + } + + protected LongObjectId putContent(Path f) + throws FileNotFoundException, IOException { + try (CloseableHttpClient client = HttpClientBuilder.create().build()) { + LongObjectId id1, id2; + String hexId1, hexId2; + try (DigestInputStream in = new DigestInputStream( + new BufferedInputStream(Files.newInputStream(f)), + Constants.newMessageDigest())) { + InputStreamEntity entity = new InputStreamEntity(in, + Files.size(f), ContentType.APPLICATION_OCTET_STREAM); + id1 = LongObjectIdTestUtils.hash(f); + hexId1 = id1.name(); + HttpPut request = new HttpPut( + server.getURI() + "/lfs/objects/" + hexId1); + request.setEntity(entity); + HttpResponse response = client.execute(request); + checkResponseStatus(response); + id2 = LongObjectId.fromRaw(in.getMessageDigest().digest()); + hexId2 = id2.name(); + assertEquals(hexId1, hexId2); + } + return id1; + } + } + + private void checkResponseStatus(HttpResponse response) { + StatusLine statusLine = response.getStatusLine(); + int status = statusLine.getStatusCode(); + if (statusLine.getStatusCode() >= 400) { + throw new RuntimeException("Status: " + status + " " + + statusLine.getReasonPhrase()); + } + assertEquals(200, status); + } + + protected long getContent(AnyLongObjectId id, Path f) throws IOException { + String hexId = id.name(); + return getContent(hexId, f); + } + + protected long getContent(String hexId, Path f) throws IOException { + try (CloseableHttpClient client = HttpClientBuilder.create().build()) { + HttpGet request = new HttpGet( + server.getURI() + "/lfs/objects/" + hexId); + HttpResponse response = client.execute(request); + checkResponseStatus(response); + HttpEntity entity = response.getEntity(); + long pos = 0; + try (InputStream in = entity.getContent(); + ReadableByteChannel inChannel = Channels.newChannel(in); + FileChannel outChannel = FileChannel.open(f, + StandardOpenOption.CREATE_NEW, + StandardOpenOption.WRITE)) { + long transferred; + do { + transferred = outChannel.transferFrom(inChannel, pos, MiB); + pos += transferred; + } while (transferred > 0); + } + return pos; + } + } + + /** + * Creates a file with random content, repeatedly writing a random string of + * 4k length to the file until the file has at least the specified length. + * + * @param f + * file to fill + * @param size + * size of the file to generate + * @return length of the generated file in bytes + * @throws IOException + */ + protected long createPseudoRandomContentFile(Path f, long size) + throws IOException { + SecureRandom rnd = new SecureRandom(); + byte[] buf = new byte[4096]; + rnd.nextBytes(buf); + ByteBuffer bytebuf = ByteBuffer.wrap(buf); + try (FileChannel outChannel = FileChannel.open(f, + StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)) { + long len = 0; + do { + len += outChannel.write(bytebuf); + if (bytebuf.position() == 4096) { + bytebuf.rewind(); + } + } while (len < size); + } + return Files.size(f); + } +} \ No newline at end of file diff --git a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java new file mode 100644 index 000000000..35bf09b0c --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2015, Matthias Sohn + * 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.lfs.server.fs; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.text.MessageFormat; + +import org.eclipse.jgit.lfs.lib.AnyLongObjectId; +import org.eclipse.jgit.lfs.lib.LongObjectId; +import org.eclipse.jgit.lfs.test.LongObjectIdTestUtils; +import org.junit.Test; + +public class UploadTest extends LfsServerTest { + + @Test + public void testUpload() throws Exception { + String TEXT = "test"; + AnyLongObjectId id = putContent(TEXT); + assertTrue("expect object " + id.name() + " to exist", + repository.getSize(id) >= 0); + assertEquals("expected object length " + TEXT.length(), TEXT.length(), + repository.getSize(id)); + } + + @Test + public void testCorruptUpload() throws Exception { + String TEXT = "test"; + AnyLongObjectId id = LongObjectIdTestUtils.hash("wrongHash"); + try { + putContent(id, TEXT); + fail("expected RuntimeException(\"Status 400\")"); + } catch (RuntimeException e) { + assertEquals("Status: 400. Bad Request", e.getMessage()); + } + assertFalse("expect object " + id.name() + " not to exist", + repository.getSize(id) >= 0); + } + + @SuppressWarnings("boxing") + @Test + public void testLargeFileUpload() throws Exception { + Path f = Paths.get(getTempDirectory().toString(), "largeRandomFile"); + createPseudoRandomContentFile(f, 5 * MiB); + long start = System.nanoTime(); + LongObjectId id = putContent(f); + System.out.println( + MessageFormat.format("uploaded 10 MiB random data in {0}ms", + (System.nanoTime() - start) / 1e6)); + assertTrue("expect object " + id.name() + " to exist", + repository.getSize(id) >= 0); + assertEquals("expected object length " + Files.size(f), Files.size(f), + repository.getSize(id)); + } +} diff --git a/org.eclipse.jgit.lfs.server/.classpath b/org.eclipse.jgit.lfs.server/.classpath new file mode 100644 index 000000000..04a2be7bd --- /dev/null +++ b/org.eclipse.jgit.lfs.server/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/org.eclipse.jgit.lfs.server/.fbprefs b/org.eclipse.jgit.lfs.server/.fbprefs new file mode 100644 index 000000000..81a0767ff --- /dev/null +++ b/org.eclipse.jgit.lfs.server/.fbprefs @@ -0,0 +1,125 @@ +#FindBugs User Preferences +#Mon May 04 16:24:13 PDT 2009 +detectorAppendingToAnObjectOutputStream=AppendingToAnObjectOutputStream|true +detectorBadAppletConstructor=BadAppletConstructor|false +detectorBadResultSetAccess=BadResultSetAccess|true +detectorBadSyntaxForRegularExpression=BadSyntaxForRegularExpression|true +detectorBadUseOfReturnValue=BadUseOfReturnValue|true +detectorBadlyOverriddenAdapter=BadlyOverriddenAdapter|true +detectorBooleanReturnNull=BooleanReturnNull|true +detectorCallToUnsupportedMethod=CallToUnsupportedMethod|true +detectorCheckImmutableAnnotation=CheckImmutableAnnotation|true +detectorCheckTypeQualifiers=CheckTypeQualifiers|true +detectorCloneIdiom=CloneIdiom|false +detectorComparatorIdiom=ComparatorIdiom|true +detectorConfusedInheritance=ConfusedInheritance|true +detectorConfusionBetweenInheritedAndOuterMethod=ConfusionBetweenInheritedAndOuterMethod|true +detectorCrossSiteScripting=CrossSiteScripting|true +detectorDoInsideDoPrivileged=DoInsideDoPrivileged|true +detectorDontCatchIllegalMonitorStateException=DontCatchIllegalMonitorStateException|true +detectorDontUseEnum=DontUseEnum|true +detectorDroppedException=DroppedException|true +detectorDumbMethodInvocations=DumbMethodInvocations|true +detectorDumbMethods=DumbMethods|true +detectorDuplicateBranches=DuplicateBranches|true +detectorEmptyZipFileEntry=EmptyZipFileEntry|true +detectorEqualsOperandShouldHaveClassCompatibleWithThis=EqualsOperandShouldHaveClassCompatibleWithThis|true +detectorFinalizerNullsFields=FinalizerNullsFields|true +detectorFindBadCast2=FindBadCast2|true +detectorFindBadForLoop=FindBadForLoop|true +detectorFindCircularDependencies=FindCircularDependencies|false +detectorFindDeadLocalStores=FindDeadLocalStores|true +detectorFindDoubleCheck=FindDoubleCheck|true +detectorFindEmptySynchronizedBlock=FindEmptySynchronizedBlock|true +detectorFindFieldSelfAssignment=FindFieldSelfAssignment|true +detectorFindFinalizeInvocations=FindFinalizeInvocations|true +detectorFindFloatEquality=FindFloatEquality|true +detectorFindHEmismatch=FindHEmismatch|true +detectorFindInconsistentSync2=FindInconsistentSync2|true +detectorFindJSR166LockMonitorenter=FindJSR166LockMonitorenter|true +detectorFindLocalSelfAssignment2=FindLocalSelfAssignment2|true +detectorFindMaskedFields=FindMaskedFields|true +detectorFindMismatchedWaitOrNotify=FindMismatchedWaitOrNotify|true +detectorFindNakedNotify=FindNakedNotify|true +detectorFindNonSerializableStoreIntoSession=FindNonSerializableStoreIntoSession|true +detectorFindNonSerializableValuePassedToWriteObject=FindNonSerializableValuePassedToWriteObject|true +detectorFindNonShortCircuit=FindNonShortCircuit|true +detectorFindNullDeref=FindNullDeref|true +detectorFindNullDerefsInvolvingNonShortCircuitEvaluation=FindNullDerefsInvolvingNonShortCircuitEvaluation|true +detectorFindOpenStream=FindOpenStream|true +detectorFindPuzzlers=FindPuzzlers|true +detectorFindRefComparison=FindRefComparison|true +detectorFindReturnRef=FindReturnRef|true +detectorFindRunInvocations=FindRunInvocations|true +detectorFindSelfComparison=FindSelfComparison|true +detectorFindSelfComparison2=FindSelfComparison2|true +detectorFindSleepWithLockHeld=FindSleepWithLockHeld|true +detectorFindSpinLoop=FindSpinLoop|true +detectorFindSqlInjection=FindSqlInjection|true +detectorFindTwoLockWait=FindTwoLockWait|true +detectorFindUncalledPrivateMethods=FindUncalledPrivateMethods|true +detectorFindUnconditionalWait=FindUnconditionalWait|true +detectorFindUninitializedGet=FindUninitializedGet|true +detectorFindUnrelatedTypesInGenericContainer=FindUnrelatedTypesInGenericContainer|true +detectorFindUnreleasedLock=FindUnreleasedLock|true +detectorFindUnsatisfiedObligation=FindUnsatisfiedObligation|true +detectorFindUnsyncGet=FindUnsyncGet|true +detectorFindUselessControlFlow=FindUselessControlFlow|true +detectorFormatStringChecker=FormatStringChecker|true +detectorHugeSharedStringConstants=HugeSharedStringConstants|true +detectorIDivResultCastToDouble=IDivResultCastToDouble|true +detectorIncompatMask=IncompatMask|true +detectorInconsistentAnnotations=InconsistentAnnotations|true +detectorInefficientMemberAccess=InefficientMemberAccess|false +detectorInefficientToArray=InefficientToArray|true +detectorInfiniteLoop=InfiniteLoop|true +detectorInfiniteRecursiveLoop=InfiniteRecursiveLoop|true +detectorInfiniteRecursiveLoop2=InfiniteRecursiveLoop2|false +detectorInheritanceUnsafeGetResource=InheritanceUnsafeGetResource|true +detectorInitializationChain=InitializationChain|true +detectorInstantiateStaticClass=InstantiateStaticClass|true +detectorInvalidJUnitTest=InvalidJUnitTest|true +detectorIteratorIdioms=IteratorIdioms|true +detectorLazyInit=LazyInit|true +detectorLoadOfKnownNullValue=LoadOfKnownNullValue|true +detectorMethodReturnCheck=MethodReturnCheck|true +detectorMultithreadedInstanceAccess=MultithreadedInstanceAccess|true +detectorMutableLock=MutableLock|true +detectorMutableStaticFields=MutableStaticFields|true +detectorNaming=Naming|true +detectorNumberConstructor=NumberConstructor|true +detectorOverridingEqualsNotSymmetrical=OverridingEqualsNotSymmetrical|true +detectorPreferZeroLengthArrays=PreferZeroLengthArrays|true +detectorPublicSemaphores=PublicSemaphores|false +detectorQuestionableBooleanAssignment=QuestionableBooleanAssignment|true +detectorReadReturnShouldBeChecked=ReadReturnShouldBeChecked|true +detectorRedundantInterfaces=RedundantInterfaces|true +detectorRepeatedConditionals=RepeatedConditionals|true +detectorRuntimeExceptionCapture=RuntimeExceptionCapture|true +detectorSerializableIdiom=SerializableIdiom|true +detectorStartInConstructor=StartInConstructor|true +detectorStaticCalendarDetector=StaticCalendarDetector|true +detectorStringConcatenation=StringConcatenation|true +detectorSuperfluousInstanceOf=SuperfluousInstanceOf|true +detectorSuspiciousThreadInterrupted=SuspiciousThreadInterrupted|true +detectorSwitchFallthrough=SwitchFallthrough|true +detectorSynchronizeAndNullCheckField=SynchronizeAndNullCheckField|true +detectorSynchronizeOnClassLiteralNotGetClass=SynchronizeOnClassLiteralNotGetClass|true +detectorSynchronizingOnContentsOfFieldToProtectField=SynchronizingOnContentsOfFieldToProtectField|true +detectorURLProblems=URLProblems|true +detectorUncallableMethodOfAnonymousClass=UncallableMethodOfAnonymousClass|true +detectorUnnecessaryMath=UnnecessaryMath|true +detectorUnreadFields=UnreadFields|true +detectorUseObjectEquals=UseObjectEquals|false +detectorUselessSubclassMethod=UselessSubclassMethod|false +detectorVarArgsProblems=VarArgsProblems|true +detectorVolatileUsage=VolatileUsage|true +detectorWaitInLoop=WaitInLoop|true +detectorWrongMapIterator=WrongMapIterator|true +detectorXMLFactoryBypass=XMLFactoryBypass|true +detector_threshold=2 +effort=default +excludefilter0=findBugs/FindBugsExcludeFilter.xml +filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,MT_CORRECTNESS,PERFORMANCE,STYLE|false +filter_settings_neg=MALICIOUS_CODE,NOISE,I18N,SECURITY,EXPERIMENTAL| +run_at_full_build=true diff --git a/org.eclipse.jgit.lfs.server/.gitignore b/org.eclipse.jgit.lfs.server/.gitignore new file mode 100644 index 000000000..934e0e06f --- /dev/null +++ b/org.eclipse.jgit.lfs.server/.gitignore @@ -0,0 +1,2 @@ +/bin +/target diff --git a/org.eclipse.jgit.lfs.server/.project b/org.eclipse.jgit.lfs.server/.project new file mode 100644 index 000000000..8379fea67 --- /dev/null +++ b/org.eclipse.jgit.lfs.server/.project @@ -0,0 +1,34 @@ + + + org.eclipse.jgit.lfs.server + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.api.tools.apiAnalysisBuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + org.eclipse.pde.api.tools.apiAnalysisNature + + diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 000000000..99f26c020 --- /dev/null +++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.core.runtime.prefs new file mode 100644 index 000000000..5a0ad22d2 --- /dev/null +++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.core.runtime.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +line.separator=\n diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..ff39d16ab --- /dev/null +++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,398 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled +org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.7 +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.comparingIdentical=error +org.eclipse.jdt.core.compiler.problem.deadCode=error +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.explicitlyClosedAutoCloseable=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled +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.includeNullInfoFromAsserts=enabled +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.missingDefaultCase=ignore +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error +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.missingJavadocTagsMethodTypeParameters=disabled +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning +org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error +org.eclipse.jdt.core.compiler.problem.nullReference=error +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=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.potentiallyUnclosedCloseable=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +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.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=error +org.eclipse.jdt.core.compiler.problem.unusedLabel=error +org.eclipse.jdt.core.compiler.problem.unusedLocal=error +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=warning +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error +org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error +org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=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.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=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_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=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_on_off_tags=true +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..c336cce6e --- /dev/null +++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,61 @@ +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=_JGit Format +formatter_settings_version=12 +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= +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_missing_override_annotations_interface_methods=false +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=true +sp_cleanup.format_source_code_changes_only=true +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 diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.mylyn.tasks.ui.prefs new file mode 100644 index 000000000..3dec4d97c --- /dev/null +++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.mylyn.tasks.ui.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +project.repository.kind=bugzilla +project.repository.url=https\://bugs.eclipse.org/bugs diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.mylyn.team.ui.prefs new file mode 100644 index 000000000..ce7a0f047 --- /dev/null +++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.mylyn.team.ui.prefs @@ -0,0 +1,2 @@ +commit.comment.template=${task.description} \n\nBug\: ${task.key} +eclipse.preferences.version=1 diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.pde.api.tools.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.pde.api.tools.prefs new file mode 100644 index 000000000..3294d4f79 --- /dev/null +++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.pde.api.tools.prefs @@ -0,0 +1,98 @@ +ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error +ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error +ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error +ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error +ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error +API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error +API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error +API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error +API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error +API_USE_SCAN_FIELD_SEVERITY=Error +API_USE_SCAN_METHOD_SEVERITY=Error +API_USE_SCAN_TYPE_SEVERITY=Error +CLASS_ELEMENT_TYPE_ADDED_METHOD=Error +CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error +CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error +CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error +CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error +CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error +CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error +CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error +CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error +CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error +CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error +CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error +CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error +CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error +CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error +CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error +CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error +CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error +ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error +ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error +ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error +ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error +ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error +ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error +FIELD_ELEMENT_TYPE_ADDED_VALUE=Error +FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error +FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error +FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error +FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error +FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error +FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error +FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error +FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error +FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error +ILLEGAL_EXTEND=Warning +ILLEGAL_IMPLEMENT=Warning +ILLEGAL_INSTANTIATE=Warning +ILLEGAL_OVERRIDE=Warning +ILLEGAL_REFERENCE=Warning +INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error +INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error +INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error +INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error +INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error +INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error +INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error +INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error +INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error +INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error +INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error +INVALID_ANNOTATION=Ignore +INVALID_JAVADOC_TAG=Ignore +INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Error +LEAK_EXTEND=Warning +LEAK_FIELD_DECL=Warning +LEAK_IMPLEMENT=Warning +LEAK_METHOD_PARAM=Warning +LEAK_METHOD_RETURN_TYPE=Warning +METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error +METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error +METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error +METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error +METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error +METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error +METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error +METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error +METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error +METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error +MISSING_EE_DESCRIPTIONS=Error +TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error +TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error +TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error +TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error +TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error +TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error +UNUSED_PROBLEM_FILTERS=Warning +automatically_removed_unused_problem_filters=false +eclipse.preferences.version=1 +incompatible_api_component_version=Error +incompatible_api_component_version_include_major_without_breaking_change=Disabled +incompatible_api_component_version_include_minor_without_api_change=Disabled +invalid_since_tag_version=Error +malformed_since_tag=Error +missing_since_tag=Error +report_api_breakage_when_major_version_incremented=Disabled +report_resolution_errors_api_component=Warning diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.pde.core.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 000000000..923c37fb8 --- /dev/null +++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +resolve.requirebundle=false diff --git a/org.eclipse.jgit.lfs.server/BUCK b/org.eclipse.jgit.lfs.server/BUCK new file mode 100644 index 000000000..6b40b7c12 --- /dev/null +++ b/org.eclipse.jgit.lfs.server/BUCK @@ -0,0 +1,22 @@ +SRCS = glob(['src/**']) +RESOURCES = glob(['resources/**']) + +java_library( + name = 'jgit-lfs-server', + srcs = SRCS, + resources = RESOURCES, + deps = [ + '//org.eclipse.jgit.http.apache:http-apache', + '//org.eclipse.jgit:jgit', + '//org.eclipse.jgit.lfs:jgit-lfs', + '//lib:gson', + '//lib:httpcore', + '//lib:servlet-api' + ], + visibility = ['PUBLIC'], +) + +java_sources( + name = 'jgit-lfs-server_src', + srcs = SRCS + RESOURCES, +) diff --git a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF new file mode 100644 index 000000000..b0ff74075 --- /dev/null +++ b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF @@ -0,0 +1,28 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %plugin_name +Bundle-SymbolicName: org.eclipse.jgit.lfs.server +Bundle-Version: 4.3.0.qualifier +Bundle-Localization: plugin +Bundle-Vendor: %provider_name +Export-Package: org.eclipse.jgit.lfs.server;version="4.3.0"; + uses:="javax.servlet.http, + org.eclipse.jgit.lfs.lib", + org.eclipse.jgit.lfs.server.fs;version="4.3.0"; + uses:="javax.servlet, + javax.servlet.http, + org.eclipse.jgit.lfs.server, + org.eclipse.jgit.lfs.lib", + org.eclipse.jgit.lfs.server.internal;version="4.3.0";x-internal:=true +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Import-Package: com.google.gson;version="[2.2.4,3.0.0)", + javax.servlet;version="[3.1.0,4.0.0)", + javax.servlet.annotation;version="[3.1.0,4.0.0)", + javax.servlet.http;version="[3.1.0,4.0.0)", + org.apache.http;version="[4.3.0,5.0.0)", + org.eclipse.jgit.annotations;version="[4.3.0,4.4.0)", + org.eclipse.jgit.internal.storage.file;version="[4.3.0,4.4.0)", + org.eclipse.jgit.lfs.errors;version="[4.3.0,4.4.0)", + org.eclipse.jgit.lfs.lib;version="[4.3.0,4.4.0)", + org.eclipse.jgit.nls;version="[4.3.0,4.4.0)", + org.eclipse.jgit.util;version="[4.3.0,4.4.0)" diff --git a/org.eclipse.jgit.lfs.server/about.html b/org.eclipse.jgit.lfs.server/about.html new file mode 100644 index 000000000..01a267187 --- /dev/null +++ b/org.eclipse.jgit.lfs.server/about.html @@ -0,0 +1,59 @@ + + + + + + +Eclipse Distribution License - Version 1.0 + + + + + + +

Eclipse Distribution License - v 1.0

+ +

Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors.

+ +

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.

+ + + + diff --git a/org.eclipse.jgit.lfs.server/build.properties b/org.eclipse.jgit.lfs.server/build.properties new file mode 100644 index 000000000..8148271ef --- /dev/null +++ b/org.eclipse.jgit.lfs.server/build.properties @@ -0,0 +1,7 @@ +source.. = src/,\ + resources/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.properties,\ + about.html diff --git a/org.eclipse.jgit.lfs.server/plugin.properties b/org.eclipse.jgit.lfs.server/plugin.properties new file mode 100644 index 000000000..59f0139b8 --- /dev/null +++ b/org.eclipse.jgit.lfs.server/plugin.properties @@ -0,0 +1,2 @@ +plugin_name=JGit Large File Storage Server +provider_name=Eclipse JGit diff --git a/org.eclipse.jgit.lfs.server/pom.xml b/org.eclipse.jgit.lfs.server/pom.xml new file mode 100644 index 000000000..8cfdf3b2e --- /dev/null +++ b/org.eclipse.jgit.lfs.server/pom.xml @@ -0,0 +1,158 @@ + + + + + 4.0.0 + + + org.eclipse.jgit + org.eclipse.jgit-parent + 4.3.0-SNAPSHOT + + + org.eclipse.jgit.lfs.server + JGit - Large File Storage Server + + + JGit Large File Storage Server implementation. + + + + + + + + + org.eclipse.jgit + org.eclipse.jgit + ${project.version} + + + + org.eclipse.jgit + org.eclipse.jgit.lfs + ${project.version} + + + + javax.servlet + javax.servlet-api + provided + + + + com.google.code.gson + gson + + + + + src/ + + + + . + + plugin.properties + about.html + + + + resources/ + + + + + + org.apache.maven.plugins + maven-source-plugin + true + + + attach-sources + process-classes + + jar + + + + ${source-bundle-manifest} + + + + + + + + maven-jar-plugin + + + ${bundle-manifest} + + + + + + org.codehaus.mojo + clirr-maven-plugin + + + + + + + + org.codehaus.mojo + clirr-maven-plugin + ${clirr-version} + + ${jgit-last-release-version} + info + + + + + diff --git a/org.eclipse.jgit.lfs.server/resources/org/eclipse/jgit/lfs/server/internal/LfsServerText.properties b/org.eclipse.jgit.lfs.server/resources/org/eclipse/jgit/lfs/server/internal/LfsServerText.properties new file mode 100644 index 000000000..752a774d1 --- /dev/null +++ b/org.eclipse.jgit.lfs.server/resources/org/eclipse/jgit/lfs/server/internal/LfsServerText.properties @@ -0,0 +1,4 @@ +corruptLongObject=The content hash ''{0}'' of the long object ''{1}'' doesn''t match its id, the corrupt object will be deleted. +invalidPathInfo=Invalid pathInfo ''{0}'' does not match ''/'{'SHA-256'}''' +objectNotFound=Object ''{0}'' not found +unsupportedOperation=Operation ''{0}'' is not supported diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LargeFileRepository.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LargeFileRepository.java new file mode 100644 index 000000000..3bdf8d08b --- /dev/null +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LargeFileRepository.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2015, Matthias Sohn + * 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.lfs.server; + +import java.io.IOException; + +import org.eclipse.jgit.annotations.Nullable; +import org.eclipse.jgit.lfs.lib.AnyLongObjectId; + +/** + * Abstraction of a repository for storing large objects + * + * @since 4.3 + */ +public interface LargeFileRepository { + + /** + * @param id + * id of the object to download + * @return Action for downloading the object + */ + public Response.Action getDownloadAction(AnyLongObjectId id); + + /** + * @param id + * id of the object to upload + * @param size + * size of the object to be uploaded + * @return Action for uploading the object + */ + public Response.Action getUploadAction(AnyLongObjectId id, long size); + + /** + * @param id + * id of the object to be verified + * @return Action for verifying the object, or {@code null} if the server + * doesn't support or require verification + */ + public @Nullable Response.Action getVerifyAction(AnyLongObjectId id); + + /** + * @param id + * id of the object + * @return length of the object content in bytes, -1 if the object doesn't + * exist + * @throws IOException + */ + public long getSize(AnyLongObjectId id) throws IOException; +} diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsObject.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsObject.java new file mode 100644 index 000000000..30ba22e88 --- /dev/null +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsObject.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2015, Sasa Zivkov + * 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.lfs.server; + +class LfsObject { + String oid; + long size; +} diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java new file mode 100644 index 000000000..394137cf6 --- /dev/null +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2015, Sasa Zivkov + * 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.lfs.server; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static javax.servlet.http.HttpServletResponse.SC_OK; +import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; +import java.util.List; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.google.gson.FieldNamingPolicy; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +/** + * LFS protocol handler implementing the LFS batch API [1] + * + * [1] https://github.com/github/git-lfs/blob/master/docs/api/http-v1-batch.md + * + * @since 4.3 + */ +public abstract class LfsProtocolServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + private static final String CONTENTTYPE_VND_GIT_LFS_JSON = "application/vnd.git-lfs+json"; //$NON-NLS-1$ + + private Gson gson = createGson(); + + /** + * Get the large file repository + * + * @return the large file repository storing large files + */ + protected abstract LargeFileRepository getLargeFileRepository(); + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse res) + throws ServletException, IOException { + res.setStatus(SC_OK); + res.setContentType(CONTENTTYPE_VND_GIT_LFS_JSON); + + Writer w = new BufferedWriter( + new OutputStreamWriter(res.getOutputStream(), UTF_8)); + + Reader r = new BufferedReader(new InputStreamReader(req.getInputStream(), UTF_8)); + LfsRequest request = gson.fromJson(r, LfsRequest.class); + + LargeFileRepository repo = getLargeFileRepository(); + if (repo == null) { + res.setStatus(SC_SERVICE_UNAVAILABLE); + return; + } + + TransferHandler handler = TransferHandler + .forOperation(request.operation, repo, request.objects); + gson.toJson(handler.process(), w); + w.flush(); + } + + private static class LfsRequest { + String operation; + + List objects; + } + + private static Gson createGson() { + GsonBuilder gb = new GsonBuilder() + .setFieldNamingPolicy( + FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) + .setPrettyPrinting().disableHtmlEscaping(); + return gb.create(); + } +} diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/Response.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/Response.java new file mode 100644 index 000000000..dc972e04e --- /dev/null +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/Response.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2015, Sasa Zivkov + * 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.lfs.server; + +import java.util.List; +import java.util.Map; + +/** + * POJOs for Gson serialization/deserialization + * + * See + * {@link LFS + * API specification} + * + * @since 4.3 + */ +public interface Response { + /** Describes an action the client can execute on a single object */ + class Action { + public String href; + public Map header; + } + + /** Describes an error to be returned by the LFS batch API */ + class Error { + public int code; + public String message; + } + + /** Describes the actions the LFS server offers for a single object */ + class ObjectInfo { + public String oid; + public long size; + public Map actions; + public Error error; + } + + /** Describes the body of a LFS batch API response */ + class Body { + public List objects; + } +} diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java new file mode 100644 index 000000000..bf5b61cc6 --- /dev/null +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2015, Sasa Zivkov + * 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.lfs.server; + +import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; + +import java.io.IOException; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.eclipse.jgit.lfs.lib.LongObjectId; +import org.eclipse.jgit.lfs.server.Response.Action; +import org.eclipse.jgit.lfs.server.Response.Body; +import org.eclipse.jgit.lfs.server.internal.LfsServerText; + +abstract class TransferHandler { + + private static final String DOWNLOAD = "download"; //$NON-NLS-1$ + private static final String UPLOAD = "upload"; //$NON-NLS-1$ + private static final String VERIFY = "verify"; //$NON-NLS-1$ + + static TransferHandler forOperation(String operation, + LargeFileRepository repository, List objects) { + switch (operation) { + case TransferHandler.UPLOAD: + return new Upload(repository, objects); + case TransferHandler.DOWNLOAD: + return new Download(repository, objects); + case TransferHandler.VERIFY: + default: + throw new UnsupportedOperationException(MessageFormat.format( + LfsServerText.get().unsupportedOperation, operation)); + } + } + + private static class Upload extends TransferHandler { + Upload(LargeFileRepository repository, + List objects) { + super(repository, objects); + } + + @Override + Body process() throws IOException { + Response.Body body = new Response.Body(); + if (objects.size() > 0) { + body.objects = new ArrayList<>(); + for (LfsObject o : objects) { + addObjectInfo(body, o); + } + } + return body; + } + + private void addObjectInfo(Response.Body body, LfsObject o) + throws IOException { + Response.ObjectInfo info = new Response.ObjectInfo(); + body.objects.add(info); + info.oid = o.oid; + info.size = o.size; + + LongObjectId oid = LongObjectId.fromString(o.oid); + if (repository.getSize(oid) == -1) { + info.actions = new HashMap<>(); + info.actions.put(UPLOAD, + repository.getUploadAction(oid, o.size)); + Action verify = repository.getVerifyAction(oid); + if (verify != null) { + info.actions.put(VERIFY, verify); + } + } + } + } + + private static class Download extends TransferHandler { + Download(LargeFileRepository repository, + List objects) { + super(repository, objects); + } + + @Override + Body process() throws IOException { + Response.Body body = new Response.Body(); + if (objects.size() > 0) { + body.objects = new ArrayList<>(); + for (LfsObject o : objects) { + addObjectInfo(body, o); + } + } + return body; + } + + private void addObjectInfo(Response.Body body, LfsObject o) + throws IOException { + Response.ObjectInfo info = new Response.ObjectInfo(); + body.objects.add(info); + info.oid = o.oid; + info.size = o.size; + + LongObjectId oid = LongObjectId.fromString(o.oid); + if (repository.getSize(oid) >= 0) { + info.actions = new HashMap<>(); + info.actions.put(DOWNLOAD, + repository.getDownloadAction(oid)); + } else { + info.error = new Response.Error(); + info.error.code = SC_NOT_FOUND; + info.error.message = MessageFormat.format( + LfsServerText.get().objectNotFound, + oid.getName()); + } + } + } + + final LargeFileRepository repository; + + final List objects; + + TransferHandler(LargeFileRepository repository, + List objects) { + this.repository = repository; + this.objects = objects; + } + + abstract Response.Body process() throws IOException; +} \ No newline at end of file diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/AtomicObjectOutputStream.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/AtomicObjectOutputStream.java new file mode 100644 index 000000000..ecc7c1f36 --- /dev/null +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/AtomicObjectOutputStream.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2015, Matthias Sohn + * 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.lfs.server.fs; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Path; +import java.security.DigestOutputStream; +import java.text.MessageFormat; + +import org.eclipse.jgit.internal.storage.file.LockFile; +import org.eclipse.jgit.lfs.errors.CorruptLongObjectException; +import org.eclipse.jgit.lfs.lib.AnyLongObjectId; +import org.eclipse.jgit.lfs.lib.Constants; +import org.eclipse.jgit.lfs.lib.LongObjectId; +import org.eclipse.jgit.lfs.server.internal.LfsServerText; + +/** + * Output stream writing content to a {@link LockFile} which is committed on + * close(). The stream checks if the hash of the stream content matches the + * id. + */ +class AtomicObjectOutputStream extends OutputStream { + + private LockFile locked; + + private DigestOutputStream out; + + private boolean aborted; + + private AnyLongObjectId id; + + AtomicObjectOutputStream(Path path, AnyLongObjectId id) + throws IOException { + locked = new LockFile(path.toFile()); + locked.lock(); + this.id = id; + out = new DigestOutputStream(locked.getOutputStream(), + Constants.newMessageDigest()); + } + + @Override + public void write(int b) throws IOException { + out.write(b); + } + + @Override + public void write(byte[] b) throws IOException { + out.write(b); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + out.write(b, off, len); + } + + @Override + public void close() throws IOException { + out.close(); + if (!aborted) { + verifyHash(); + locked.commit(); + } + } + + private void verifyHash() { + AnyLongObjectId contentHash = LongObjectId + .fromRaw(out.getMessageDigest().digest()); + if (!contentHash.equals(id)) { + abort(); + throw new CorruptLongObjectException(id, contentHash, + MessageFormat.format(LfsServerText.get().corruptLongObject, + contentHash, id)); + } + } + + void abort() { + locked.unlock(); + aborted = true; + } +} \ No newline at end of file diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java new file mode 100644 index 000000000..12da271b3 --- /dev/null +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2015, Matthias Sohn + * 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.lfs.server.fs; + +import static org.eclipse.jgit.util.HttpSupport.HDR_AUTHORIZATION; + +import java.io.IOException; +import java.nio.channels.Channels; +import java.nio.channels.FileChannel; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.Collections; + +import org.eclipse.jgit.annotations.Nullable; +import org.eclipse.jgit.lfs.lib.AnyLongObjectId; +import org.eclipse.jgit.lfs.lib.Constants; +import org.eclipse.jgit.lfs.server.LargeFileRepository; +import org.eclipse.jgit.lfs.server.Response; +import org.eclipse.jgit.lfs.server.Response.Action; + +/** + * Repository storing large objects in the file system + * + * @since 4.3 + */ +public class FileLfsRepository implements LargeFileRepository { + + private final String url; + private final Path dir; + private AtomicObjectOutputStream out; + + /** + * @param url + * external URL of this repository + * @param dir + * storage directory + * @throws IOException + */ + public FileLfsRepository(String url, Path dir) throws IOException { + this.url = url; + this.dir = dir; + Files.createDirectories(dir); + } + + @Override + public Response.Action getDownloadAction(AnyLongObjectId id) { + return getAction(id); + } + + @Override + public Action getUploadAction(AnyLongObjectId id, long size) { + return getAction(id); + } + + @Override + public @Nullable Action getVerifyAction(AnyLongObjectId id) { + return null; + } + + @Override + public long getSize(AnyLongObjectId id) throws IOException { + Path p = getPath(id); + if (Files.exists(p)) { + return Files.size(p); + } else { + return -1; + } + } + + /** + * Get the storage directory + * + * @return the path of the storage directory + */ + public Path getDir() { + return dir; + } + + /** + * Get the path where the given object is stored + * + * @param id + * id of a large object + * @return path the object's storage path + */ + protected Path getPath(AnyLongObjectId id) { + StringBuilder s = new StringBuilder( + Constants.LONG_OBJECT_ID_STRING_LENGTH + 6); + s.append(toHexCharArray(id.getFirstByte())).append('/'); + s.append(toHexCharArray(id.getSecondByte())).append('/'); + s.append(id.name()); + return dir.resolve(s.toString()); + } + + private Response.Action getAction(AnyLongObjectId id) { + Response.Action a = new Response.Action(); + a.href = url + id.getName(); + a.header = Collections.singletonMap(HDR_AUTHORIZATION, "not:required"); //$NON-NLS-1$ + return a; + } + + ReadableByteChannel getReadChannel(AnyLongObjectId id) + throws IOException { + return FileChannel.open(getPath(id), StandardOpenOption.READ); + } + + WritableByteChannel getWriteChannel(AnyLongObjectId id) + throws IOException { + Path path = getPath(id); + Files.createDirectories(path.getParent()); + out = new AtomicObjectOutputStream(path, id); + return Channels.newChannel(out); + } + + /** + * Abort the output stream + */ + void abortWrite() { + if (out != null) { + out.abort(); + } + } + + private static char[] toHexCharArray(int b) { + final char[] dst = new char[2]; + formatHexChar(dst, 0, b); + return dst; + } + + private static final char[] hexchar = { '0', '1', '2', '3', '4', '5', '6', + '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + + private static void formatHexChar(final char[] dst, final int p, int b) { + int o = p + 1; + while (o >= p && b != 0) { + dst[o--] = hexchar[b & 0xf]; + b >>>= 4; + } + while (o >= p) + dst[o--] = '0'; + } +} diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsServlet.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsServlet.java new file mode 100644 index 000000000..8864af87a --- /dev/null +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsServlet.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2015, Matthias Sohn + * 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.lfs.server.fs; + +import java.io.IOException; +import java.text.MessageFormat; + +import javax.servlet.AsyncContext; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.http.HttpStatus; +import org.eclipse.jgit.lfs.errors.InvalidLongObjectIdException; +import org.eclipse.jgit.lfs.lib.AnyLongObjectId; +import org.eclipse.jgit.lfs.lib.Constants; +import org.eclipse.jgit.lfs.lib.LongObjectId; +import org.eclipse.jgit.lfs.server.internal.LfsServerText; + +/** + * Servlet supporting upload and download of large objects as defined by the + * GitHub Large File Storage extension API extending git to allow separate + * storage of large files + * (https://github.com/github/git-lfs/tree/master/docs/api). + * + * @since 4.3 + */ +@WebServlet(asyncSupported = true) +public class FileLfsServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + private final FileLfsRepository repository; + + private final long timeout; + + /** + * @param repository + * the repository storing the large objects + * @param timeout + * timeout for object upload / download in milliseconds + */ + public FileLfsServlet(FileLfsRepository repository, long timeout) { + this.repository = repository; + this.timeout = timeout; + } + + /** + * Handles object downloads + * + * @param req + * servlet request + * @param rsp + * servlet response + * @throws ServletException + * if a servlet-specific error occurs + * @throws IOException + * if an I/O error occurs + */ + @Override + protected void doGet(HttpServletRequest req, + HttpServletResponse rsp) throws ServletException, IOException { + AnyLongObjectId obj = getObjectToTransfer(req, rsp); + if (obj != null) { + if (repository.getSize(obj) == -1) { + sendError(rsp, HttpStatus.SC_NOT_FOUND, MessageFormat + .format(LfsServerText.get().objectNotFound, obj)); + return; + } + AsyncContext context = req.startAsync(); + context.setTimeout(timeout); + rsp.getOutputStream() + .setWriteListener(new ObjectDownloadListener(repository, + context, rsp, obj)); + } + } + + private AnyLongObjectId getObjectToTransfer(HttpServletRequest req, + HttpServletResponse rsp) throws IOException { + String info = req.getPathInfo(); + if (info.length() != 1 + Constants.LONG_OBJECT_ID_STRING_LENGTH) { + sendError(rsp, HttpStatus.SC_BAD_REQUEST, MessageFormat + .format(LfsServerText.get().invalidPathInfo, info)); + return null; + } + try { + return LongObjectId.fromString(info.substring(1, 65)); + } catch (InvalidLongObjectIdException e) { + sendError(rsp, HttpStatus.SC_BAD_REQUEST, e.getMessage()); + return null; + } + } + + /** + * Handle object uploads + * + * @param req + * servlet request + * @param rsp + * servlet response + * @throws ServletException + * if a servlet-specific error occurs + * @throws IOException + * if an I/O error occurs + */ + @Override + protected void doPut(HttpServletRequest req, + HttpServletResponse rsp) throws ServletException, IOException { + AnyLongObjectId id = getObjectToTransfer(req, rsp); + if (id != null) { + AsyncContext context = req.startAsync(); + context.setTimeout(timeout); + req.getInputStream().setReadListener(new ObjectUploadListener( + repository, context, req, rsp, id)); + } + } + + static void sendError(HttpServletResponse rsp, int status, String message) + throws IOException { + rsp.setStatus(status); + // TODO return message in response body in json format as specified in + // https://github.com/github/git-lfs/blob/master/docs/api/http-v1-batch.md + rsp.flushBuffer(); + } +} diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectDownloadListener.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectDownloadListener.java new file mode 100644 index 000000000..bfdea4fb1 --- /dev/null +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectDownloadListener.java @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2015, Matthias Sohn + * 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.lfs.server.fs; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.servlet.AsyncContext; +import javax.servlet.ServletOutputStream; +import javax.servlet.WriteListener; +import javax.servlet.http.HttpServletResponse; + +import org.apache.http.HttpStatus; +import org.eclipse.jgit.lfs.lib.AnyLongObjectId; +import org.eclipse.jgit.lfs.lib.Constants; +import org.eclipse.jgit.util.HttpSupport; + +/** + * Handle asynchronous large object download + */ +class ObjectDownloadListener implements WriteListener { + + private static Logger LOG = Logger + .getLogger(ObjectDownloadListener.class.getName()); + + private final AsyncContext context; + + private final HttpServletResponse response; + + private final ServletOutputStream out; + + private final ReadableByteChannel in; + + private final WritableByteChannel outChannel; + + private final ByteBuffer buffer = ByteBuffer.allocateDirect(8192); + + /** + * @param repository + * the repository storing large objects + * @param context + * the servlet asynchronous context + * @param response + * the servlet response + * @param id + * id of the object to be downloaded + * @throws IOException + */ + public ObjectDownloadListener(FileLfsRepository repository, + AsyncContext context, HttpServletResponse response, + AnyLongObjectId id) throws IOException { + this.context = context; + this.response = response; + this.in = repository.getReadChannel(id); + this.out = response.getOutputStream(); + this.outChannel = Channels.newChannel(out); + + response.addHeader(HttpSupport.HDR_CONTENT_LENGTH, + String.valueOf(repository.getSize(id))); + response.setContentType(Constants.HDR_APPLICATION_OCTET_STREAM); + } + + /** + * Write file content + * + * @throws IOException + */ + @Override + public void onWritePossible() throws IOException { + while (out.isReady()) { + if (in.read(buffer) != -1) { + buffer.flip(); + outChannel.write(buffer); + buffer.compact(); + } else { + in.close(); + buffer.flip(); + while (out.isReady()) { + if (buffer.hasRemaining()) { + outChannel.write(buffer); + } else { + context.complete(); + } + } + } + } + } + + /** + * Handle errors + * + * @param e + * the cause + */ + @Override + public void onError(Throwable e) { + try { + FileLfsServlet.sendError(response, + HttpStatus.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + context.complete(); + in.close(); + } catch (IOException ex) { + LOG.log(Level.SEVERE, ex.getMessage(), ex); + } + } +} diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java new file mode 100644 index 000000000..05970ad1f --- /dev/null +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2015, Matthias Sohn + * 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.lfs.server.fs; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.servlet.AsyncContext; +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.http.HttpStatus; +import org.eclipse.jgit.lfs.errors.CorruptLongObjectException; +import org.eclipse.jgit.lfs.lib.AnyLongObjectId; +import org.eclipse.jgit.lfs.lib.Constants; + +/** + * Handle asynchronous object upload + */ +class ObjectUploadListener implements ReadListener { + + private static Logger LOG = Logger + .getLogger(ObjectUploadListener.class.getName()); + + private final AsyncContext context; + + private final HttpServletResponse response; + + private FileLfsRepository repository; + + private final ServletInputStream in; + + private final ReadableByteChannel inChannel; + + private WritableByteChannel out; + + private final ByteBuffer buffer = ByteBuffer.allocateDirect(8192); + + /** + * @param repository + * the repository storing large objects + * @param context + * @param request + * @param response + * @param id + * @throws FileNotFoundException + * @throws IOException + */ + public ObjectUploadListener(FileLfsRepository repository, + AsyncContext context, HttpServletRequest request, + HttpServletResponse response, AnyLongObjectId id) + throws FileNotFoundException, IOException { + this.repository = repository; + this.context = context; + this.response = response; + this.in = request.getInputStream(); + this.inChannel = Channels.newChannel(in); + this.out = repository.getWriteChannel(id); + response.setContentType(Constants.CONTENT_TYPE_GIT_LFS_JSON); + } + + /** + * Writes all the received data to the output channel + * + * @throws IOException + */ + @Override + public void onDataAvailable() throws IOException { + while (in.isReady()) { + if (inChannel.read(buffer) > 0) { + buffer.flip(); + out.write(buffer); + buffer.compact(); + } else { + buffer.flip(); + while (buffer.hasRemaining()) { + out.write(buffer); + } + close(); + return; + } + } + } + + /** + * @throws IOException + */ + @Override + public void onAllDataRead() throws IOException { + close(); + } + + protected void close() throws IOException { + try { + inChannel.close(); + out.close(); + // TODO check if status 200 is ok for PUT request, HTTP foresees 204 + // for successful PUT without response body + response.setStatus(HttpServletResponse.SC_OK); + } finally { + context.complete(); + } + } + + /** + * @param e + * the exception that caused the problem + */ + @Override + public void onError(Throwable e) { + try { + repository.abortWrite(); + inChannel.close(); + out.close(); + int status; + if (e instanceof CorruptLongObjectException) { + status = HttpStatus.SC_BAD_REQUEST; + LOG.log(Level.WARNING, e.getMessage(), e); + } else { + status = HttpStatus.SC_INTERNAL_SERVER_ERROR; + LOG.log(Level.SEVERE, e.getMessage(), e); + } + FileLfsServlet.sendError(response, status, e.getMessage()); + } catch (IOException ex) { + LOG.log(Level.SEVERE, ex.getMessage(), ex); + } + } +} \ No newline at end of file diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/internal/LfsServerText.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/internal/LfsServerText.java new file mode 100644 index 000000000..4e1c4c639 --- /dev/null +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/internal/LfsServerText.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2015, Matthias Sohn + * 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.lfs.server.internal; + +import org.eclipse.jgit.nls.NLS; +import org.eclipse.jgit.nls.TranslationBundle; + +/** + * Translation bundle for JGit LFS server + */ +public class LfsServerText extends TranslationBundle { + + /** + * @return an instance of this translation bundle + */ + public static LfsServerText get() { + return NLS.getBundleFor(LfsServerText.class); + } + + // @formatter:off + /***/ public String corruptLongObject; + /***/ public String invalidPathInfo; + /***/ public String objectNotFound; + /***/ public String unsupportedOperation; +} diff --git a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF index 118583c21..61456f1cb 100644 --- a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF @@ -16,5 +16,5 @@ Import-Package: org.eclipse.jgit.junit;version="[4.3.0,4.4.0)", org.junit.runner;version="[4.0.0,5.0.0)", org.junit.runners;version="[4.0.0,5.0.0)" Export-Package: org.eclipse.jgit.lfs.lib;version="4.3.0";x-internal:=true, - org.eclipse.jgit.lfs.test;version="4.3.0";x-internal:=true + org.eclipse.jgit.lfs.test;version="4.3.0";x-friends:="org.eclipse.jgit.lfs.server.test" diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/CorruptLongObjectException.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/CorruptLongObjectException.java new file mode 100644 index 000000000..fea148b88 --- /dev/null +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/CorruptLongObjectException.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2015, Matthias Sohn + * 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.lfs.errors; + +import org.eclipse.jgit.lfs.lib.AnyLongObjectId; + +/** + * Thrown when an object id is given that doesn't match the hash of the object's + * content + * + * @since 4.3 + */ +public class CorruptLongObjectException extends IllegalArgumentException { + + private static final long serialVersionUID = 1L; + + private final AnyLongObjectId id; + + private final AnyLongObjectId contentHash; + + /** + * Corrupt long object detected. + * + * @param id + * id of the long object + * @param contentHash + * hash of the long object's content + * + * @param message + */ + public CorruptLongObjectException(AnyLongObjectId id, + AnyLongObjectId contentHash, + String message) { + super(message); + this.id = id; + this.contentHash = contentHash; + } + + /** + * @return the id of the object, i.e. the expected hash of the object's + * content + */ + public AnyLongObjectId getId() { + return id; + } + + /** + * @return the actual hash of the object's content which doesn't match the + * object's id when this exception is thrown which signals that the + * object has been corrupted + */ + public AnyLongObjectId getContentHash() { + return contentHash; + } +} diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/Constants.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/Constants.java index 92a5c4250..3cadbf73a 100644 --- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/Constants.java +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/Constants.java @@ -99,4 +99,16 @@ public final class Constants { throw new LinkageError( LfsText.get().incorrectLONG_OBJECT_ID_LENGTH); } -} + + /** + * Content type used by LFS REST API as defined in + * {@link "https://github.com/github/git-lfs/blob/master/docs/api/http-v1-batch.md"} + */ + public static String CONTENT_TYPE_GIT_LFS_JSON = "application/vnd.git-lfs+json"; + + /** + * "arbitrary binary data" as defined in RFC 2046 + * {@link "https://www.ietf.org/rfc/rfc2046.txt"} + */ + public static String HDR_APPLICATION_OCTET_STREAM = "application/octet-stream"; +} \ No newline at end of file diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml index e8f74f4aa..bb5285749 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml @@ -33,4 +33,18 @@ version="0.0.0" unpack="false"/> + + + + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml index ef7fd79a9..9d35816a4 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml @@ -72,6 +72,11 @@ ${project.version} + + org.eclipse.jgit + org.eclipse.jgit.lfs.server + ${project.version} +
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml index 5f21a609d..9d842efa1 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml @@ -74,6 +74,11 @@ org.eclipse.jgit.lfs ${project.version} + + org.eclipse.jgit + org.eclipse.jgit.lfs.server + ${project.version} + org.eclipse.jgit org.eclipse.jgit.pgm diff --git a/org.eclipse.jgit.pgm/BUCK b/org.eclipse.jgit.pgm/BUCK index edcf2fc28..47711b5c6 100644 --- a/org.eclipse.jgit.pgm/BUCK +++ b/org.eclipse.jgit.pgm/BUCK @@ -9,8 +9,18 @@ java_library( '//org.eclipse.jgit:jgit', '//org.eclipse.jgit.archive:jgit-archive', '//org.eclipse.jgit.http.apache:http-apache', + '//org.eclipse.jgit.lfs.server:jgit-lfs-server', '//org.eclipse.jgit.ui:ui', '//lib:args4j', + '//lib:httpcomponents', + '//lib:httpcore', + '//lib/jetty:http', + '//lib/jetty:io', + '//lib/jetty:server', + '//lib/jetty:servlet', + '//lib/jetty:security', + '//lib/jetty:util', + '//lib:servlet-api' ], visibility = ['PUBLIC'], ) diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF index bf1fc5dd8..b654fc935 100644 --- a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF @@ -7,9 +7,25 @@ Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.7 -Import-Package: org.apache.commons.compress.archivers;version="[1.3,2.0)", +Import-Package: javax.servlet;version="[3.1.0,4.0.0)", + javax.servlet.http;version="[3.1.0,4.0.0)", + org.apache.commons.compress.archivers;version="[1.3,2.0)", org.apache.commons.compress.archivers.tar;version="[1.3,2.0)", org.apache.commons.compress.archivers.zip;version="[1.3,2.0)", + org.eclipse.jetty.continuation;version="[9.0.0,10.0.0)", + org.eclipse.jetty.http;version="[9.0.0,10.0.0)", + org.eclipse.jetty.io;version="[9.0.0,10.0.0)", + org.eclipse.jetty.security;version="[9.0.0,10.0.0)", + org.eclipse.jetty.security.authentication;version="[9.0.0,10.0.0)", + org.eclipse.jetty.server;version="[9.0.0,10.0.0)", + org.eclipse.jetty.server.handler;version="[9.0.0,10.0.0)", + org.eclipse.jetty.server.nio;version="[9.0.0,10.0.0)", + org.eclipse.jetty.servlet;version="[9.0.0,10.0.0)", + org.eclipse.jetty.util;version="[9.0.0,10.0.0)", + org.eclipse.jetty.util.component;version="[9.0.0,10.0.0)", + org.eclipse.jetty.util.log;version="[9.0.0,10.0.0)", + org.eclipse.jetty.util.security;version="[9.0.0,10.0.0)", + org.eclipse.jetty.util.thread;version="[9.0.0,10.0.0)", org.eclipse.jgit.api;version="[4.3.0,4.4.0)", org.eclipse.jgit.api.errors;version="[4.3.0,4.4.0)", org.eclipse.jgit.archive;version="[4.3.0,4.4.0)", @@ -23,8 +39,11 @@ Import-Package: org.apache.commons.compress.archivers;version="[1.3,2.0)", org.eclipse.jgit.internal.storage.file;version="[4.3.0,4.4.0)", org.eclipse.jgit.internal.storage.pack;version="[4.3.0,4.4.0)", org.eclipse.jgit.internal.storage.reftree;version="[4.3.0,4.4.0)", + org.eclipse.jgit.lfs.lib;version="[4.3.0,4.4.0)", + org.eclipse.jgit.lfs.server;version="[4.3.0,4.4.0)", + org.eclipse.jgit.lfs.server.fs;version="[4.3.0,4.4.0)", org.eclipse.jgit.lib;version="[4.3.0,4.4.0)", - org.eclipse.jgit.merge;version="4.3.0", + org.eclipse.jgit.merge;version="[4.3.0,4.4.0)", org.eclipse.jgit.nls;version="[4.3.0,4.4.0)", org.eclipse.jgit.notes;version="[4.3.0,4.4.0)", org.eclipse.jgit.revplot;version="[4.3.0,4.4.0)", diff --git a/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin b/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin index 6aa20041b..c159f7d60 100644 --- a/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin +++ b/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin @@ -38,6 +38,7 @@ org.eclipse.jgit.pgm.UploadPack org.eclipse.jgit.pgm.Version org.eclipse.jgit.pgm.debug.DiffAlgorithms +org.eclipse.jgit.pgm.debug.LfsStore org.eclipse.jgit.pgm.debug.MakeCacheTree org.eclipse.jgit.pgm.debug.ReadDirCache org.eclipse.jgit.pgm.debug.RebuildCommitGraph diff --git a/org.eclipse.jgit.pgm/pom.xml b/org.eclipse.jgit.pgm/pom.xml index 0531e4440..8d0bcf9be 100644 --- a/org.eclipse.jgit.pgm/pom.xml +++ b/org.eclipse.jgit.pgm/pom.xml @@ -122,6 +122,34 @@ log4j ${log4j-version} + + + org.eclipse.jetty + jetty-servlet + + + + junit + junit + + + + org.eclipse.jgit + org.eclipse.jgit.junit.http + ${project.version} + + + + org.eclipse.jgit + org.eclipse.jgit.lfs + ${project.version} + + + + org.eclipse.jgit + org.eclipse.jgit.lfs.server + ${project.version} + diff --git a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties index b4b1261b3..544e234e3 100644 --- a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties +++ b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties @@ -125,6 +125,7 @@ metaVar_remoteName=name metaVar_revision=REVISION metaVar_seconds=SECONDS metaVar_service=SERVICE +metaVar_lfsStorage=STORAGE metaVar_treeish=tree-ish metaVar_uriish=uri-ish metaVar_url=URL @@ -218,6 +219,10 @@ usage_DisplayTheVersionOfJgit=Display the version of jgit usage_Gc=Cleanup unnecessary files and optimize the local repository usage_Glog=View commit history as a graph usage_IndexPack=Build pack index file for an existing packed archive +usage_LFSDirectory=Directory to store large objects +usage_LFSPort=Server http port +usage_LFSRunStore=fs: store lfs objects in file system +usage_LFSStoreUrl=URL of the LFS store usage_LongFormat=Always output the long format usage_LsRemote=List references in a remote repository usage_lsRemoteHeads=Show only refs starting with refs/heads @@ -347,6 +352,7 @@ usage_resetReference=Reset to given reference name usage_resetHard=Resets the index and working tree usage_resetSoft=Resets without touching the index file nor the working tree usage_resetMixed=Resets the index but not the working tree +usage_runLfsStore=Run LFS Store in a given directory usage_setTheGitRepositoryToOperateOn=set the git repository to operate on usage_show=display one commit usage_showRefNamesMatchingCommits=Show ref names matching commits diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/LfsStore.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/LfsStore.java new file mode 100644 index 000000000..18398f664 --- /dev/null +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/LfsStore.java @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2015, Sasa Zivkov + * 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.debug; + +import java.net.InetAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.UnknownHostException; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jgit.lfs.server.LargeFileRepository; +import org.eclipse.jgit.lfs.server.LfsProtocolServlet; +import org.eclipse.jgit.lfs.server.fs.FileLfsServlet; +import org.eclipse.jgit.lfs.server.fs.FileLfsRepository; +import org.eclipse.jgit.pgm.Command; +import org.eclipse.jgit.pgm.TextBuiltin; +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.Option; + +@Command(common = true, usage = "usage_runLfsStore") +class LfsStore extends TextBuiltin { + + /** + * Tiny web application server for testing + */ + class AppServer { + + private final Server server; + + private final ServerConnector connector; + + private final ContextHandlerCollection contexts; + + private URI uri; + + AppServer(int port) { + server = new Server(); + + HttpConfiguration http_config = new HttpConfiguration(); + http_config.setOutputBufferSize(32768); + + connector = new ServerConnector(server, + new HttpConnectionFactory(http_config)); + connector.setPort(port); + try { + String host = InetAddress.getByName("localhost") //$NON-NLS-1$ + .getHostAddress(); + connector.setHost(host); + if (host.contains(":") && !host.startsWith("[")) //$NON-NLS-1$ //$NON-NLS-2$ + host = "[" + host + "]"; //$NON-NLS-1$//$NON-NLS-2$ + uri = new URI("http://" + host + ":" + port); //$NON-NLS-1$ //$NON-NLS-2$ + } catch (UnknownHostException e) { + throw new RuntimeException("Cannot find localhost", e); //$NON-NLS-1$ + } catch (URISyntaxException e) { + throw new RuntimeException("Unexpected URI error on " + uri, e); //$NON-NLS-1$ + } + + contexts = new ContextHandlerCollection(); + server.setHandler(contexts); + server.setConnectors(new Connector[] { connector }); + } + + /** + * Create a new servlet context within the server. + *

+ * This method should be invoked before the server is started, once for + * each context the caller wants to register. + * + * @param path + * path of the context; use "/" for the root context if + * binding to the root is desired. + * @return the context to add servlets into. + */ + ServletContextHandler addContext(String path) { + assertNotRunning(); + if ("".equals(path)) //$NON-NLS-1$ + path = "/"; //$NON-NLS-1$ + + ServletContextHandler ctx = new ServletContextHandler(); + ctx.setContextPath(path); + contexts.addHandler(ctx); + + return ctx; + } + + void start() throws Exception { + server.start(); + } + + void stop() throws Exception { + server.stop(); + } + + URI getURI() { + return uri; + } + + private void assertNotRunning() { + if (server.isRunning()) { + throw new IllegalStateException("server is running"); //$NON-NLS-1$ + } + } + } + + private static enum StoreType { + FS; + } + + private static final String OBJECTS = "objects/"; //$NON-NLS-1$ + + private static final String STORE_PATH = "/" + OBJECTS + "*"; //$NON-NLS-1$//$NON-NLS-2$ + + private static final String PROTOCOL_PATH = "/lfs/objects/batch"; //$NON-NLS-1$ + + @Option(name = "--port", aliases = {"-p" }, metaVar = "metaVar_port", + usage = "usage_LFSPort") + int port; + + @Option(name = "--store", metaVar = "metaVar_lfsStorage", usage = "usage_LFSRunStore") + StoreType storeType; + + @Option(name = "--store-url", aliases = {"-u" }, metaVar = "metaVar_url", + usage = "usage_LFSStoreUrl") + String storeUrl; + + @Argument(required = false, metaVar = "metaVar_directory", usage = "usage_LFSDirectory") + String directory; + + String protocolUrl; + + String accessKey; + + String secretKey; + + @Override + protected boolean requiresRepository() { + return false; + } + + protected void run() throws Exception { + AppServer server = new AppServer(port); + URI baseURI = server.getURI(); + ServletContextHandler app = server.addContext("/"); //$NON-NLS-1$ + + final LargeFileRepository repository; + switch (storeType) { + case FS: + Path dir = Paths.get(directory); + FileLfsRepository fsRepo = new FileLfsRepository( + getStoreUrl(baseURI), dir); + FileLfsServlet content = new FileLfsServlet(fsRepo, 30000); + app.addServlet(new ServletHolder(content), STORE_PATH); + repository = fsRepo; + break; + + default: + throw new IllegalArgumentException( + "Unknown store type: " + storeType); //$NON-NLS-1$ + } + + LfsProtocolServlet protocol = new LfsProtocolServlet() { + + private static final long serialVersionUID = 1L; + + @Override + protected LargeFileRepository getLargeFileRepository() { + return repository; + } + + }; + app.addServlet(new ServletHolder(protocol), PROTOCOL_PATH); + + server.start(); + + outw.println("LFS protocol URL: " + getProtocolUrl(baseURI)); //$NON-NLS-1$ + if (storeType == StoreType.FS) { + outw.println("LFS objects located in: " + directory); //$NON-NLS-1$ + outw.println("LFS store URL: " + getStoreUrl(baseURI)); //$NON-NLS-1$ + } + } + + private String getStoreUrl(URI baseURI) { + if (storeUrl == null) { + if (storeType == StoreType.FS) { + storeUrl = baseURI + "/" + OBJECTS; //$NON-NLS-1$ + } else { + die("Local store not running and no --store-url specified"); //$NON-NLS-1$ + } + } + return storeUrl; + } + + private String getProtocolUrl(URI baseURI) { + if (protocolUrl == null) { + protocolUrl = baseURI + PROTOCOL_PATH; + } + return protocolUrl; + } +} diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF index f263a5ca9..3e155a7d3 100644 --- a/org.eclipse.jgit/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit/META-INF/MANIFEST.MF @@ -66,8 +66,9 @@ Export-Package: org.eclipse.jgit.annotations;version="4.3.0", org.eclipse.jgit.junit, org.eclipse.jgit.junit.http, org.eclipse.jgit.http.server, - org.eclipse.jgit.pgm.test, - org.eclipse.jgit.pgm", + org.eclipse.jgit.lfs.server, + org.eclipse.jgit.pgm, + org.eclipse.jgit.pgm.test", org.eclipse.jgit.internal.storage.pack;version="4.3.0";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", org.eclipse.jgit.internal.storage.reftree;version="4.3.0";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", org.eclipse.jgit.lib;version="4.3.0"; diff --git a/pom.xml b/pom.xml index 054143e04..6bb30fe7a 100644 --- a/pom.xml +++ b/pom.xml @@ -775,6 +775,7 @@ org.eclipse.jgit.http.server org.eclipse.jgit.pgm org.eclipse.jgit.lfs + org.eclipse.jgit.lfs.server org.eclipse.jgit.junit org.eclipse.jgit.junit.http @@ -783,6 +784,7 @@ org.eclipse.jgit.http.test org.eclipse.jgit.pgm.test org.eclipse.jgit.lfs.test + org.eclipse.jgit.lfs.server.test