blob: f63691d7de6727efef18b0a291bbb6277ccb7b62 [file] [log] [blame]
/*******************************************************************************
* 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)));
}
}