Package com.senseidb.indexing

Source Code of com.senseidb.indexing.DefaultSenseiInterpreter$MetaFormatSpec

/**
* This software is licensed to you under the Apache License, Version 2.0 (the
* "Apache License").
*
* LinkedIn's contributions are made under the Apache License. If you contribute
* to the Software, the contributions will be deemed to have been made under the
* Apache License, unless you expressly indicate otherwise. Please do not make any
* contributions that would be inconsistent with the Apache License.
*
* You may obtain a copy of the Apache License at http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, this software
* distributed under the Apache License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Apache
* License for the specific language governing permissions and limitations for the
* software governed under the Apache License.
*
* © 2012 LinkedIn Corp. All Rights Reserved. 
*/
package com.senseidb.indexing;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.Field.TermVector;

import proj.zoie.api.indexing.AbstractZoieIndexableInterpreter;
import proj.zoie.api.indexing.ZoieIndexable;

import com.browseengine.bobo.facets.data.PredefinedTermListFactory;
import com.browseengine.bobo.facets.data.TermListFactory;

public class DefaultSenseiInterpreter<V> extends
    AbstractZoieIndexableInterpreter<V> {

  private static Logger logger = Logger.getLogger(DefaultSenseiInterpreter.class);
 

  public static final Map<MetaType,String> DEFAULT_FORMAT_STRING_MAP = new HashMap<MetaType,String>();
  public static final Map<Class,MetaType>  CLASS_METATYPE_MAP = new HashMap<Class,MetaType>();
 
  public static final Map<String,Index>  INDEX_VAL_MAP = new HashMap<String,Index>();
  public static final Map<String,Store>  STORE_VAL_MAP = new HashMap<String,Store>();
  public static final Map<String,TermVector>  TV_VAL_MAP = new HashMap<String,TermVector>();   
 
  static{
    DEFAULT_FORMAT_STRING_MAP.put(MetaType.Integer, "00000000000000000000");
    DEFAULT_FORMAT_STRING_MAP.put(MetaType.Short, "00000");
    DEFAULT_FORMAT_STRING_MAP.put(MetaType.Long, "0000000000000000000000000000000000000000");
    DEFAULT_FORMAT_STRING_MAP.put(MetaType.Date, "yyyyMMdd-kk:mm");
    DEFAULT_FORMAT_STRING_MAP.put(MetaType.Float, "00000000000000000000.00");
    DEFAULT_FORMAT_STRING_MAP.put(MetaType.Double, "0000000000000000000000000000000000000000.00");
   
    CLASS_METATYPE_MAP.put(String.class, MetaType.String);
    CLASS_METATYPE_MAP.put(int.class, MetaType.Integer);
    CLASS_METATYPE_MAP.put(Integer.class, MetaType.Integer);
    CLASS_METATYPE_MAP.put(short.class, MetaType.Short);
    CLASS_METATYPE_MAP.put(Short.class, MetaType.Short);
    CLASS_METATYPE_MAP.put(long.class, MetaType.Long);
    CLASS_METATYPE_MAP.put(Long.class, MetaType.Long);
    CLASS_METATYPE_MAP.put(float.class, MetaType.Float);
    CLASS_METATYPE_MAP.put(Float.class, MetaType.Float);
    CLASS_METATYPE_MAP.put(double.class, MetaType.Double);
    CLASS_METATYPE_MAP.put(Double.class, MetaType.Double);
    CLASS_METATYPE_MAP.put(char.class, MetaType.Char);
    CLASS_METATYPE_MAP.put(Character.class, MetaType.Char);
    CLASS_METATYPE_MAP.put(boolean.class, MetaType.Boolean);
    CLASS_METATYPE_MAP.put(Boolean.class, MetaType.Boolean);
    CLASS_METATYPE_MAP.put(Date.class, MetaType.Date);
   
    INDEX_VAL_MAP.put("NO",Index.NO);
    INDEX_VAL_MAP.put("ANALYZED",Index.ANALYZED);
    INDEX_VAL_MAP.put("TOKENIZED",Index.ANALYZED);
    INDEX_VAL_MAP.put("NOT_ANALYZED",Index.NOT_ANALYZED);
    INDEX_VAL_MAP.put("UN_TOKENIZED",Index.NOT_ANALYZED);
    INDEX_VAL_MAP.put("NOT_ANALYZED_NO_NORMS",Index.NOT_ANALYZED_NO_NORMS);
    INDEX_VAL_MAP.put("NO_NORMS",Index.NOT_ANALYZED_NO_NORMS);
    INDEX_VAL_MAP.put("NOT_ANALYZED_NO_NORMS",Index.NOT_ANALYZED_NO_NORMS);
    INDEX_VAL_MAP.put("ANALYZED_NO_NORMS",Index.ANALYZED_NO_NORMS);
   
    STORE_VAL_MAP.put("NO",Store.NO);
    STORE_VAL_MAP.put("YES",Store.YES);
   
    TV_VAL_MAP.put("NO",TermVector.NO);
    TV_VAL_MAP.put("YES",TermVector.YES);
    TV_VAL_MAP.put("WITH_POSITIONS",TermVector.WITH_POSITIONS);
    TV_VAL_MAP.put("WITH_OFFSETS",TermVector.WITH_OFFSETS);
    TV_VAL_MAP.put("WITH_POSITIONS_OFFSETS",TermVector.WITH_POSITIONS_OFFSETS);
  }
 
  public static <T> TermListFactory<T> getTermListFactory(Class<T> cls){
    MetaType metaType = CLASS_METATYPE_MAP.get(cls);
    if (metaType == null){
      throw new IllegalArgumentException("unsupported class: "+cls.getName());
    }
    return new PredefinedTermListFactory<T>(cls,DEFAULT_FORMAT_STRING_MAP.get(metaType));
  }
 
 
  public static class IndexSpec{
    public Store store;
    public Index index;
    public TermVector tv;
    Field fld;
  }
 
  static class MetaFormatSpec{
    Format formatter;
    Field fld;
  }
 
  private Class<V> _cls;

  final Map<String,IndexSpec> _textIndexingSpecMap;
  final Map<String,MetaFormatSpec> _metaFormatSpecMap;
 
  Field _uidField;
  Method _deleteChecker;
  Method _skipChecker;
 
  public DefaultSenseiInterpreter(Class<V> cls){
    _cls = cls;
    _metaFormatSpecMap = new HashMap<String,MetaFormatSpec>();
    _textIndexingSpecMap = new HashMap<String,IndexSpec>();
    _uidField = null;
    Field[] fields = cls.getDeclaredFields();
    for (Field f : fields){
      if (f.isAnnotationPresent(Uid.class)){
      if (_uidField != null){
        throw new IllegalStateException("multiple uids defined in class: "+cls);
      }
      else{
      Class fieldType = f.getType();
      if (fieldType.isPrimitive()){
        if (int.class.equals(fieldType) || short.class.equals(fieldType) || long.class.equals(fieldType)){
          _uidField = f;
          _uidField.setAccessible(true);
        }
      }
      if (_uidField == null){
        throw new IllegalStateException("uid field's type must be one of long, int or short");
      }
      }
      }
      else if (f.isAnnotationPresent(Text.class)){
        f.setAccessible(true);
        Text textAnnotation = f.getAnnotation(Text.class);
        String name=textAnnotation.name();
      if ("".equals(name)){
      name = f.getName();
      }
     
      Index idx = INDEX_VAL_MAP.get(textAnnotation.index());
      Store store = STORE_VAL_MAP.get(textAnnotation.store());
      TermVector tv = TV_VAL_MAP.get(textAnnotation.termVector());
   
      if (idx==null || store==null || tv==null){
      throw new RuntimeException("Invalid indexing parameter specification");
      }
      IndexSpec indexingSpec = new IndexSpec();
      indexingSpec.store = store;
      indexingSpec.index = idx;
      indexingSpec.tv = tv;
      indexingSpec.fld = f;
      _textIndexingSpecMap.put(name, indexingSpec);
      }
      else if (f.isAnnotationPresent(StoredValue.class)){
          f.setAccessible(true);
          StoredValue storeAnnotation = f.getAnnotation(StoredValue.class);
          String name=storeAnnotation.name();
        if ("".equals(name)){
        name = f.getName();
        }
        IndexSpec indexingSpec = new IndexSpec();
        indexingSpec.store = Store.YES;
        indexingSpec.index = Index.NO;
        indexingSpec.tv = TermVector.NO;
        indexingSpec.fld = f;
        _textIndexingSpecMap.put(name, indexingSpec);
    }
      else if (f.isAnnotationPresent(Meta.class)){
        f.setAccessible(true);
        Meta metaAnnotation = f.getAnnotation(Meta.class);
        String name=metaAnnotation.name();
        if ("".equals(name)){
        name = f.getName();
        }
        MetaType metaType = metaAnnotation.type();
        if (MetaType.Auto.equals(metaType)){
          Class typeClass = f.getType();
          if (Collection.class.isAssignableFrom(typeClass)){
            metaType = MetaType.String;
          }
          else{
            metaType = CLASS_METATYPE_MAP.get(typeClass);
            if (metaType==null){
            metaType = MetaType.String;
            }
          }
        }
        String defaultFormatString = DEFAULT_FORMAT_STRING_MAP.get(metaType);
        String formatString = metaAnnotation.format();
        if ("".equals(formatString)){
          formatString = defaultFormatString;
        }
       
        MetaFormatSpec formatSpec = new MetaFormatSpec();
        _metaFormatSpecMap.put(name, formatSpec);
        formatSpec.fld = f;
        if (defaultFormatString!=null){
          if (MetaType.Date == metaType){
          formatSpec.formatter = new SimpleDateFormat(formatString);
          }
          else{
          formatSpec.formatter = new DecimalFormat(formatString, new DecimalFormatSymbols(Locale.US));
          }
        }
      }
    }
   
    Method[] methods = cls.getDeclaredMethods();
    for (Method method : methods){
      if (method.isAnnotationPresent(DeleteChecker.class)){
      if (_deleteChecker==null){
        method.setAccessible(true);
        _deleteChecker = method;
      }
      else{
        throw new IllegalStateException("more than 1 delete checker defined in class: "+cls);
      }
      }
      else if (method.isAnnotationPresent(SkipChecker.class)){
      if (_skipChecker==null){
        method.setAccessible(true);
        _skipChecker = method;
      }
      else{
        throw new IllegalStateException("more than 1 skip checker defined in class: "+cls);
     
      }
    }
   
      if (_uidField == null){
        throw new IllegalStateException(cls + " does not have uid defined");
      }
  }
 
  @Override
  public String toString(){
    StringBuilder buf = new StringBuilder();
    buf.append("data class name: ").append(_cls.getName());
    buf.append("\n_uid field: ").append(_uidField.getName());
    buf.append("\ndelete checker: ").append(_deleteChecker==null?"none":_deleteChecker.getName());
    buf.append("\nskip checker: ").append(_skipChecker==null?"none":_skipChecker.getName());
    buf.append("\ntext fields: ");
    if (_textIndexingSpecMap.size()==0){
      buf.append("none");
    }
    else{
      boolean first = true;
      Set<String> tfNames = _textIndexingSpecMap.keySet();
      for (String name : tfNames){
        if (!first){
          buf.append(",");
        }
        else{
          first=false;
        }
        buf.append(name);
      }
    }
    buf.append("\nmeta fields: ");
    if (_metaFormatSpecMap.size()==0){
      buf.append("none");
    }
    else{
      boolean first = true;
      Set<String> tfNames = _metaFormatSpecMap.keySet();
      for (String tf : tfNames){
        if (!first){
          buf.append(",");
        }
        else{
          first=false;
        }
        buf.append(tf);
      }
    }
    return buf.toString();
  }
 
  @Override
  public ZoieIndexable convertAndInterpret(V obj) {
    return new DefaultSenseiZoieIndexable<V>(obj,this);
  }
 
}
TOP

Related Classes of com.senseidb.indexing.DefaultSenseiInterpreter$MetaFormatSpec

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.