package org.apache.blur.analysis.type;
/**
* 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.
*/
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Constructor;
import java.util.Map;
import org.apache.blur.analysis.FieldTypeDefinition;
import org.apache.blur.analysis.NoStopWordStandardAnalyzer;
import org.apache.blur.log.Log;
import org.apache.blur.log.LogFactory;
import org.apache.blur.lucene.LuceneVersionConstant;
import org.apache.blur.thrift.generated.Column;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.TextField;
import org.apache.lucene.search.SortField;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.Version;
public class TextFieldTypeDefinition extends FieldTypeDefinition {
private static final Log LOG = LogFactory.getLog(TextFieldTypeDefinition.class);
public static final String ANALYZER_CLASS = "analyzerClass";
public static final String STOP_WORD_PATH = "stopWordPath";
public static final String NAME = "text";
public static final FieldType TYPE_NOT_STORED;
public static final FieldType TYPE_STORED;
private Analyzer _analyzer;
static {
TYPE_STORED = new FieldType(TextField.TYPE_STORED);
TYPE_STORED.setOmitNorms(true);
TYPE_STORED.freeze();
TYPE_NOT_STORED = new FieldType(TextField.TYPE_NOT_STORED);
TYPE_NOT_STORED.setOmitNorms(true);
TYPE_NOT_STORED.freeze();
}
@Override
public String getName() {
return NAME;
}
@Override
public void configure(String fieldNameForThisInstance, Map<String, String> properties, Configuration configuration) {
String stopWordUri = properties.get(STOP_WORD_PATH);
String className = properties.get(ANALYZER_CLASS);
if (stopWordUri == null) {
if (className == null) {
_analyzer = new NoStopWordStandardAnalyzer();
} else {
_analyzer = instance(className);
}
} else {
if (className != null) {
LOG.warn("Class name [{0}] ignored do due to the [{1}] property being set.", className, STOP_WORD_PATH);
}
try {
Path path = new Path(stopWordUri);
FileSystem fileSystem = path.getFileSystem(configuration);
Reader reader = new InputStreamReader(fileSystem.open(path));
// Reader closed by analyzer
_analyzer = new StandardAnalyzer(LuceneVersionConstant.LUCENE_VERSION, reader);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
private static Analyzer instance(String name) {
try {
Class<?> clazz = Class.forName(name);
Constructor<?>[] constructors = clazz.getConstructors();
for (Constructor<?> constructor : constructors) {
Class<?>[] parameterTypes = constructor.getParameterTypes();
if (parameterTypes.length == 0) {
return (Analyzer) constructor.newInstance(new Object[] {});
}
}
for (Constructor<?> constructor : constructors) {
Class<?>[] parameterTypes = constructor.getParameterTypes();
if (parameterTypes.length == 1) {
Class<?> type = parameterTypes[0];
if (type.equals(Version.class)) {
return (Analyzer) constructor.newInstance(new Object[] { LuceneVersionConstant.LUCENE_VERSION });
}
}
}
throw new RuntimeException("Cannot find a default constructor or a constructor that takes a ["
+ Version.class.getName() + "]");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public Iterable<? extends Field> getFieldsForColumn(String family, Column column) {
String name = getName(family, column.getName());
Field field = new Field(name, column.getValue(), TYPE_STORED);
return makeIterable(field);
}
@Override
public Iterable<? extends Field> getFieldsForSubColumn(String family, Column column, String subName) {
String name = getName(family, column.getName(), subName);
Field field = new Field(name, column.getValue(), TYPE_NOT_STORED);
return makeIterable(field);
}
@Override
public Analyzer getAnalyzerForIndex(String fieldName) {
return _analyzer;
}
@Override
public Analyzer getAnalyzerForQuery(String fieldName) {
return _analyzer;
}
@Override
public boolean checkSupportForFuzzyQuery() {
return true;
}
@Override
public boolean checkSupportForWildcardQuery() {
return true;
}
@Override
public boolean checkSupportForPrefixQuery() {
return true;
}
@Override
public boolean checkSupportForRegexQuery() {
return true;
}
@Override
public boolean isNumeric() {
return false;
}
@Override
public boolean checkSupportForCustomQuery() {
return false;
}
@Override
public boolean checkSupportForSorting() {
return false;
}
@Override
public SortField getSortField(boolean reverse) {
throw new RuntimeException("Sort not supported.");
}
@Override
public String readTerm(BytesRef byteRef) {
return byteRef.utf8ToString();
}
}