Bug 491268 - Apache Lucene based indexer for DLTK
Change-Id: I98a6d0f435b146d2dee3ff599797eb47f41562c0
Signed-off-by: Bartlomiej Laczkowski <bartlomiej.l@zend.com>
Also-by: Michal Niewrzal <michal.n@zend.com>
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/.classpath b/core/plugins/org.eclipse.dltk.core.index.lucene/.classpath
new file mode 100644
index 0000000..290a9f6
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/.classpath
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry exported="true" kind="lib" path="lib/lucene-analyzers-common-5.2.1.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/lucene-core-5.2.1.jar"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/.gitignore b/core/plugins/org.eclipse.dltk.core.index.lucene/.gitignore
new file mode 100644
index 0000000..ae3c172
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/.project b/core/plugins/org.eclipse.dltk.core.index.lucene/.project
new file mode 100644
index 0000000..d9896d2
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.dltk.core.index.lucene</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/.settings/org.eclipse.jdt.core.prefs b/core/plugins/org.eclipse.dltk.core.index.lucene/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..10d6339
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,359 @@
+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.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=warning
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.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=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+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=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+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=warning
+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=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+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=warning
+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=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+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_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.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_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/.settings/org.eclipse.jdt.ui.prefs b/core/plugins/org.eclipse.dltk.core.index.lucene/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..e143cd1
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,55 @@
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile
+formatter_settings_version=11
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=false
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=false
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/META-INF/MANIFEST.MF b/core/plugins/org.eclipse.dltk.core.index.lucene/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..0170f7a
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.eclipse.dltk.core.index.lucene;singleton:=true
+Bundle-Version: 5.5.0.qualifier
+Bundle-Activator: org.eclipse.dltk.core.index.lucene.LucenePlugin
+Bundle-Localization: plugin
+Bundle-Vendor: %Bundle-Vendor
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.eclipse.dltk.core
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-ActivationPolicy: lazy
+Bundle-ClassPath: .,
+ lib/lucene-analyzers-common-5.2.1.jar,
+ lib/lucene-core-5.2.1.jar
+Export-Package: org.eclipse.dltk.core.index.lucene
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/about.html b/core/plugins/org.eclipse.dltk.core.index.lucene/about.html
new file mode 100644
index 0000000..0728339
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>April 6, 2016</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/build.properties b/core/plugins/org.eclipse.dltk.core.index.lucene/build.properties
new file mode 100644
index 0000000..a2351aa
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/build.properties
@@ -0,0 +1,20 @@
+###############################################################################
+# Copyright (c) 2016 Zend Technologies and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Zend Technologies - initial API and implementation
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ plugin.properties,\
+ about.html,\
+ lib/lucene-analyzers-common-5.2.1.jar,\
+ lib/lucene-core-5.2.1.jar
+source.. = src/
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/lib/lucene-analyzers-common-5.2.1.jar b/core/plugins/org.eclipse.dltk.core.index.lucene/lib/lucene-analyzers-common-5.2.1.jar
new file mode 100644
index 0000000..aaa26a1
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/lib/lucene-analyzers-common-5.2.1.jar
Binary files differ
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/lib/lucene-core-5.2.1.jar b/core/plugins/org.eclipse.dltk.core.index.lucene/lib/lucene-core-5.2.1.jar
new file mode 100644
index 0000000..18b887f
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/lib/lucene-core-5.2.1.jar
Binary files differ
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/plugin.properties b/core/plugins/org.eclipse.dltk.core.index.lucene/plugin.properties
new file mode 100644
index 0000000..35d8e95
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/plugin.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2016 Zend Technologies and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Zend Technologies - initial API and implementation
+###############################################################################
+Bundle-Vendor = Eclipse DLTK
+Bundle-Name = DLTK Apache Lucene-based Indexer
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/plugin.xml b/core/plugins/org.eclipse.dltk.core.index.lucene/plugin.xml
new file mode 100644
index 0000000..4119151
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/plugin.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.dltk.core.indexer">
+ <indexer
+ class="org.eclipse.dltk.internal.core.index.lucene.LuceneIndexer"
+ id="org.eclipse.dltk.core.index.lucene.indexer">
+ </indexer>
+ </extension>
+</plugin>
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/pom.xml b/core/plugins/org.eclipse.dltk.core.index.lucene/pom.xml
new file mode 100644
index 0000000..29035fd
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/pom.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>core</artifactId>
+ <groupId>org.eclipse.dltk.core</groupId>
+ <version>5.5.0-SNAPSHOT</version>
+ <relativePath>../..</relativePath>
+ </parent>
+ <artifactId>org.eclipse.dltk.core.index.lucene</artifactId>
+ <packaging>eclipse-plugin</packaging>
+</project>
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/core/index/lucene/LucenePlugin.java b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/core/index/lucene/LucenePlugin.java
new file mode 100644
index 0000000..60507b2
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/core/index/lucene/LucenePlugin.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Zend Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dltk.core.index.lucene;
+
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.jobs.Job;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Lucene based DLTK indexer plug-in.
+ *
+ * @author Bartlomiej Laczkowski
+ */
+public class LucenePlugin extends Plugin {
+
+ /**
+ * Plug-in unique ID.
+ */
+ public static final String ID = "org.eclipse.dltk.core.index.lucene"; //$NON-NLS-1$
+
+ /**
+ * Lucene indexer plug-in job family indicator.
+ */
+ public static final Object LUCENE_JOB_FAMILY = new Object();
+
+ private static LucenePlugin plugin;
+
+ public static LucenePlugin getDefault() {
+ return plugin;
+ }
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ try {
+ Job.getJobManager().join(LUCENE_JOB_FAMILY, null);
+ } finally {
+ plugin = null;
+ super.stop(context);
+ }
+ }
+
+}
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/BitFlagsQuery.java b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/BitFlagsQuery.java
new file mode 100644
index 0000000..9af3308
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/BitFlagsQuery.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Zend Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dltk.internal.core.index.lucene;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.Set;
+
+import org.apache.lucene.index.DocValues;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.NumericDocValues;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.ConstantScoreScorer;
+import org.apache.lucene.search.DocIdSet;
+import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.DocValuesDocIdSet;
+import org.apache.lucene.search.Explanation;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.Weight;
+import org.apache.lucene.util.Bits;
+import org.eclipse.dltk.ast.Modifiers;
+
+/**
+ * Query for scoring declaration modifiers represented by corresponding DLTK's
+ * modifiers bit flags {@link Modifiers}.
+ *
+ * @author Michal Niewrzal, Bartlomiej Laczkowski
+ */
+public class BitFlagsQuery extends Query {
+
+ private final int fTrueFlags;
+ private final int fFalseFlags;
+
+ public BitFlagsQuery(final int trueFlags, final int falseFlags) {
+ fTrueFlags = trueFlags;
+ fFalseFlags = falseFlags;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + fFalseFlags;
+ result = prime * result + fTrueFlags;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ BitFlagsQuery other = (BitFlagsQuery) obj;
+ if (fFalseFlags != other.fFalseFlags)
+ return false;
+ if (fTrueFlags != other.fTrueFlags)
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString(String input) {
+ return MessageFormat.format(
+ "BitFlagsQuery(Field: {0}, True Flags: {1}, False Flags: {2})", //$NON-NLS-1$
+ IndexFields.NDV_FLAGS, fTrueFlags, fFalseFlags);
+ }
+
+ @Override
+ public Weight createWeight(IndexSearcher searcher, boolean needsScores)
+ throws IOException {
+ return new Weight(this) {
+ @Override
+ public void extractTerms(Set<Term> terms) {
+ // Ignore
+ }
+
+ @Override
+ public void normalize(float norm, float topLevelBoost) {
+ // Ignore
+ }
+
+ @Override
+ public float getValueForNormalization() throws IOException {
+ return 0;
+ }
+
+ @Override
+ public Explanation explain(LeafReaderContext context, int doc)
+ throws IOException {
+ final Scorer scorer = scorer(context,
+ context.reader().getLiveDocs());
+ final boolean match = (scorer != null
+ && scorer.advance(doc) == doc);
+ if (match) {
+ assert scorer.score() == 0;
+ return Explanation.match(0, "Match on id" + doc); //$NON-NLS-1$
+ } else {
+ return Explanation.match(0, "No match on id" + doc); //$NON-NLS-1$
+ }
+ }
+
+ @Override
+ public Scorer scorer(LeafReaderContext context, Bits acceptDocs)
+ throws IOException {
+ final DocIdSet set = getDocIdSet(context, acceptDocs);
+ if (set == null) {
+ return null;
+ }
+ final DocIdSetIterator iterator = set.iterator();
+ if (iterator == null) {
+ return null;
+ }
+ return new ConstantScoreScorer(this, 0, iterator);
+ }
+ };
+
+ }
+
+ /**
+ * Finds and returns matching doc ID set.
+ *
+ * @param context
+ * @param acceptDocs
+ * @return matching doc ID set
+ * @throws IOException
+ */
+ protected DocIdSet getDocIdSet(final LeafReaderContext context,
+ Bits acceptDocs) throws IOException {
+ final NumericDocValues numDocValues = DocValues
+ .getNumeric(context.reader(), IndexFields.NDV_FLAGS);
+ return new DocValuesDocIdSet(context.reader().maxDoc(), acceptDocs) {
+ @Override
+ protected boolean matchDoc(int doc) {
+ long flags = numDocValues.get(doc);
+ if (fTrueFlags != 0) {
+ if ((flags & fTrueFlags) == 0) {
+ return false;
+ }
+ }
+ if (fFalseFlags != 0) {
+ if ((flags & fFalseFlags) != 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+ };
+ }
+
+}
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/DocumentFactory.java b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/DocumentFactory.java
new file mode 100644
index 0000000..f63691d
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/DocumentFactory.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Zend Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dltk.internal.core.index.lucene;
+
+import static org.eclipse.dltk.internal.core.index.lucene.IndexFields.*;
+
+import org.apache.lucene.document.BinaryDocValuesField;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.NumericDocValuesField;
+import org.apache.lucene.document.StringField;
+import org.apache.lucene.util.BytesRef;
+import org.eclipse.dltk.core.index2.IIndexingRequestor.DeclarationInfo;
+import org.eclipse.dltk.core.index2.IIndexingRequestor.ReferenceInfo;
+
+/**
+ * <p>
+ * Factory for creating different types of Lucene documents.
+ * </p>
+ * <p>
+ * To boost the performance of documents search and related data retrieval,
+ * numeric and binary document values are being used in pair with non-stored
+ * fields. It basically means that non-stored fields are used for document
+ * search purposes while numeric and binary document values are used to retrieve
+ * the related data for particular search matches.
+ * </p>
+ *
+ * @author Bartlomiej Laczkowski
+ */
+public final class DocumentFactory {
+
+ /**
+ * Creates and returns a document for provided reference info.
+ *
+ * @param source
+ * @param info
+ * @return a document for provided reference info
+ */
+ public static Document createForReference(String source,
+ ReferenceInfo info) {
+ Document doc = new Document();
+ // Fields for search (no store, doc values will be used instead)
+ addStringEntry(doc, F_PATH, source, false);
+ addStringEntry(doc, F_QUALIFIER, info.qualifier, false);
+ addStringLCEntry(doc, F_ELEMENT_NAME_LC, info.elementName, false);
+ // Add numeric doc values
+ addLongEntry(doc, NDV_OFFSET, info.offset);
+ addLongEntry(doc, NDV_LENGTH, info.length);
+ // Add text as binary doc values
+ addBinaryEntry(doc, BDV_PATH, source);
+ addBinaryEntry(doc, BDV_ELEMENT_NAME, info.elementName);
+ addBinaryEntry(doc, BDV_QUALIFIER, info.qualifier);
+ addBinaryEntry(doc, BDV_METADATA, info.metadata);
+ return doc;
+ }
+
+ /**
+ * Creates and returns a document for provided declaration info.
+ *
+ * @param source
+ * @param info
+ * @return a document for provided declaration info
+ */
+ public static Document createForDeclaration(String source,
+ DeclarationInfo info) {
+ Document doc = new Document();
+ // Fields for search (no store, doc values will be used instead)
+ addStringEntry(doc, F_PATH, source, false);
+ addStringEntry(doc, F_PARENT, info.parent, false);
+ addStringEntry(doc, F_QUALIFIER, info.qualifier, false);
+ addStringLCEntry(doc, F_ELEMENT_NAME_LC, info.elementName, false);
+ addCCNameEntry(doc, info.elementName);
+ // Add numeric doc values
+ addLongEntry(doc, NDV_OFFSET, info.offset);
+ addLongEntry(doc, NDV_LENGTH, info.length);
+ addLongEntry(doc, NDV_NAME_OFFSET, info.nameOffset);
+ addLongEntry(doc, NDV_NAME_LENGTH, info.nameLength);
+ addLongEntry(doc, NDV_FLAGS, info.flags);
+ // Add text as binary doc values
+ addBinaryEntry(doc, BDV_PATH, source);
+ addBinaryEntry(doc, BDV_ELEMENT_NAME, info.elementName);
+ addBinaryEntry(doc, BDV_PARENT, info.parent);
+ addBinaryEntry(doc, BDV_QUALIFIER, info.qualifier);
+ addBinaryEntry(doc, BDV_METADATA, info.metadata);
+ addBinaryEntry(doc, BDV_DOC, info.doc);
+ return doc;
+ }
+
+ /**
+ * Creates and returns a document for source file time stamp.
+ *
+ * @param source
+ * @param timestamp
+ * @return a document for source file time stamp
+ */
+ public static Document createForTimestamp(String source, long timestamp) {
+ Document doc = new Document();
+ addStringEntry(doc, F_PATH, source, true);
+ addLongEntry(doc, NDV_TIMESTAMP, timestamp);
+ return doc;
+ }
+
+ private static void addLongEntry(Document doc, String category,
+ long value) {
+ doc.add(new NumericDocValuesField(category, value));
+ }
+
+ private static void addStringEntry(Document doc, String category,
+ String value, boolean store) {
+ if (value == null) {
+ return;
+ }
+ doc.add(new StringField(category, value,
+ store ? Field.Store.YES : Field.Store.NO));
+ }
+
+ private static void addStringLCEntry(Document doc, String category,
+ String value, boolean store) {
+ addStringEntry(doc, category, value.toLowerCase(), store);
+ }
+
+ private static void addCCNameEntry(Document doc, String name) {
+ String camelCaseName = null;
+ StringBuilder camelCaseNameBuf = new StringBuilder();
+ for (int i = 0; i < name.length(); ++i) {
+ char ch = name.charAt(i);
+ if (Character.isUpperCase(ch)) {
+ camelCaseNameBuf.append(ch);
+ } else if (i == 0) {
+ // Not applicable for camel case search
+ break;
+ }
+ }
+ camelCaseName = camelCaseNameBuf.length() > 0
+ ? camelCaseNameBuf.toString() : null;
+ addStringEntry(doc, F_CC_NAME, camelCaseName, false);
+ }
+
+ private static void addBinaryEntry(Document doc, String category,
+ String value) {
+ if (value == null) {
+ return;
+ }
+ doc.add(new BinaryDocValuesField(category, new BytesRef(value)));
+ }
+
+}
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/IndexContainer.java b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/IndexContainer.java
new file mode 100644
index 0000000..f5da1fd
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/IndexContainer.java
@@ -0,0 +1,239 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Zend Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dltk.internal.core.index.lucene;
+
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.lucene.analysis.core.SimpleAnalyzer;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.IndexWriterConfig.OpenMode;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.SearcherFactory;
+import org.apache.lucene.search.SearcherManager;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.FSDirectory;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.dltk.core.index.lucene.LucenePlugin;
+
+/**
+ * Class responsible for handling container index data.
+ *
+ * @author Bartlomiej Laczkowski
+ */
+class IndexContainer {
+
+ private final class IndexCleaner extends Job {
+
+ public IndexCleaner() {
+ super(""); //$NON-NLS-1$
+ setUser(false);
+ setSystem(true);
+ }
+
+ @Override
+ public boolean belongsTo(Object family) {
+ return family == LucenePlugin.LUCENE_JOB_FAMILY;
+ }
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ close();
+ Path containerPath = Paths.get(fIndexRoot, getId());
+ try {
+ Files.walkFileTree(containerPath,
+ new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file,
+ BasicFileAttributes attrs)
+ throws IOException {
+ Files.delete(file);
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir,
+ IOException exc) throws IOException {
+ Files.delete(dir);
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ } catch (IOException e) {
+ Logger.logException(e);
+ }
+ return Status.OK_STATUS;
+ }
+
+ }
+
+ private static final String TIMESTAMPS_DIR = "timestamps"; //$NON-NLS-1$
+
+ private final String fIndexRoot;
+ private final String fContainerId;
+ private IndexWriter fTimestampsWriter;
+ private SearcherManager fTimestampsSearcher;
+ private Map<IndexType, Map<Integer, IndexWriter>> fIndexWriters;
+ private Map<IndexType, Map<Integer, SearcherManager>> fIndexSearchers;
+
+ public IndexContainer(String indexRoot, String containerId) {
+ fIndexRoot = indexRoot;
+ fContainerId = containerId;
+ initialize();
+ }
+
+ private void initialize() {
+ fIndexWriters = new HashMap<>();
+ fIndexWriters.put(IndexType.DECLARATIONS,
+ new HashMap<Integer, IndexWriter>());
+ fIndexWriters.put(IndexType.REFERENCES,
+ new HashMap<Integer, IndexWriter>());
+ fIndexSearchers = new HashMap<>();
+ fIndexSearchers.put(IndexType.DECLARATIONS,
+ new HashMap<Integer, SearcherManager>());
+ fIndexSearchers.put(IndexType.REFERENCES,
+ new HashMap<Integer, SearcherManager>());
+ }
+
+ public final String getId() {
+ return fContainerId;
+ }
+
+ public synchronized IndexWriter getTimestampsWriter() {
+ if (fTimestampsWriter == null) {
+ try {
+ Directory indexDir = FSDirectory.open(
+ Paths.get(fIndexRoot, fContainerId, TIMESTAMPS_DIR));
+ IndexWriterConfig config = new IndexWriterConfig(
+ new SimpleAnalyzer());
+ config.setOpenMode(OpenMode.CREATE_OR_APPEND);
+ fTimestampsWriter = new IndexWriter(indexDir, config);
+ } catch (IOException e) {
+ Logger.logException(e);
+ }
+ }
+ return fTimestampsWriter;
+ }
+
+ public synchronized SearcherManager getTimestampsSearcher() {
+ try {
+ if (fTimestampsSearcher == null) {
+ fTimestampsSearcher = new SearcherManager(getTimestampsWriter(),
+ true, new SearcherFactory());
+ }
+ // Try to achieve the up-to-date index state
+ fTimestampsSearcher.maybeRefresh();
+ } catch (IOException e) {
+ Logger.logException(e);
+ }
+ return fTimestampsSearcher;
+ }
+
+ public synchronized IndexWriter getIndexWriter(IndexType dataType,
+ int elementType) {
+ IndexWriter writer = fIndexWriters.get(dataType).get(elementType);
+ if (writer == null) {
+ try {
+ Directory indexDir = FSDirectory.open(Paths.get(fIndexRoot,
+ fContainerId, dataType.getDirectory(),
+ String.valueOf(elementType)));
+ IndexWriterConfig config = new IndexWriterConfig(
+ new SimpleAnalyzer());
+ config.setOpenMode(OpenMode.CREATE_OR_APPEND);
+ writer = new IndexWriter(indexDir, config);
+ fIndexWriters.get(dataType).put(elementType, writer);
+ } catch (IOException e) {
+ Logger.logException(e);
+ }
+ }
+ return writer;
+ }
+
+ public synchronized SearcherManager getIndexSearcher(IndexType dataType,
+ int elementType) {
+ SearcherManager searcher = fIndexSearchers.get(dataType)
+ .get(elementType);
+ try {
+ if (searcher == null) {
+ searcher = new SearcherManager(
+ getIndexWriter(dataType, elementType), true,
+ new SearcherFactory());
+ fIndexSearchers.get(dataType).put(elementType, searcher);
+ }
+ // Try to achieve the up-to-date index state
+ searcher.maybeRefresh();
+ } catch (IOException e) {
+ Logger.logException(e);
+ }
+ return searcher;
+ }
+
+ public synchronized void delete(String sourceModule) {
+ Term term = new Term(IndexFields.F_PATH, sourceModule);
+ try {
+ // Cleanup related time stamp
+ getTimestampsWriter().deleteDocuments(term);
+ // Cleanup all related documents in data writers
+ for (Map<Integer, IndexWriter> dataWriters : fIndexWriters
+ .values()) {
+ for (IndexWriter writer : dataWriters.values()) {
+ writer.deleteDocuments(term);
+ }
+ }
+ } catch (IOException e) {
+ Logger.logException(e);
+ }
+ }
+
+ public synchronized void delete() {
+ // Delete container entry entirely
+ (new IndexCleaner()).schedule();
+ }
+
+ public synchronized void close() {
+ try {
+ // Close time stamps searcher & writer
+ if (fTimestampsSearcher != null)
+ fTimestampsSearcher.close();
+ if (fTimestampsWriter != null)
+ fTimestampsWriter.close();
+ // Close all data searchers
+ for (Map<Integer, SearcherManager> dataSearchers : fIndexSearchers
+ .values()) {
+ for (SearcherManager searcher : dataSearchers.values()) {
+ if (searcher != null)
+ searcher.close();
+ }
+ }
+ // Close all data writers
+ for (Map<Integer, IndexWriter> dataWriters : fIndexWriters
+ .values()) {
+ for (IndexWriter writer : dataWriters.values()) {
+ if (writer != null)
+ writer.close();
+ }
+ }
+ } catch (IOException e) {
+ Logger.logException(e);
+ }
+ }
+
+}
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/IndexFields.java b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/IndexFields.java
new file mode 100644
index 0000000..68b7343
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/IndexFields.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Zend Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dltk.internal.core.index.lucene;
+
+/**
+ * Constants for Lucene document fields.
+ *
+ * @author Michal Niewrzal, Bartlomiej Laczkowski
+ */
+public final class IndexFields {
+
+ private IndexFields() {
+ // Constants only
+ }
+
+ // Common set of fields
+ public static final String F_PATH = "path"; //$NON-NLS-1$
+ public static final String F_ELEMENT_NAME_LC = "elementNameLC"; //$NON-NLS-1$
+ public static final String F_CC_NAME = "ccName"; //$NON-NLS-1$
+ public static final String F_QUALIFIER = "qualifier"; //$NON-NLS-1$
+ public static final String F_PARENT = "parent"; //$NON-NLS-1$
+ // Numeric doc values
+ public static final String NDV_TIMESTAMP = "timestampNDV"; //$NON-NLS-1$
+ public static final String NDV_OFFSET = "offsetNDV"; //$NON-NLS-1$
+ public static final String NDV_LENGTH = "lengthNDV"; //$NON-NLS-1$
+ public static final String NDV_FLAGS = "flagsNDV"; //$NON-NLS-1$
+ public static final String NDV_NAME_OFFSET = "nameOffsetNDV"; //$NON-NLS-1$
+ public static final String NDV_NAME_LENGTH = "nameLengthNDV"; //$NON-NLS-1$
+ // Binary doc values
+ public static final String BDV_PATH = "pathBDV"; //$NON-NLS-1$
+ public static final String BDV_ELEMENT_NAME = "elementNameBDV"; //$NON-NLS-1$
+ public static final String BDV_QUALIFIER = "qualifierBDV"; //$NON-NLS-1$
+ public static final String BDV_PARENT = "parentBDV"; //$NON-NLS-1$
+ public static final String BDV_METADATA = "metadataBDV"; //$NON-NLS-1$
+ public static final String BDV_DOC = "docBDV"; //$NON-NLS-1$
+
+}
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/IndexProperties.java b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/IndexProperties.java
new file mode 100644
index 0000000..ee4a283
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/IndexProperties.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Zend Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dltk.internal.core.index.lucene;
+
+import org.apache.lucene.util.Version;
+import org.eclipse.dltk.core.index.lucene.LucenePlugin;
+
+/**
+ * Lucene support properties, i.e. model & Lucene engine version.
+ *
+ * @author Bartlomiej Laczkowski
+ */
+public final class IndexProperties {
+
+ private static final String PREFIX = LucenePlugin.ID + ".property."; //$NON-NLS-1$
+
+ public static final String KEY_MODEL_VERSION = PREFIX + "model.version"; //$NON-NLS-1$
+ public static final String KEY_LUCENE_VERSION = PREFIX + "lucene.version"; //$NON-NLS-1$
+
+ public static final String MODEL_VERSION = "1.0"; //$NON-NLS-1$
+ public static final String LUCENE_VERSION = Version.LATEST.toString();
+
+}
\ No newline at end of file
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/IndexType.java b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/IndexType.java
new file mode 100644
index 0000000..13c400a
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/IndexType.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Zend Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dltk.internal.core.index.lucene;
+
+/**
+ * Index type (declarations or references).
+ */
+public enum IndexType {
+
+ /**
+ * Index type for storing declarations data.
+ */
+ DECLARATIONS("declarations"), //$NON-NLS-1$
+ /**
+ * Index type for storing references data.
+ */
+ REFERENCES("references"); //$NON-NLS-1$
+
+ private final String fDirectory;
+
+ private IndexType(String directory) {
+ this.fDirectory = directory;
+ }
+
+ /**
+ * Returns related directory name.
+ *
+ * @return related directory name
+ */
+ public String getDirectory() {
+ return fDirectory;
+ }
+
+}
\ No newline at end of file
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/Logger.java b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/Logger.java
new file mode 100644
index 0000000..393833e
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/Logger.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Zend Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dltk.internal.core.index.lucene;
+
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.dltk.core.index.lucene.LucenePlugin;
+import org.osgi.framework.Bundle;
+
+/**
+ * Small convenience class to log messages to plugin's log file and also in the
+ * console if desired.
+ *
+ * @author Bartlomiej Laczkowski
+ */
+public class Logger {
+
+ private static final String PLUGIN_ID = LucenePlugin.ID;
+ private static final String TRACEFILTER_LOCATION = "/debug/tracefilter"; //$NON-NLS-1$
+
+ public static final int OK = IStatus.OK; // 0
+ public static final int INFO = IStatus.INFO; // 1
+ public static final int WARNING = IStatus.WARNING; // 2
+ public static final int ERROR = IStatus.ERROR; // 4
+ public static final int OK_DEBUG = 200 + OK;
+ public static final int INFO_DEBUG = 200 + INFO;
+ public static final int WARNING_DEBUG = 200 + WARNING;
+ public static final int ERROR_DEBUG = 200 + ERROR;
+
+ /**
+ * Adds message to log.
+ *
+ * @param level
+ * severity level of the message (OK, INFO, WARNING, ERROR,
+ * OK_DEBUG, INFO_DEBUG, WARNING_DEBUG, ERROR_DEBUG)
+ * @param message
+ * text to add to the log
+ * @param exception
+ * exception thrown
+ */
+ protected static void _log(int level, String message, Throwable exception) {
+ if (level == OK_DEBUG || level == INFO_DEBUG || level == WARNING_DEBUG
+ || level == ERROR_DEBUG) {
+ if (!isDebugging())
+ return;
+ }
+ int severity = IStatus.OK;
+ switch (level) {
+ case INFO_DEBUG:
+ case INFO:
+ severity = IStatus.INFO;
+ break;
+ case WARNING_DEBUG:
+ case WARNING:
+ severity = IStatus.WARNING;
+ break;
+ case ERROR_DEBUG:
+ case ERROR:
+ severity = IStatus.ERROR;
+ }
+ message = (message != null) ? message : "null"; //$NON-NLS-1$
+ Status statusObj = new Status(severity, PLUGIN_ID, severity, message,
+ exception);
+ Bundle bundle = Platform.getBundle(PLUGIN_ID);
+ if (bundle != null)
+ Platform.getLog(bundle).log(statusObj);
+ }
+
+ /**
+ * Prints message to log if category matches /debug/tracefilter option.
+ *
+ * @param message
+ * text to print
+ * @param category
+ * category of the message, to be compared with
+ * /debug/tracefilter
+ */
+ protected static void _trace(String category, String message,
+ Throwable exception) {
+ if (isTracing(category)) {
+ message = (message != null) ? message : "null"; //$NON-NLS-1$
+ Status statusObj = new Status(IStatus.OK, PLUGIN_ID, IStatus.OK,
+ message, exception);
+ Bundle bundle = Platform.getBundle(PLUGIN_ID);
+ if (bundle != null)
+ Platform.getLog(bundle).log(statusObj);
+ }
+ }
+
+ /**
+ * Checks if the platform is debugging.
+ *
+ * @return true if the platform is debugging
+ */
+ public static boolean isDebugging() {
+ return Platform.inDebugMode();
+ }
+
+ /**
+ * Determines if currently tracing a category
+ *
+ * @param category
+ * @return true if tracing category, false otherwise
+ */
+ public static boolean isTracing(String category) {
+ if (!isDebugging())
+ return false;
+
+ String traceFilter = Platform
+ .getDebugOption(PLUGIN_ID + TRACEFILTER_LOCATION);
+ if (traceFilter != null) {
+ StringTokenizer tokenizer = new StringTokenizer(traceFilter, ","); //$NON-NLS-1$
+ while (tokenizer.hasMoreTokens()) {
+ String cat = tokenizer.nextToken().trim();
+ if (category.equals(cat)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Log message with given severity level.
+ *
+ * @param level
+ * @param message
+ */
+ public static void log(int level, String message) {
+ _log(level, message, null);
+ }
+
+ /**
+ * Log message with given severity level and exception.
+ *
+ * @param level
+ * @param message
+ * @param exception
+ */
+ public static void log(int level, String message, Throwable exception) {
+ _log(level, message, exception);
+ }
+
+ /**
+ * Log error message with given exception.
+ *
+ * @param message
+ * @param exception
+ */
+ public static void logException(String message, Throwable exception) {
+ _log(ERROR, message, exception);
+ }
+
+ /**
+ * Log error with given exception.
+ *
+ * @param exception
+ */
+ public static void logException(Throwable exception) {
+ _log(ERROR, exception.getMessage(), exception);
+ }
+
+ /**
+ * Trace exception.
+ *
+ * @param category
+ * @param message
+ * @param exception
+ */
+ public static void traceException(String category, String message,
+ Throwable exception) {
+ _trace(category, message, exception);
+ }
+
+ /**
+ * Trace exception.
+ *
+ * @param category
+ * @param exception
+ */
+ public static void traceException(String category, Throwable exception) {
+ _trace(category, exception.getMessage(), exception);
+ }
+
+ /**
+ * Trace message.
+ *
+ * @param category
+ * @param message
+ */
+ public static void trace(String category, String message) {
+ _trace(category, message, null);
+ }
+
+}
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/LuceneIndexer.java b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/LuceneIndexer.java
new file mode 100644
index 0000000..919d028
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/LuceneIndexer.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Zend Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dltk.internal.core.index.lucene;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.LeafReader;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.NumericDocValues;
+import org.apache.lucene.search.Collector;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.LeafCollector;
+import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.Scorer;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.dltk.core.DLTKLanguageManager;
+import org.eclipse.dltk.core.IDLTKLanguageToolkit;
+import org.eclipse.dltk.core.IDLTKLanguageToolkitExtension;
+import org.eclipse.dltk.core.IModelElement;
+import org.eclipse.dltk.core.ISourceModule;
+import org.eclipse.dltk.core.environment.EnvironmentPathUtils;
+import org.eclipse.dltk.core.environment.IFileHandle;
+import org.eclipse.dltk.core.index2.AbstractIndexer;
+import org.eclipse.dltk.core.index2.search.ISearchEngine;
+import org.eclipse.dltk.internal.core.ExternalSourceModule;
+import org.eclipse.dltk.internal.core.SourceModule;
+import org.eclipse.dltk.internal.core.util.Util;
+
+/**
+ * Lucene based implementation for DLTK indexer.
+ *
+ * @author Michal Niewrzal, Bartlomiej Laczkowski
+ */
+@SuppressWarnings("restriction")
+public class LuceneIndexer extends AbstractIndexer {
+
+ private static final class TimestampsCollector implements Collector {
+
+ private static final Set<String> fFields = Collections
+ .singleton(IndexFields.F_PATH);
+
+ private final Map<String, Long> fResult;
+
+ public TimestampsCollector(Map<String, Long> result) {
+ this.fResult = result;
+ }
+
+ @Override
+ public boolean needsScores() {
+ return false;
+ }
+
+ @Override
+ public LeafCollector getLeafCollector(LeafReaderContext context)
+ throws IOException {
+ final LeafReader reader = context.reader();
+ final NumericDocValues timestampField = context.reader()
+ .getNumericDocValues(IndexFields.NDV_TIMESTAMP);
+ return new LeafCollector() {
+ @Override
+ public void setScorer(Scorer scorer) throws IOException {
+ // ignore
+ }
+
+ @Override
+ public void collect(int docId) throws IOException {
+ Document document = reader.document(docId, fFields);
+ fResult.put(document.get(IndexFields.F_PATH),
+ timestampField.get(docId));
+ }
+ };
+ }
+
+ }
+
+ private String fFile;
+ private String fContainer;
+
+ @Override
+ public ISearchEngine createSearchEngine() {
+ return new LuceneSearchEngine();
+ }
+
+ @Override
+ public Map<String, Long> getDocuments(IPath containerPath) {
+ IndexSearcher indexSearcher = null;
+ String container = containerPath.toString();
+ try {
+ final Map<String, Long> result = new HashMap<>();
+ indexSearcher = LuceneManager.INSTANCE
+ .findTimestampsSearcher(container).acquire();
+ indexSearcher.search(new MatchAllDocsQuery(),
+ new TimestampsCollector(result));
+ return result;
+ } catch (IOException e) {
+ Logger.logException(e);
+ } finally {
+ if (indexSearcher != null) {
+ try {
+ LuceneManager.INSTANCE.findTimestampsSearcher(container)
+ .release(indexSearcher);
+ } catch (IOException e) {
+ Logger.logException(e);
+ }
+ }
+ }
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public void addDeclaration(DeclarationInfo info) {
+ try {
+ IndexWriter writer = LuceneManager.INSTANCE.findIndexWriter(
+ fContainer, IndexType.DECLARATIONS, info.elementType);
+ writer.addDocument(
+ DocumentFactory.createForDeclaration(fFile, info));
+ } catch (IOException e) {
+ Logger.logException(e);
+ }
+ }
+
+ @Override
+ public void addReference(ReferenceInfo info) {
+ try {
+ IndexWriter writer = LuceneManager.INSTANCE.findIndexWriter(
+ fContainer, IndexType.REFERENCES, info.elementType);
+ writer.addDocument(DocumentFactory.createForReference(fFile, info));
+ } catch (IOException e) {
+ Logger.logException(e);
+ }
+ }
+
+ @Override
+ public void indexDocument(ISourceModule sourceModule) {
+ final IFileHandle fileHandle = EnvironmentPathUtils
+ .getFile(sourceModule);
+ try {
+ IDLTKLanguageToolkit toolkit = DLTKLanguageManager
+ .getLanguageToolkit(sourceModule);
+ if (toolkit == null) {
+ return;
+ }
+ resetDocument(sourceModule, toolkit);
+ long lastModified = fileHandle == null ? 0
+ : fileHandle.lastModified();
+ // Cleanup and write new info...
+ LuceneManager.INSTANCE.delete(fContainer, fFile);
+ IndexWriter indexWriter = LuceneManager.INSTANCE
+ .findTimestampsWriter(fContainer);
+ indexWriter.addDocument(
+ DocumentFactory.createForTimestamp(fFile, lastModified));
+ super.indexDocument(sourceModule);
+ } catch (Exception e) {
+ Logger.logException(e);
+ }
+ }
+
+ @Override
+ public void removeContainer(IPath containerPath) {
+ LuceneManager.INSTANCE.delete(containerPath.toString());
+ }
+
+ @Override
+ public void removeDocument(IPath containerPath, String sourceModulePath) {
+ LuceneManager.INSTANCE.delete(containerPath.toString(),
+ sourceModulePath);
+ }
+
+ private void resetDocument(ISourceModule sourceModule,
+ IDLTKLanguageToolkit toolkit) {
+ IPath containerPath;
+ if (sourceModule instanceof SourceModule) {
+ containerPath = sourceModule.getScriptProject().getPath();
+ } else {
+ containerPath = sourceModule
+ .getAncestor(IModelElement.PROJECT_FRAGMENT).getPath();
+ }
+ String relativePath;
+ if (toolkit instanceof IDLTKLanguageToolkitExtension
+ && ((IDLTKLanguageToolkitExtension) toolkit)
+ .isArchiveFileName(sourceModule.getPath().toString())) {
+ relativePath = ((ExternalSourceModule) sourceModule).getFullPath()
+ .toString();
+ } else {
+ relativePath = Util.relativePath(sourceModule.getPath(),
+ containerPath.segmentCount());
+ }
+ this.fContainer = containerPath.toString();
+ this.fFile = relativePath;
+ }
+
+}
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/LuceneManager.java b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/LuceneManager.java
new file mode 100644
index 0000000..92fcf38
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/LuceneManager.java
@@ -0,0 +1,401 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Zend Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dltk.internal.core.index.lucene;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.search.SearcherManager;
+import org.eclipse.core.resources.ISaveContext;
+import org.eclipse.core.resources.ISaveParticipant;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.dltk.core.DLTKLanguageManager;
+import org.eclipse.dltk.core.IDLTKLanguageToolkit;
+import org.eclipse.dltk.core.index.lucene.LucenePlugin;
+import org.eclipse.dltk.core.search.indexing.IndexManager;
+import org.eclipse.dltk.internal.core.ModelManager;
+import org.eclipse.dltk.internal.core.search.DLTKWorkspaceScope;
+
+/**
+ * <p>
+ * Apache Lucene indexes manager responsible for managing indexes model.
+ * </p>
+ * <p>
+ * Indexes are stored in hierarchical directory structure as follows:
+ * <code><pre>
+ * index_root
+ * |_container_id
+ * |_declarations
+ * |_model_element_type_id (index data)
+ * ...
+ * |_references
+ * |_model_element_type_id (index data)
+ * ...
+ * |_timestamps (index data)
+ * </pre></code>
+ * </p>
+ *
+ * @author Bartlomiej Laczkowski
+ */
+@SuppressWarnings("restriction")
+public enum LuceneManager {
+
+ /**
+ * Manager Instance.
+ */
+ INSTANCE;
+
+ private final class SaveParticipant extends Job
+ implements ISaveParticipant {
+
+ public SaveParticipant() {
+ super(""); //$NON-NLS-1$
+ setSystem(true);
+ setUser(false);
+ }
+
+ @Override
+ public void doneSaving(ISaveContext context) {
+ // ignore
+ }
+
+ @Override
+ public void prepareToSave(ISaveContext context) throws CoreException {
+ // ignore
+ }
+
+ @Override
+ public void rollback(ISaveContext context) {
+ // ignore
+ }
+
+ @Override
+ public void saving(ISaveContext context) throws CoreException {
+ // Close all indexes on workspace save
+ if (context.getKind() == ISaveContext.FULL_SAVE)
+ schedule();
+ }
+
+ @Override
+ public boolean belongsTo(Object family) {
+ return family == LucenePlugin.LUCENE_JOB_FAMILY;
+ }
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ IndexManager indexManager = ModelManager.getModelManager()
+ .getIndexManager();
+ // Wait for indexer before shutting down
+ while (indexManager.awaitingJobsCount() > 0) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ Logger.logException(e);
+ }
+ }
+ shutdown();
+ return Status.OK_STATUS;
+ }
+
+ }
+
+ private static final String INDEX_DIR = "index"; //$NON-NLS-1$
+ private static final String PROPERTIES_FILE = ".properties"; //$NON-NLS-1$
+ private static final String MAPPINGS_FILE = ".mappings"; //$NON-NLS-1$
+
+ private final String fIndexRoot;
+ private final Properties fIndexProperties;
+ private final Properties fContainerMappings;
+ private final Map<String, IndexContainer> fIndexContainers;
+
+ private LuceneManager() {
+ fIndexProperties = new Properties();
+ fContainerMappings = new Properties();
+ fIndexContainers = new HashMap<>();
+ fIndexRoot = Platform
+ .getStateLocation(LucenePlugin.getDefault().getBundle())
+ .append(INDEX_DIR).toOSString();
+ File indexRootDirectory = new File(fIndexRoot);
+ if (!indexRootDirectory.exists()) {
+ indexRootDirectory.mkdirs();
+ }
+ startup();
+ }
+
+ /**
+ * Finds and returns index writer for given container, data type and model
+ * element.
+ *
+ * @param container
+ * @param dataType
+ * @param elementType
+ * @return index writer
+ */
+ public final IndexWriter findIndexWriter(String container,
+ IndexType dataType, int elementType) {
+ return getIndexContainer(container).getIndexWriter(dataType,
+ elementType);
+ }
+
+ /**
+ * Finds and returns index searcher for given container, data type and model
+ * element.
+ *
+ * @param container
+ * @param dataType
+ * @param elementType
+ * @return index searcher
+ */
+ public final SearcherManager findIndexSearcher(String container,
+ IndexType dataType, int elementType) {
+ return getIndexContainer(container).getIndexSearcher(dataType,
+ elementType);
+ }
+
+ /**
+ * Finds and returns time stamps index writer for given container.
+ *
+ * @param container
+ * @return time stamps index writer
+ */
+ public final IndexWriter findTimestampsWriter(String container) {
+ return getIndexContainer(container).getTimestampsWriter();
+ }
+
+ /**
+ * Finds and returns time stamps index searcher for given container.
+ *
+ * @param container
+ * @return time stamps index searcher
+ */
+ public final SearcherManager findTimestampsSearcher(String container) {
+ return getIndexContainer(container).getTimestampsSearcher();
+ }
+
+ /**
+ * Deletes related container index entry (container entry is removed
+ * completely).
+ *
+ * @param container
+ */
+ public final void delete(final String container) {
+ deleteIndexContainer(container);
+ }
+
+ /**
+ * Deletes given container's source module index data.
+ *
+ * @param container
+ * @param sourceModule
+ */
+ public final void delete(String container, String sourceModule) {
+ if (fContainerMappings.getProperty(container) != null) {
+ getIndexContainer(container).delete(sourceModule);
+ }
+ }
+
+ private synchronized void startup() {
+ loadProperties();
+ boolean purgeIndexRoot = false;
+ boolean resetProperties = false;
+ String modelVersion = fIndexProperties
+ .getProperty(IndexProperties.KEY_MODEL_VERSION);
+ String luceneVersion = fIndexProperties
+ .getProperty(IndexProperties.KEY_LUCENE_VERSION);
+ if (!IndexProperties.MODEL_VERSION.equals(modelVersion)
+ || !IndexProperties.LUCENE_VERSION.equals(luceneVersion)) {
+ purgeIndexRoot = true;
+ resetProperties = true;
+ }
+ if (purgeIndexRoot) {
+ purge();
+ }
+ if (resetProperties) {
+ resetProperties();
+ saveProperties();
+ }
+ loadMappings();
+ registerIndexContainers();
+ try {
+ ResourcesPlugin.getWorkspace().addSaveParticipant(LucenePlugin.ID,
+ new SaveParticipant());
+ } catch (CoreException e) {
+ Logger.logException(e);
+ }
+ }
+
+ private synchronized void shutdown() {
+ // Close all searchers & writers in all container entries
+ for (IndexContainer entry : fIndexContainers.values()) {
+ entry.close();
+ }
+ cleanup();
+ }
+
+ private synchronized IndexContainer getIndexContainer(String container) {
+ String containerId = fContainerMappings.getProperty(container);
+ if (containerId == null) {
+ do {
+ // Just to be sure that ID does not already exist
+ containerId = UUID.randomUUID().toString();
+ } while (fContainerMappings.containsValue(containerId));
+ fContainerMappings.put(container, containerId);
+ fIndexContainers.put(containerId,
+ new IndexContainer(fIndexRoot, containerId));
+ // Persist mapping
+ saveMappings();
+ }
+ return fIndexContainers.get(containerId);
+ }
+
+ private synchronized void deleteIndexContainer(String container) {
+ String containerId = (String) fContainerMappings.remove(container);
+ if (containerId != null) {
+ IndexContainer containerEntry = fIndexContainers
+ .remove(containerId);
+ saveMappings();
+ containerEntry.delete();
+ }
+ }
+
+ private void registerIndexContainers() {
+ for (String container : fContainerMappings.stringPropertyNames()) {
+ String containerId = fContainerMappings.getProperty(container);
+ fIndexContainers.put(containerId,
+ new IndexContainer(fIndexRoot, containerId));
+ }
+ }
+
+ private void loadProperties() {
+ File file = Paths.get(fIndexRoot, PROPERTIES_FILE).toFile();
+ if (!file.exists()) {
+ return;
+ }
+ try (FileInputStream fis = new FileInputStream(file)) {
+ fIndexProperties.load(fis);
+ } catch (IOException e) {
+ Logger.logException(e);
+ }
+ }
+
+ private void loadMappings() {
+ File file = Paths.get(fIndexRoot, MAPPINGS_FILE).toFile();
+ if (!file.exists()) {
+ return;
+ }
+ try (FileInputStream fis = new FileInputStream(file)) {
+ fContainerMappings.load(fis);
+ } catch (IOException e) {
+ Logger.logException(e);
+ }
+ }
+
+ private void saveProperties() {
+ File file = Paths.get(fIndexRoot, PROPERTIES_FILE).toFile();
+ try (FileOutputStream fos = new FileOutputStream(file)) {
+ fIndexProperties.store(fos, ""); //$NON-NLS-1$
+ } catch (IOException e) {
+ Logger.logException(e);
+ }
+ }
+
+ private void saveMappings() {
+ File file = Paths.get(fIndexRoot, MAPPINGS_FILE).toFile();
+ try (FileOutputStream fos = new FileOutputStream(file)) {
+ fContainerMappings.store(fos, ""); //$NON-NLS-1$
+ } catch (IOException e) {
+ Logger.logException(e);
+ }
+ }
+
+ private void resetProperties() {
+ fIndexProperties.clear();
+ fIndexProperties.put(IndexProperties.KEY_MODEL_VERSION,
+ IndexProperties.MODEL_VERSION);
+ fIndexProperties.put(IndexProperties.KEY_LUCENE_VERSION,
+ IndexProperties.LUCENE_VERSION);
+ }
+
+ private void cleanup() {
+ List<String> containers = new ArrayList<>();
+ for (IDLTKLanguageToolkit toolkit : DLTKLanguageManager
+ .getLanguageToolkits()) {
+ DLTKWorkspaceScope scope = ModelManager.getModelManager()
+ .getWorkspaceScope(toolkit);
+ for (IPath path : scope.enclosingProjectsAndZips()) {
+ containers.add(path.toString());
+ }
+ }
+ Set<String> toRemove = new HashSet<>();
+ for (String mappedContainer : fContainerMappings
+ .stringPropertyNames()) {
+ if (!containers.contains(mappedContainer)) {
+ toRemove.add(mappedContainer);
+ }
+ }
+ if (!toRemove.isEmpty()) {
+ for (String container : toRemove) {
+ deleteIndexContainer(container);
+ }
+ // Save cleaned up container mappings
+ saveMappings();
+ }
+ }
+
+ private void purge() {
+ Path indexRoot = Paths.get(fIndexRoot);
+ try {
+ Files.walkFileTree(indexRoot, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file,
+ BasicFileAttributes attrs) throws IOException {
+ Files.delete(file);
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir,
+ IOException exc) throws IOException {
+ Files.delete(dir);
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ } catch (IOException e) {
+ Logger.logException(e);
+ }
+ indexRoot.toFile().mkdir();
+ }
+
+}
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/LuceneSearchEngine.java b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/LuceneSearchEngine.java
new file mode 100644
index 0000000..f435262
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/LuceneSearchEngine.java
@@ -0,0 +1,306 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Zend Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dltk.internal.core.index.lucene;
+
+import static org.eclipse.dltk.internal.core.index.lucene.IndexFields.*;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.lucene.index.BinaryDocValues;
+import org.apache.lucene.index.LeafReader;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.NumericDocValues;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause.Occur;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.Collector;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.LeafCollector;
+import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.PrefixQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.SearcherManager;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.WildcardQuery;
+import org.apache.lucene.util.BytesRef;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.dltk.core.ScriptModelUtil;
+import org.eclipse.dltk.core.index2.search.ISearchEngineExtension;
+import org.eclipse.dltk.core.index2.search.ISearchRequestor;
+import org.eclipse.dltk.core.search.IDLTKSearchScope;
+import org.eclipse.dltk.internal.core.search.DLTKSearchScope;
+
+/**
+ * Lucene based implementation for DLTK search engine.
+ *
+ * @author Michal Niewrzal, Bartlomiej Laczkowski
+ */
+@SuppressWarnings("restriction")
+public class LuceneSearchEngine implements ISearchEngineExtension {
+
+ private static final class SearchScope {
+
+ static List<String> getContainers(IDLTKSearchScope scope) {
+ List<String> containers = new ArrayList<>();
+ for (IPath path : scope.enclosingProjectsAndZips()) {
+ containers.add(path.toString());
+ }
+ return containers;
+ }
+
+ static List<String> getScripts(IDLTKSearchScope scope) {
+ List<String> scripts = new ArrayList<>();
+ if (scope instanceof DLTKSearchScope) {
+ String[] relativePaths = ((DLTKSearchScope) scope)
+ .getRelativePaths();
+ String[] fileExtensions = ScriptModelUtil
+ .getFileExtensions(scope.getLanguageToolkit());
+ for (String relativePath : relativePaths) {
+ if (relativePath.length() > 0) {
+ if (fileExtensions != null) {
+ boolean isScriptFile = false;
+ for (String ext : fileExtensions) {
+ if (relativePath.endsWith("." + ext)) { //$NON-NLS-1$
+ isScriptFile = true;
+ break;
+ }
+ }
+ if (!isScriptFile) {
+ break;
+ }
+ }
+ scripts.add(relativePath);
+ }
+ }
+ }
+ return scripts;
+ }
+
+ }
+
+ private static final class ResultsCollector implements Collector {
+
+ private static final String[] NUMERIC_FIELDS = new String[] {
+ NDV_OFFSET, NDV_LENGTH, NDV_FLAGS, NDV_NAME_OFFSET,
+ NDV_NAME_LENGTH };
+ private static final String[] BINARY_FIELDS = new String[] { BDV_PATH,
+ BDV_ELEMENT_NAME, BDV_QUALIFIER, BDV_PARENT, BDV_METADATA,
+ BDV_DOC };
+ private Map<String, NumericDocValues> fDocNumericValues;
+ private Map<String, BinaryDocValues> fDocBinaryValues;
+ private String fContainer;
+ private int fElementType;
+ private List<SearchMatch> fResult;
+
+ public ResultsCollector(String container, int elementType,
+ List<SearchMatch> result) {
+ this.fContainer = container;
+ this.fElementType = elementType;
+ this.fResult = result;
+ }
+
+ @Override
+ public boolean needsScores() {
+ return true;
+ }
+
+ @Override
+ public LeafCollector getLeafCollector(final LeafReaderContext context)
+ throws IOException {
+ final LeafReader reader = context.reader();
+ fDocNumericValues = new HashMap<>();
+ for (String field : NUMERIC_FIELDS) {
+ NumericDocValues docValues = reader.getNumericDocValues(field);
+ if (docValues != null) {
+ fDocNumericValues.put(field, docValues);
+ }
+ }
+ fDocBinaryValues = new HashMap<>();
+ for (String field : BINARY_FIELDS) {
+ BinaryDocValues docValues = reader.getBinaryDocValues(field);
+ if (docValues != null) {
+ fDocBinaryValues.put(field, docValues);
+ }
+ }
+ return new LeafCollector() {
+ @Override
+ public void setScorer(Scorer scorer) throws IOException {
+ // ignore
+ }
+
+ @Override
+ public void collect(int docId) throws IOException {
+ addResult(docId);
+ }
+ };
+ }
+
+ private void addResult(int docId) {
+ fResult.add(new SearchMatch(fContainer, fElementType,
+ getNumericValue(NDV_OFFSET, docId),
+ getNumericValue(NDV_LENGTH, docId),
+ getNumericValue(NDV_NAME_OFFSET, docId),
+ getNumericValue(NDV_NAME_LENGTH, docId),
+ getNumericValue(NDV_FLAGS, docId),
+ getStringValue(BDV_ELEMENT_NAME, docId),
+ getStringValue(BDV_PATH, docId),
+ getStringValue(BDV_PARENT, docId),
+ getStringValue(BDV_QUALIFIER, docId),
+ getStringValue(BDV_DOC, docId),
+ getStringValue(BDV_METADATA, docId)));
+ }
+
+ private int getNumericValue(String field, int docId) {
+ NumericDocValues docValues = fDocNumericValues.get(field);
+ if (docValues != null) {
+ return (int) docValues.get(docId);
+ }
+ return 0;
+ }
+
+ private String getStringValue(String field, int docId) {
+ BinaryDocValues docValues = fDocBinaryValues.get(field);
+ if (docValues != null) {
+ BytesRef bytesRef = docValues.get(docId);
+ if (bytesRef.length > 0)
+ return bytesRef.utf8ToString();
+ }
+ return null;
+ }
+ }
+
+ @Override
+ public void search(int elementType, String qualifier, String elementName,
+ int trueFlags, int falseFlags, int limit, SearchFor searchFor,
+ MatchRule matchRule, IDLTKSearchScope scope,
+ ISearchRequestor requestor, IProgressMonitor monitor) {
+ search(elementType, qualifier, elementName, null, trueFlags, falseFlags,
+ limit, searchFor, matchRule, scope, requestor, monitor);
+ }
+
+ @Override
+ public void search(int elementType, String qualifier, String elementName,
+ String parent, int trueFlags, int falseFlags, int limit,
+ SearchFor searchFor, MatchRule matchRule, IDLTKSearchScope scope,
+ ISearchRequestor requestor, IProgressMonitor monitor) {
+ boolean searchForDecls = searchFor == SearchFor.DECLARATIONS
+ || searchFor == SearchFor.ALL_OCCURRENCES;
+ boolean searchForRefs = searchFor == SearchFor.REFERENCES
+ || searchFor == SearchFor.ALL_OCCURRENCES;
+ if (searchForRefs) {
+ doSearch(elementType, qualifier, elementName, parent, trueFlags,
+ falseFlags, limit, true, matchRule, scope, requestor,
+ monitor);
+ }
+ if (searchForDecls) {
+ doSearch(elementType, qualifier, elementName, parent, trueFlags,
+ falseFlags, limit, false, matchRule, scope, requestor,
+ monitor);
+ }
+ }
+
+ private Query createQuery(final String elementName, final String qualifier,
+ final String parent, final int trueFlags, final int falseFlags,
+ final boolean searchForRefs, MatchRule matchRule,
+ IDLTKSearchScope scope) {
+ BooleanQuery query = new BooleanQuery();
+ List<String> scripts = SearchScope.getScripts(scope);
+ if (!scripts.isEmpty()) {
+ BooleanQuery scriptQuery = new BooleanQuery();
+ for (String script : scripts) {
+ scriptQuery.add(new TermQuery(new Term(F_PATH, script)),
+ Occur.FILTER);
+ }
+ query.add(scriptQuery, Occur.FILTER);
+ }
+ if (elementName != null && !elementName.isEmpty()) {
+ String elementNameLC = elementName.toLowerCase();
+ Query nameQuery = null;
+ Term nameCaseInsensitiveTerm = new Term(F_ELEMENT_NAME_LC,
+ elementNameLC);
+ if (matchRule == MatchRule.PREFIX) {
+ nameQuery = new PrefixQuery(nameCaseInsensitiveTerm);
+ } else if (matchRule == MatchRule.EXACT) {
+ nameQuery = new TermQuery(nameCaseInsensitiveTerm);
+ } else if (matchRule == MatchRule.CAMEL_CASE) {
+ nameQuery = new PrefixQuery(new Term(F_CC_NAME, elementName));
+ } else if (matchRule == MatchRule.PATTERN) {
+ nameQuery = new WildcardQuery(nameCaseInsensitiveTerm);
+ } else {
+ throw new UnsupportedOperationException();
+ }
+ if (nameQuery != null) {
+ query.add(nameQuery, Occur.FILTER);
+ }
+ }
+ if (qualifier != null && !qualifier.isEmpty()) {
+ query.add(new TermQuery(new Term(F_QUALIFIER, qualifier)),
+ Occur.FILTER);
+ }
+ if (parent != null && !parent.isEmpty()) {
+ query.add(new TermQuery(new Term(F_PARENT, parent)), Occur.FILTER);
+ }
+ if (trueFlags != 0 || falseFlags != 0) {
+ query.add(new BitFlagsQuery(trueFlags, falseFlags), Occur.FILTER);
+ }
+ return query.clauses().isEmpty() ? null : query;
+ }
+
+ private void doSearch(final int elementType, String qualifier,
+ String elementName, String parent, final int trueFlags,
+ final int falseFlags, int limit, final boolean searchForRefs,
+ MatchRule matchRule, IDLTKSearchScope scope,
+ ISearchRequestor requestor, IProgressMonitor monitor) {
+ Query query = createQuery(elementName, qualifier, parent, trueFlags,
+ falseFlags, searchForRefs, matchRule, scope);
+ IndexSearcher indexSearcher = null;
+ final SearchMatchHandler searchMatchHandler = new SearchMatchHandler(
+ scope, requestor);
+ List<SearchMatch> results = new ArrayList<>();
+ for (String container : SearchScope.getContainers(scope)) {
+ SearcherManager searcherManager = LuceneManager.INSTANCE
+ .findIndexSearcher(container, searchForRefs
+ ? IndexType.REFERENCES : IndexType.DECLARATIONS,
+ elementType);
+ try {
+ indexSearcher = searcherManager.acquire();
+ ResultsCollector collector = new ResultsCollector(container,
+ elementType, results);
+ if (query != null) {
+ indexSearcher.search(query, collector);
+ } else {
+ indexSearcher.search(new MatchAllDocsQuery(), collector);
+ }
+ } catch (IOException e) {
+ Logger.logException(e);
+ } finally {
+ if (indexSearcher != null) {
+ try {
+ searcherManager.release(indexSearcher);
+ } catch (IOException e) {
+ Logger.logException(e);
+ }
+ }
+ }
+ }
+ // Pass results to entity handler
+ for (SearchMatch result : results) {
+ searchMatchHandler.handle(result, searchForRefs);
+ }
+ }
+
+}
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/SearchMatch.java b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/SearchMatch.java
new file mode 100644
index 0000000..96194c3
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/SearchMatch.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Zend Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dltk.internal.core.index.lucene;
+
+/**
+ * Search match descriptor.
+ *
+ * @author Bartlomiej Laczkowski
+ */
+public class SearchMatch {
+
+ public final String path;
+ public final String container;
+ public final int elementType;
+ public final String elementName;
+ public final int offset;
+ public final int length;
+ public final String metadata;
+ public final String qualifier;
+ public final String doc;
+ public final int flags;
+ public final int nameOffset;
+ public final int nameLength;
+ public final String parent;
+
+ /**
+ * Creates new search match.
+ *
+ * @param container
+ * @param elementType
+ * @param offset
+ * @param length
+ * @param nameOffset
+ * @param nameLength
+ * @param flags
+ * @param elementName
+ * @param path
+ * @param parent
+ * @param qualifier
+ * @param doc
+ * @param metadata
+ */
+ public SearchMatch(String container, int elementType, int offset,
+ int length, int nameOffset, int nameLength, int flags,
+ String elementName, String path, String parent, String qualifier,
+ String doc, String metadata) {
+ super();
+ this.container = container;
+ this.elementType = elementType;
+ this.offset = offset;
+ this.length = length;
+ this.nameOffset = nameOffset;
+ this.nameLength = nameLength;
+ this.flags = flags;
+ this.elementName = elementName;
+ this.path = path;
+ this.parent = parent;
+ this.qualifier = qualifier;
+ this.doc = doc;
+ this.metadata = metadata;
+ }
+
+}
diff --git a/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/SearchMatchHandler.java b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/SearchMatchHandler.java
new file mode 100644
index 0000000..20be5de
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.index.lucene/src/org/eclipse/dltk/internal/core/index/lucene/SearchMatchHandler.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Zend Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Zend Technologies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dltk.internal.core.index.lucene;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.core.IDLTKLanguageToolkit;
+import org.eclipse.dltk.core.IDLTKLanguageToolkitExtension;
+import org.eclipse.dltk.core.IProjectFragment;
+import org.eclipse.dltk.core.IScriptFolder;
+import org.eclipse.dltk.core.ISourceModule;
+import org.eclipse.dltk.core.index2.search.ISearchRequestor;
+import org.eclipse.dltk.core.search.IDLTKSearchScope;
+import org.eclipse.dltk.internal.core.ArchiveFolder;
+import org.eclipse.dltk.internal.core.BuiltinScriptFolder;
+import org.eclipse.dltk.internal.core.ExternalScriptFolder;
+import org.eclipse.dltk.internal.core.ModelManager;
+import org.eclipse.dltk.internal.core.ProjectFragment;
+import org.eclipse.dltk.internal.core.search.DLTKSearchScope;
+
+/**
+ * Class responsible for handling search match.
+ *
+ * @author Michal Niewrzal
+ */
+@SuppressWarnings("restriction")
+public class SearchMatchHandler {
+
+ private static class FilePathHandler {
+
+ private IPath fFolderPath = Path.EMPTY;
+ private String fFileName;
+
+ public FilePathHandler(String filePath) {
+ this.fFileName = filePath;
+ int i = filePath.lastIndexOf('/');
+ if (i == -1) {
+ i = filePath.lastIndexOf('\\');
+ }
+ if (i != -1) {
+ this.fFolderPath = new Path(filePath.substring(0, i));
+ this.fFileName = filePath.substring(i + 1);
+ }
+ }
+
+ public IPath getFolderPath() {
+ return fFolderPath;
+ }
+
+ public String getFileName() {
+ return fFileName;
+ }
+ }
+
+ private Map<String, IProjectFragment> fProjectFragmentCache = new HashMap<>();
+ private Map<String, ISourceModule> fSourceModuleCache = new HashMap<>();
+ private ISearchRequestor fSearchRequestor;
+ private IDLTKSearchScope fScope;
+
+ /**
+ * Creates new search match handler.
+ *
+ * @param scope
+ * @param searchRequestor
+ */
+ public SearchMatchHandler(IDLTKSearchScope scope,
+ ISearchRequestor searchRequestor) {
+ this.fScope = scope;
+ this.fSearchRequestor = searchRequestor;
+ }
+
+ /**
+ * Handle search match.
+ *
+ * @param match
+ * @param isReference
+ */
+ public void handle(SearchMatch match, boolean isReference) {
+ String containerPath = match.container;
+ IDLTKLanguageToolkit toolkit = ((DLTKSearchScope) fScope)
+ .getLanguageToolkit();
+ if (toolkit instanceof IDLTKLanguageToolkitExtension
+ && ((IDLTKLanguageToolkitExtension) toolkit)
+ .isArchiveFileName(containerPath)) {
+ containerPath = containerPath
+ + IDLTKSearchScope.FILE_ENTRY_SEPARATOR;
+ }
+ if (containerPath.length() != 0 && containerPath
+ .charAt(containerPath.length() - 1) != IPath.SEPARATOR) {
+ containerPath = containerPath + IPath.SEPARATOR;
+ }
+ String filePath = match.path;
+ final String resourcePath = containerPath + filePath;
+ IProjectFragment projectFragment = fProjectFragmentCache
+ .get(containerPath);
+ if (projectFragment == null) {
+ projectFragment = ((DLTKSearchScope) fScope)
+ .projectFragment(resourcePath);
+ if (projectFragment == null) {
+ projectFragment = ((DLTKSearchScope) fScope)
+ .projectFragment(containerPath);
+ }
+ fProjectFragmentCache.put(containerPath, projectFragment);
+ }
+ if (projectFragment == null) {
+ return;
+ }
+ if (!fScope.encloses(resourcePath)) {
+ return;
+ }
+ ISourceModule sourceModule = fSourceModuleCache.get(resourcePath);
+ if (sourceModule == null) {
+ if (projectFragment.isArchive()) {
+ FilePathHandler filePathHandler = new FilePathHandler(filePath);
+ IScriptFolder scriptFolder = new ArchiveFolder(
+ (ProjectFragment) projectFragment,
+ filePathHandler.getFolderPath());
+ sourceModule = scriptFolder
+ .getSourceModule(filePathHandler.getFileName());
+ } else if (projectFragment.isExternal()) {
+ FilePathHandler filePathHandler = new FilePathHandler(filePath);
+ IScriptFolder scriptFolder = new ExternalScriptFolder(
+ (ProjectFragment) projectFragment,
+ filePathHandler.getFolderPath());
+ sourceModule = scriptFolder
+ .getSourceModule(filePathHandler.getFileName());
+ } else if (projectFragment.isBuiltin()) {
+ FilePathHandler filePathHandler = new FilePathHandler(filePath);
+ IScriptFolder scriptFolder = new BuiltinScriptFolder(
+ (ProjectFragment) projectFragment,
+ filePathHandler.getFolderPath());
+ sourceModule = scriptFolder
+ .getSourceModule(filePathHandler.getFileName());
+ } else {
+ IProject project = projectFragment.getScriptProject()
+ .getProject();
+ sourceModule = DLTKCore
+ .createSourceModuleFrom(project.getFile(filePath));
+ }
+ fSourceModuleCache.put(resourcePath, sourceModule);
+ }
+ String name = match.elementName;
+ if (name == null) {
+ return;
+ }
+ ModelManager modelManager = ModelManager.getModelManager();
+ name = modelManager.intern(name);
+ // Pass to requestor
+ fSearchRequestor.match(match.elementType, match.flags, match.offset,
+ match.length, match.nameOffset, match.nameLength, name,
+ match.metadata, match.doc, match.qualifier, match.parent,
+ sourceModule, isReference);
+
+ }
+
+}
\ No newline at end of file