nodeindexer.java
来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 578 行 · 第 1/2 页
JAVA
578 行
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.jackrabbit.core.query.lucene;import org.apache.jackrabbit.core.PropertyId;import org.apache.jackrabbit.core.NodeId;import org.apache.jackrabbit.core.state.ItemStateException;import org.apache.jackrabbit.core.state.ItemStateManager;import org.apache.jackrabbit.core.state.NoSuchItemStateException;import org.apache.jackrabbit.core.state.NodeState;import org.apache.jackrabbit.core.state.PropertyState;import org.apache.jackrabbit.core.value.BLOBFileValue;import org.apache.jackrabbit.core.value.InternalValue;import org.apache.jackrabbit.extractor.TextExtractor;import org.apache.jackrabbit.name.NoPrefixDeclaredException;import org.apache.jackrabbit.name.Path;import org.apache.jackrabbit.name.QName;import org.apache.jackrabbit.name.NameFormat;import org.apache.jackrabbit.name.PathFormat;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.apache.lucene.document.Document;import org.apache.lucene.document.Field;import javax.jcr.NamespaceException;import javax.jcr.PropertyType;import javax.jcr.RepositoryException;import java.io.InputStream;import java.io.Reader;import java.io.IOException;import java.util.Calendar;import java.util.Iterator;import java.util.Set;/** * Creates a lucene <code>Document</code> object from a {@link javax.jcr.Node}. */public class NodeIndexer { /** * The logger instance for this class. */ private static final Logger log = LoggerFactory.getLogger(NodeIndexer.class); /** * The <code>NodeState</code> of the node to index */ protected final NodeState node; /** * The persistent item state provider */ protected final ItemStateManager stateProvider; /** * Namespace mappings to use for indexing. This is the internal * namespace mapping. */ protected final NamespaceMappings mappings; /** * Content extractor. */ protected final TextExtractor extractor; /** * If set to <code>true</code> the fulltext field is stored and and a term * vector is created with offset information. */ protected boolean supportHighlighting = false; /** * Creates a new node indexer. * * @param node the node state to index. * @param stateProvider the persistent item state manager to retrieve properties. * @param mappings internal namespace mappings. * @param extractor content extractor */ public NodeIndexer(NodeState node, ItemStateManager stateProvider, NamespaceMappings mappings, TextExtractor extractor) { this.node = node; this.stateProvider = stateProvider; this.mappings = mappings; this.extractor = extractor; } /** * Returns the <code>NodeId</code> of the indexed node. * @return the <code>NodeId</code> of the indexed node. */ public NodeId getNodeId() { return node.getNodeId(); } /** * If set to <code>true</code> additional information is stored in the index * to support highlighting using the rep:excerpt pseudo property. * * @param b <code>true</code> to enable highlighting support. */ public void setSupportHighlighting(boolean b) { supportHighlighting = b; } /** * Creates a lucene Document. * * @return the lucene Document with the index layout. * @throws RepositoryException if an error occurs while reading property * values from the <code>ItemStateProvider</code>. */ protected Document createDoc() throws RepositoryException { Document doc = new Document(); // special fields // UUID doc.add(new Field(FieldNames.UUID, node.getNodeId().getUUID().toString(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); try { // parent UUID if (node.getParentId() == null) { // root node doc.add(new Field(FieldNames.PARENT, "", Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); doc.add(new Field(FieldNames.LABEL, "", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); } else { doc.add(new Field(FieldNames.PARENT, node.getParentId().toString(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); NodeState parent = (NodeState) stateProvider.getItemState(node.getParentId()); NodeState.ChildNodeEntry child = parent.getChildNodeEntry(node.getNodeId()); if (child == null) { // this can only happen when jackrabbit // is running in a cluster. throw new RepositoryException("Missing child node entry " + "for node with id: " + node.getNodeId()); } String name = NameFormat.format(child.getName(), mappings); doc.add(new Field(FieldNames.LABEL, name, Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); } } catch (NoSuchItemStateException e) { throwRepositoryException(e); } catch (ItemStateException e) { throwRepositoryException(e); } catch (NoPrefixDeclaredException e) { // will never happen, because this.mappings will dynamically add // unknown uri<->prefix mappings } Set props = node.getPropertyNames(); for (Iterator it = props.iterator(); it.hasNext();) { QName propName = (QName) it.next(); PropertyId id = new PropertyId(node.getNodeId(), propName); try { PropertyState propState = (PropertyState) stateProvider.getItemState(id); InternalValue[] values = propState.getValues(); for (int i = 0; i < values.length; i++) { addValue(doc, values[i], propState.getName()); } if (values.length > 1) { // real multi-valued addMVPName(doc, propState.getName()); } } catch (NoSuchItemStateException e) { throwRepositoryException(e); } catch (ItemStateException e) { throwRepositoryException(e); } } return doc; } /** * Wraps the exception <code>e</code> into a <code>RepositoryException</code> * and throws the created exception. * * @param e the base exception. */ private void throwRepositoryException(Exception e) throws RepositoryException { String msg = "Error while indexing node: " + node.getNodeId() + " of " + "type: " + node.getNodeTypeName(); throw new RepositoryException(msg, e); } /** * Adds a {@link FieldNames#MVP} field to <code>doc</code> with the resolved * <code>name</code> using the internal search index namespace mapping. * * @param doc the lucene document. * @param name the name of the multi-value property. */ private void addMVPName(Document doc, QName name) { try { String propName = NameFormat.format(name, mappings); doc.add(new Field(FieldNames.MVP, propName, Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); } catch (NoPrefixDeclaredException e) { // will never happen, prefixes are created dynamically } } /** * Adds a value to the lucene Document. * * @param doc the document. * @param value the internal jackrabbit value. * @param name the name of the property. */ private void addValue(Document doc, InternalValue value, QName name) { String fieldName = name.getLocalName(); try { fieldName = NameFormat.format(name, mappings); } catch (NoPrefixDeclaredException e) { // will never happen } Object internalValue = value.internalValue(); switch (value.getType()) { case PropertyType.BINARY: addBinaryValue(doc, fieldName, internalValue); break; case PropertyType.BOOLEAN: addBooleanValue(doc, fieldName, internalValue); break; case PropertyType.DATE: addCalendarValue(doc, fieldName, internalValue); break; case PropertyType.DOUBLE: addDoubleValue(doc, fieldName, internalValue); break; case PropertyType.LONG: addLongValue(doc, fieldName, internalValue); break; case PropertyType.REFERENCE: addReferenceValue(doc, fieldName, internalValue); break; case PropertyType.PATH: addPathValue(doc, fieldName, internalValue); break; case PropertyType.STRING: // do not fulltext index jcr:uuid String boolean tokenize = !name.equals(QName.JCR_UUID); addStringValue(doc, fieldName, internalValue, tokenize); break; case PropertyType.NAME: addNameValue(doc, fieldName, internalValue); break; default: throw new IllegalArgumentException("illegal internal value type"); } } /** * Adds the binary value to the document as the named field. * <p/> * This implementation checks if this {@link #node} is of type nt:resource * and if that is the case, tries to extract text from the binary property * using the {@link #extractor}. * * @param doc The document to which to add the field * @param fieldName The name of the field to add * @param internalValue The value for the field to add to the document. */ protected void addBinaryValue(Document doc, String fieldName, Object internalValue) { // 'check' if node is of type nt:resource try { String jcrData = mappings.getPrefix(QName.NS_JCR_URI) + ":data"; if (!jcrData.equals(fieldName)) { // don't know how to index return; } InternalValue typeValue = getValue(QName.JCR_MIMETYPE); if (typeValue != null) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?