| /******************************************************************************* |
| * 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))); |
| } |
| |
| } |