/* * 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.lucene.document; import org.apache.lucene.analysis.Analyzer; // javadocs import org.apache.lucene.index.DocValuesType; import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexableFieldType; import org.apache.lucene.index.PointValues; /** * Describes the properties of a field. */ public class FieldType implements IndexableFieldType { private boolean stored; private boolean tokenized = true; private boolean storeTermVectors; private boolean storeTermVectorOffsets; private boolean storeTermVectorPositions; private boolean storeTermVectorPayloads; private boolean omitNorms; private IndexOptions indexOptions = IndexOptions.NONE; private boolean frozen; private DocValuesType docValuesType = DocValuesType.NONE; private int dimensionCount; private int dimensionNumBytes; /** * Create a new mutable FieldType with all of the properties from <code>ref</code> */ public FieldType(IndexableFieldType ref) { this.stored = ref.stored(); this.tokenized = ref.tokenized(); this.storeTermVectors = ref.storeTermVectors(); this.storeTermVectorOffsets = ref.storeTermVectorOffsets(); this.storeTermVectorPositions = ref.storeTermVectorPositions(); this.storeTermVectorPayloads = ref.storeTermVectorPayloads(); this.omitNorms = ref.omitNorms(); this.indexOptions = ref.indexOptions(); this.docValuesType = ref.docValuesType(); this.dimensionCount = ref.pointDimensionCount(); this.dimensionNumBytes = ref.pointNumBytes(); // Do not copy frozen! } /** * Create a new FieldType with default properties. */ public FieldType() { } /** * Throws an exception if this FieldType is frozen. Subclasses should * call this within setters for additional state. */ protected void checkIfFrozen() { if (frozen) { throw new IllegalStateException("this FieldType is already frozen and cannot be changed"); } } /** * Prevents future changes. Note, it is recommended that this is called once * the FieldTypes's properties have been set, to prevent unintentional state * changes. */ public void freeze() { this.frozen = true; } /** * {@inheritDoc} * <p> * The default is <code>false</code>. * @see #setStored(boolean) */ @Override public boolean stored() { return this.stored; } /** * Set to <code>true</code> to store this field. * @param value true if this field should be stored. * @throws IllegalStateException if this FieldType is frozen against * future modifications. * @see #stored() */ public void setStored(boolean value) { checkIfFrozen(); this.stored = value; } /** * {@inheritDoc} * <p> * The default is <code>true</code>. * @see #setTokenized(boolean) */ public boolean tokenized() { return this.tokenized; } /** * Set to <code>true</code> to tokenize this field's contents via the * configured {@link Analyzer}. * @param value true if this field should be tokenized. * @throws IllegalStateException if this FieldType is frozen against * future modifications. * @see #tokenized() */ public void setTokenized(boolean value) { checkIfFrozen(); this.tokenized = value; } /** * {@inheritDoc} * <p> * The default is <code>false</code>. * @see #setStoreTermVectors(boolean) */ @Override public boolean storeTermVectors() { return this.storeTermVectors; } /** * Set to <code>true</code> if this field's indexed form should be also stored * into term vectors. * @param value true if this field should store term vectors. * @throws IllegalStateException if this FieldType is frozen against * future modifications. * @see #storeTermVectors() */ public void setStoreTermVectors(boolean value) { checkIfFrozen(); this.storeTermVectors = value; } /** * {@inheritDoc} * <p> * The default is <code>false</code>. * @see #setStoreTermVectorOffsets(boolean) */ @Override public boolean storeTermVectorOffsets() { return this.storeTermVectorOffsets; } /** * Set to <code>true</code> to also store token character offsets into the term * vector for this field. * @param value true if this field should store term vector offsets. * @throws IllegalStateException if this FieldType is frozen against * future modifications. * @see #storeTermVectorOffsets() */ public void setStoreTermVectorOffsets(boolean value) { checkIfFrozen(); this.storeTermVectorOffsets = value; } /** * {@inheritDoc} * <p> * The default is <code>false</code>. * @see #setStoreTermVectorPositions(boolean) */ @Override public boolean storeTermVectorPositions() { return this.storeTermVectorPositions; } /** * Set to <code>true</code> to also store token positions into the term * vector for this field. * @param value true if this field should store term vector positions. * @throws IllegalStateException if this FieldType is frozen against * future modifications. * @see #storeTermVectorPositions() */ public void setStoreTermVectorPositions(boolean value) { checkIfFrozen(); this.storeTermVectorPositions = value; } /** * {@inheritDoc} * <p> * The default is <code>false</code>. * @see #setStoreTermVectorPayloads(boolean) */ @Override public boolean storeTermVectorPayloads() { return this.storeTermVectorPayloads; } /** * Set to <code>true</code> to also store token payloads into the term * vector for this field. * @param value true if this field should store term vector payloads. * @throws IllegalStateException if this FieldType is frozen against * future modifications. * @see #storeTermVectorPayloads() */ public void setStoreTermVectorPayloads(boolean value) { checkIfFrozen(); this.storeTermVectorPayloads = value; } /** * {@inheritDoc} * <p> * The default is <code>false</code>. * @see #setOmitNorms(boolean) */ @Override public boolean omitNorms() { return this.omitNorms; } /** * Set to <code>true</code> to omit normalization values for the field. * @param value true if this field should omit norms. * @throws IllegalStateException if this FieldType is frozen against * future modifications. * @see #omitNorms() */ public void setOmitNorms(boolean value) { checkIfFrozen(); this.omitNorms = value; } /** * {@inheritDoc} * <p> * The default is {@link IndexOptions#DOCS_AND_FREQS_AND_POSITIONS}. * @see #setIndexOptions(IndexOptions) */ @Override public IndexOptions indexOptions() { return this.indexOptions; } /** * Sets the indexing options for the field: * @param value indexing options * @throws IllegalStateException if this FieldType is frozen against * future modifications. * @see #indexOptions() */ public void setIndexOptions(IndexOptions value) { checkIfFrozen(); if (value == null) { throw new NullPointerException("IndexOptions must not be null"); } this.indexOptions = value; } /** * Enables points indexing. */ public void setDimensions(int dimensionCount, int dimensionNumBytes) { if (dimensionCount < 0) { throw new IllegalArgumentException("dimensionCount must be >= 0; got " + dimensionCount); } if (dimensionCount > PointValues.MAX_DIMENSIONS) { throw new IllegalArgumentException("dimensionCount must be <= " + PointValues.MAX_DIMENSIONS + "; got " + dimensionCount); } if (dimensionNumBytes < 0) { throw new IllegalArgumentException("dimensionNumBytes must be >= 0; got " + dimensionNumBytes); } if (dimensionNumBytes > PointValues.MAX_NUM_BYTES) { throw new IllegalArgumentException("dimensionNumBytes must be <= " + PointValues.MAX_NUM_BYTES + "; got " + dimensionNumBytes); } if (dimensionCount == 0) { if (dimensionNumBytes != 0) { throw new IllegalArgumentException("when dimensionCount is 0, dimensionNumBytes must 0; got " + dimensionNumBytes); } } else if (dimensionNumBytes == 0) { if (dimensionCount != 0) { throw new IllegalArgumentException("when dimensionNumBytes is 0, dimensionCount must 0; got " + dimensionCount); } } this.dimensionCount = dimensionCount; this.dimensionNumBytes = dimensionNumBytes; } @Override public int pointDimensionCount() { return dimensionCount; } @Override public int pointNumBytes() { return dimensionNumBytes; } /** Prints a Field for human consumption. */ @Override public String toString() { StringBuilder result = new StringBuilder(); if (stored()) { result.append("stored"); } if (indexOptions != IndexOptions.NONE) { if (result.length() > 0) result.append(","); result.append("indexed"); if (tokenized()) { result.append(",tokenized"); } if (storeTermVectors()) { result.append(",termVector"); } if (storeTermVectorOffsets()) { result.append(",termVectorOffsets"); } if (storeTermVectorPositions()) { result.append(",termVectorPosition"); } if (storeTermVectorPayloads()) { result.append(",termVectorPayloads"); } if (omitNorms()) { result.append(",omitNorms"); } if (indexOptions != IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) { result.append(",indexOptions="); result.append(indexOptions); } } if (dimensionCount != 0) { if (result.length() > 0) { result.append(","); } result.append("pointDimensionCount="); result.append(dimensionCount); result.append(",pointNumBytes="); result.append(dimensionNumBytes); } if (docValuesType != DocValuesType.NONE) { if (result.length() > 0) { result.append(","); } result.append("docValuesType="); result.append(docValuesType); } return result.toString(); } /** * {@inheritDoc} * <p> * The default is <code>null</code> (no docValues) * @see #setDocValuesType(DocValuesType) */ @Override public DocValuesType docValuesType() { return docValuesType; } /** * Sets the field's DocValuesType * @param type DocValues type, or null if no DocValues should be stored. * @throws IllegalStateException if this FieldType is frozen against * future modifications. * @see #docValuesType() */ public void setDocValuesType(DocValuesType type) { checkIfFrozen(); if (type == null) { throw new NullPointerException("DocValuesType must not be null"); } docValuesType = type; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + dimensionCount; result = prime * result + dimensionNumBytes; result = prime * result + ((docValuesType == null) ? 0 : docValuesType.hashCode()); result = prime * result + indexOptions.hashCode(); result = prime * result + (omitNorms ? 1231 : 1237); result = prime * result + (storeTermVectorOffsets ? 1231 : 1237); result = prime * result + (storeTermVectorPayloads ? 1231 : 1237); result = prime * result + (storeTermVectorPositions ? 1231 : 1237); result = prime * result + (storeTermVectors ? 1231 : 1237); result = prime * result + (stored ? 1231 : 1237); result = prime * result + (tokenized ? 1231 : 1237); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; FieldType other = (FieldType) obj; if (dimensionCount != other.dimensionCount) return false; if (dimensionNumBytes != other.dimensionNumBytes) return false; if (docValuesType != other.docValuesType) return false; if (indexOptions != other.indexOptions) return false; if (omitNorms != other.omitNorms) return false; if (storeTermVectorOffsets != other.storeTermVectorOffsets) return false; if (storeTermVectorPayloads != other.storeTermVectorPayloads) return false; if (storeTermVectorPositions != other.storeTermVectorPositions) return false; if (storeTermVectors != other.storeTermVectors) return false; if (stored != other.stored) return false; if (tokenized != other.tokenized) return false; return true; } }