com.aurel.track.lucene.LuceneUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.aurel.track.lucene.LuceneUtil.java

Source

/**
 * Genji Scrum Tool and Issue Tracker
 * Copyright (C) 2015 Steinbeis GmbH & Co. KG Task Management Solutions
    
 * <a href="http://www.trackplus.com">Genji Scrum Tool</a>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

/* $Id:$ */

package com.aurel.track.lucene;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import javax.servlet.ServletContext;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.DateTools;
import org.apache.lucene.document.Field;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.SimpleFSDirectory;

import com.aurel.track.beans.TListTypeBean;
import com.aurel.track.beans.TSiteBean;
import com.aurel.track.dao.DAOFactory;
import com.aurel.track.dao.SiteDAO;
import com.aurel.track.fieldType.runtime.base.LookupContainer;
import com.aurel.track.fieldType.types.FieldTypeManager;
import com.aurel.track.util.LabelValueBean;
import com.aurel.track.util.PluginUtils;

/**
 *
 * @author  Tamas Ruff
 * @version $Revision: 1799 $
 *
 */
public class LuceneUtil {

    private static final Logger LOGGER = LogManager.getLogger(LuceneUtil.class);
    private static SiteDAO siteDAO = DAOFactory.getFactory().getSiteDAO();
    //the separator which should be entered by the end-user to split the parts of a composite value
    //for example pc:p1#c11 means the field with name pc (parent child) 
    //and first part (parent value) is p1 and second part (child value) is c11
    //if the separator string is part of the string value it should be escaped with \
    //Ex. pc:p\#1#c\#11 means search for p#1 as parent value and c#11 as child value 
    public static String COMPOSITE_FIELDVALUE_SEPARATOR = "#";
    //the temporary replacement for field value separator to execute the split correctly
    public static String COMPOSITE_FIELDVALUE_SEPARATOR_ESCAPING_REPLACEMENT = "hopefully_not_used_string_if_used_bad_luck";

    //the separator of the composite part field for synthetize the lucene field name
    private static String COMPOSITE_FIELDNAME_SEPARATOR = "#";

    //the symbolic boolean values stored in the index because "Y" and "N" does not work (it is filtered out by the analyzer?)
    public static String BOOLEAN_YES = "yesnotfilteredoutbyanalyzer";
    public static String BOOLEAN_NO = "nonotfilteredoutbyanalyzer";

    public static String HIGHLIGHTER_FIELD = "Highlighter";

    /**
     * Lucene index identifier constants
     *
     */
    public static interface INDEXES {
        public static final int WORKITEM_INDEX = 1;
        public static final int NOT_LOCALIZED_LIST_INDEX = 2;
        public static final int LOCALIZED_LIST_INDEX = 3;
        public static final int ATTACHMENT_INDEX = 4;
        public static final int EXTERNAL_LOOKUP_WRITER = 5;
        public static final int LINK_INDEX = 6;
        public static final int EXPENSE_INDEX = 7;
        public static final int BUDGET_PLAN_INDEX = 8;
    }

    /**
     * Config parameters for lucene
     *
     */
    public static interface LUCENESETTINGS {
        public static final String USELUCENE = "useLucene";
        public static final String INDEXATTACHMENTS = "indexAttachments";
        public static final String ANALYZER = "analizer";
        public static final String INDEXPATH = "indexPath";
        public static final String REINDEXONSTARTUP = "reindexOnStartup";
    }

    /**
     * Constants to avoid referencing lucene store constants from the fieldType classes 
     * @author Tamas Ruff
     *
     */
    public static interface STORE {
        public static final int YES = 1;
        public static final int NO = 0;
    }

    /**
     * Constants to avoid referencing lucene tokenize constants from the fieldType classes 
     * @author Tamas Ruff
     *
     */
    public static interface TOKENIZE {
        public static final int YES = 1;
        public static final int NO = 0;
    }

    /**
     * Helper method to transform the symbolic store constants to lucene store constants  
     * @param store
     * @return
     */
    public static Field.Store getLuceneStore(int store) {
        switch (store) {
        case STORE.YES:
            return Field.Store.YES;
        case STORE.NO:
            return Field.Store.NO;
        default:
            return Field.Store.NO;
        }
    }

    /**
     * Helper method to transform the symbolic tokenized constants to lucene tokenized constants  
     * @param tokenized
     * @return
     */

    /**
     * Lookup entity types defined
     *
     */
    public static interface LOOKUPENTITYTYPES {
        //not stored (calculated) value
        public static int NOSTORE = 0;
        //direct values
        public static int DIRECTTEXT = 1;
        public static int DIRECTDATE = 2;
        public static int DIRECTINTEGER = 3;
        public static int DIRECTDOUBLE = 4;
        public static int DIRECTBOOLEAN = 5;
        //localized lookup types
        public static int LISTTYPE = 10;
        public static int PRIORITY = 11;
        public static int SEVERITY = 12;
        public static int STATE = 13;
        //not localized lookup types
        public static int PROJECT = 20;
        //public static int CLASS = 22;
        public static int RELEASE = 23;
        public static int PERSONNAME = 24;
        public static int CUSTOMOPTION = 25;
        //composite values
        public static int COMPOSITE = 30;

        public static int EXTERNALID = 40;
    }

    /**
     * Preprocess types defined
     * Depending on the preprocess type different preprocessing is needed
     */
    public static interface PREPROCESSTYPES {
        //stored directly, no preprocessing of the user entered values needed
        public static int DIRECT = 1;
        //stored a date directly, preprocessing needed to format the date to the format used by lucene (YYYYMMDD) 
        public static int DATE = 2;
        //localized boolen strings: YES/NO JA/NEIN
        public static int BOOLEAN_LOOKUP = 3;
        //stored in the not localized lookup index, 
        //preprocessing needed to replace the user entered values with the matching lookup IDs 
        public static int NOT_LOCALIZED_LOOKUP = 4;
        //stored in the localized lookup index, 
        //preprocessing needed to replace the user entered values with the matching lookup IDs
        public static int LOCALIZED_LOOKUP = 5;
        //preprocessing needed to replace the user entered (#-divided) 
        //composite values with the matching parts
        public static int COMPOSITE_LOOKUP = 6;
        //preprocessing needed to replace the user entered values with the matching external lookup IDs
        public static int EXTERNAL_LOOKUP = 7;
        //no store
        public static int NOSTORE = 8;
    }

    /**
     * Get the preprocess type needed by lookupEntityType
     * Determines which preprocessing is needed for a lookupEntityType
     * @param lookupEntityType
     * @return
     */
    public static int getPreprocessType(int lookupEntityType) {
        switch (lookupEntityType) {
        case LOOKUPENTITYTYPES.DIRECTTEXT:
        case LOOKUPENTITYTYPES.DIRECTINTEGER:
        case LOOKUPENTITYTYPES.DIRECTDOUBLE:
            return PREPROCESSTYPES.DIRECT;
        case LOOKUPENTITYTYPES.DIRECTDATE:
            return PREPROCESSTYPES.DATE;
        case LOOKUPENTITYTYPES.DIRECTBOOLEAN:
            return PREPROCESSTYPES.BOOLEAN_LOOKUP;
        case LOOKUPENTITYTYPES.LISTTYPE:
        case LOOKUPENTITYTYPES.PRIORITY:
        case LOOKUPENTITYTYPES.SEVERITY:
        case LOOKUPENTITYTYPES.STATE:
        case LOOKUPENTITYTYPES.CUSTOMOPTION:
            return PREPROCESSTYPES.LOCALIZED_LOOKUP;
        case LOOKUPENTITYTYPES.PROJECT:
        case LOOKUPENTITYTYPES.PERSONNAME:
        case LOOKUPENTITYTYPES.RELEASE:
            return PREPROCESSTYPES.NOT_LOCALIZED_LOOKUP;
        case LOOKUPENTITYTYPES.COMPOSITE:
            return PREPROCESSTYPES.COMPOSITE_LOOKUP;
        case LOOKUPENTITYTYPES.EXTERNALID:
            return PREPROCESSTYPES.EXTERNAL_LOOKUP;
        case LOOKUPENTITYTYPES.NOSTORE:
            return PREPROCESSTYPES.NOSTORE;
        }
        return PREPROCESSTYPES.DIRECT;
    }

    /**
     * The hardcoded name of the attachment field
     * TODO make it configurable (how?)
     */
    public static String ATTACHMENT = "Attachment";
    /**
     * Link descriptions
     */
    public static String LINK = "Link";
    /**
     * Expense subject or description
     */
    public static String EXPENSE = "Expense";
    /**
     * Plan description
     */
    public static String BUDGET_PLAN = "BudgetPlan";

    /**
     * Gets the name of the field by fieldID
     */
    public static String getFieldName(int fieldID) {
        return FieldTypeManager.getInstance().getFieldBean(Integer.valueOf(fieldID)).getName();
    }

    /**
     * the java Properties file accepts no spaces in the key
     * we replace all spaces with underscore  
     * @param fieldName
     * @return
     */
    public static String normalizeFieldName(String fieldName) {
        if (fieldName == null) {
            fieldName = "";
        }
        return fieldName.trim().replaceAll(" ", "_");
    }

    /**
     * the java Properties file accepts no spaces in the key
     * we replace all spaces with underscore  
     * @param fieldName
     * @param parameterCode
     * @return
     */
    public static String synthetizeCompositePartFieldName(String fieldName, Integer parameterCode) {
        return fieldName + COMPOSITE_FIELDNAME_SEPARATOR + parameterCode;
    }

    /**
     * lucene field names for external lookup types
     * the labels of external lookups are defined in the corresponding field type
     *
     */
    public static class EXTERNAL_INDEX_FIELDS {
        public static String FIELDID = "FieldID";
        //used only by delete, because it works only with Term (BooleanQuery not possible)
        public static String COMBINEDKEY = "CombinedKey";
        public static String OBJECTID = "ObjectID";
    }

    /**
     * lucene field names for the not localized lookup types
     *
     */
    public static class LIST_INDEX_FIELDS_NOT_LOCALIZED {
        public static String LABEL = "Label";
        public static String VALUE = "Value";
        public static String TYPE = "Type";
        //used only by delete, because it works only with Term (BooleanQuery not possible)
        public static String COMBINEDKEY = "CombinedKey";
    }

    /**
     * lucene field names for the localized lookup types
     *
     */
    public static class LIST_INDEX_FIELDS_LOCALIZED {
        //there is a field name for each locale found but these are not previously known
        //they look like en_US or de
        //the key from the lookup table 
        public static String VALUE = "Value";
        //the not localized label from the lookup table
        public static String LABEL = "Label";
        //normally same as Label (could differ by initializing the db: severity 'major' in db, 'serious' in defualt localized)
        public static String DEFAULT_LOCALIZED = "DefaultLocalized";
        //the localized entity type
        public static String TYPE = "Type";
        //used only by delete, because it works only with Term (BooleanQuery not possible)
        public static String COMBINEDKEY = "CombinedKey";
    }

    /**
     * lucene field names for the not localized lookup types
     *
     */
    public static class ATTACHMENT_INDEX_FIELDS {
        public static String ATTACHMENTID = "AttachmentID";
        public static String ISSUENO = "IssueNo";
        //original name of the file
        public static String ORIGINALNAME = "OriginalName";
        //the real name of the file
        public static String REALNAME = "RealName";
        //public static String COMBINEDKEY = "CombinedKey";
        //the content of the file
        public static String CONTENT = "Content";
        //the user entered description for an attachment
        public static String DESCRIPTION = "Description";
    }

    /**
     * lucene field names for the links
     *
     */
    public static class LINK_INDEX_FIELDS {
        public static String LINKID = "LinkID";
        public static String LINKPRED = "LinkPred";
        public static String LINKSUCC = "LinkSucc";
        public static String BIDIRECTIONAL = "Bidirectional";
        //the user entered description for link
        public static String DESCRIPTION = "Description";
    }

    /**
     * lucene field names for the expenses
     *
     */
    public static class EXPENSE_INDEX_FIELDS {
        public static String EXPENSEID = "ExpenseID";
        public static String WORKITEMID = "WorkitemID";
        public static String SUBJECT = "Subject";
        public static String DESCRIPTION = "Description";
    }

    /**
     * lucene field names for the plans
     *
     */
    public static class BUDGET_INDEX_FIELDS {
        public static String PLANID = "PlanID";
        public static String WORKITEMID = "WorkitemID";
        public static String DESCRIPTION = "Description";
        public static String BUDGET_TYPE = "BudgetType";
    }

    /**
     * name of the application context attribute storing the LuceneIndexer
     */
    //public static String LUCENEINDEXER = "LUCENEINDEXER";

    /**
     * lucene settings 
     */
    private static List<LabelValueBean> foundAnalysers = new ArrayList<LabelValueBean>();
    private static Analyzer analyzer;
    private static String path;
    private static boolean useLucene;
    private static boolean indexAttachments;
    public static boolean reindexOnStartup;

    public static String LUCENEMAINDIR = "LuceneIndexes";
    private static String WORKITEM_DIRECTORY = "WorkItemIndex";
    private static String NOTLOCALIZED_LOOKUPFIELDS_DIRECTORY = "NotLocalizedLookupIndex";
    private static String LOCALIZED_LOOKUPFIELDS_DIRECTORY = "LocalizedLookupIndex";
    private static String ATTACHMENT_DIRECTORY = "AttachmentIndex";
    private static String EXTERNAL_LOOKUPFIELDS_DIRECTORY = "ExternalLookupIndex";
    private static String LINK_DIRECTORY = "LinkIndex";
    private static String EXPENSE_DIRECTORY = "ExpenseIndex";
    private static String BUDGET_PLAN_DIRECTORY = "BudgetPlanIndex";

    /**
     * @return Returns the analyzer.
     */
    public static Analyzer getAnalyzer() {
        return analyzer;
    }

    /**
     * @param analyzer The analyzer to set.
     */
    public static void setAnalyzer(Analyzer analyzer) {
        LuceneUtil.analyzer = analyzer;
    }

    /**
     * @return Returns the foundAnalysers.
     */
    public static List<LabelValueBean> getFoundAnalysers() {
        return foundAnalysers;
    }

    /**
     * @param foundAnalysers The foundAnalysers to set.
     */
    public static void setFoundAnalysers(List<LabelValueBean> foundAnalysers) {
        LuceneUtil.foundAnalysers = foundAnalysers;
    }

    /**
     * @return Returns the indexAttachments.
     */
    public static boolean isIndexAttachments() {
        return indexAttachments;
    }

    /**
     * @param indexAttachments The indexAttachments to set.
     */
    public static void setIndexAttachments(boolean indexAttachments) {
        LuceneUtil.indexAttachments = indexAttachments;
    }

    /**
     * @return Returns the path.
     */
    public static String getPath() {
        return path;
    }

    /**
     * @param path The path to set.
     */
    public static void setPath(String path) {
        LuceneUtil.path = path;
    }

    /**
     * @return Returns the reindexOnStartup.
     */
    public static boolean isReindexOnStartup() {
        return reindexOnStartup;
    }

    /**
     * @param reindexOnStartup The reindexOnStartup to set.
     */
    public static void setReindexOnStartup(boolean reindexOnStartup) {
        LuceneUtil.reindexOnStartup = reindexOnStartup;
    }

    /**
     * @return Returns the useLucene.
     */
    public static boolean isUseLucene() {
        return useLucene;
    }

    /**
     * @param useLucene The useLucene to set.
     */
    public static void setUseLucene(boolean useLucene) {
        LuceneUtil.useLucene = useLucene;
    }

    /**
     * creation of the combined field value based on the field value and field type
     * @param value
     * @param type
     * @return
     */
    public static String getCombinedKeyValue(String value, String type) {
        return value + "|" + type;
    }

    /**
     * Gets the context path of the application
     * @return
     */
    public static String getContexPath() {
        URL url = null;
        File file;
        //get the application context path
        url = LuceneUtil.class.getResource("/../..");
        if (url == null) {
            return null;
        }
        if (url.getPath() != null) {
            file = new File(url.getPath());
            if (file.exists()) {
                return stripTrailingPathSeparator(url.getPath());
            }
        }
        //see Bug ID:  4466485 (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4466485) 
        URI uri = null;
        try {
            uri = new URI(url.toString());
        } catch (URISyntaxException e) {
            LOGGER.error("Getting the lucene index root URI from URL failed with " + e.getMessage());
            LOGGER.debug(ExceptionUtils.getStackTrace(e));
        }
        if (uri == null) {
            return null;
        }
        //sometimes it is enough
        if (uri.getPath() != null) {
            file = new File(uri.getPath());
            if (file.exists()) {
                return stripTrailingPathSeparator(uri.getPath());
            }
        }

        try {
            url = uri.toURL();
        } catch (MalformedURLException e) {
        }
        if (url != null && url.getPath() != null) {
            file = new File(url.getPath());
            if (file.exists()) {
                return stripTrailingPathSeparator(url.getPath());
            }
        }
        return "";
    }

    public static String getDirectoryString(int index) {
        String indexDir;
        switch (index) {
        case INDEXES.WORKITEM_INDEX:
            indexDir = WORKITEM_DIRECTORY;
            break;
        case INDEXES.NOT_LOCALIZED_LIST_INDEX:
            indexDir = NOTLOCALIZED_LOOKUPFIELDS_DIRECTORY;
            break;
        case INDEXES.LOCALIZED_LIST_INDEX:
            indexDir = LOCALIZED_LOOKUPFIELDS_DIRECTORY;
            break;
        case INDEXES.ATTACHMENT_INDEX:
            indexDir = ATTACHMENT_DIRECTORY;
            break;
        case INDEXES.EXTERNAL_LOOKUP_WRITER:
            indexDir = EXTERNAL_LOOKUPFIELDS_DIRECTORY;
            break;
        case INDEXES.LINK_INDEX:
            indexDir = LINK_DIRECTORY;
            break;
        case INDEXES.EXPENSE_INDEX:
            indexDir = EXPENSE_DIRECTORY;
            break;
        case INDEXES.BUDGET_PLAN_INDEX:
            indexDir = BUDGET_PLAN_DIRECTORY;
            break;
        default:
            indexDir = WORKITEM_DIRECTORY;
            break;
        }
        return indexDir;
    }

    /**
     * Gets the directory for an index based on the index number
     * @param index
     * @return
     */
    public static Directory getIndexDirectory(int index) {
        String indexDir = getDirectoryString(index);
        String filePath = stripTrailingPathSeparator(LuceneUtil.getPath());
        if (filePath == null) {
            filePath = "";
        }
        //filePath = filePath.replace('\\', '/');
        String indexPath;
        if ("".equals(filePath.trim())) {
            //relative path
            indexPath = getContexPath() + "/" + LuceneUtil.LUCENEMAINDIR + "/" + indexDir;
        } else {
            //absolute path
            indexPath = filePath + "/" + LuceneUtil.LUCENEMAINDIR + "/" + indexDir;
        }
        File directoryFile = new File(indexPath);
        boolean created;
        //if not exists create a file
        if (!directoryFile.exists()) {
            created = directoryFile.mkdirs();
            if (!created) {
                LOGGER.error("Can't create the directory " + filePath);
            }
        } else {
            //if exists with this name but is not a directory
            //the file should be deleted manually
            if (!directoryFile.isDirectory()) {
                LOGGER.error("Can't create the directory because a file with this name exists " + filePath);
            }
        }
        Directory directory = null;
        try {
            directory = new SimpleFSDirectory(directoryFile.toPath());
        } catch (IOException e) {
            LOGGER.error("Can't create a SimpleFSDirectory because a file with this name exists " + filePath);
        }
        return directory;
    }

    /**
     * strip the trailing pathseparator if exists
     * @param path
     * @return
     */
    private static String stripTrailingPathSeparator(String path) {
        if (path == null) {
            return "";
        }
        if (path.endsWith("/")) {
            path = path.substring(0, path.length() - 1);
        }
        return path;
    }

    /**
     * get the list of analyzers found in the system
     * @param servletContext
     * @return
     */
    public static List<LabelValueBean> getAnalyzersList(ServletContext servletContext) {
        Set<String> foundAnalyzersSet = new TreeSet<String>();
        List<LabelValueBean> analyzersBeans = new ArrayList<LabelValueBean>();
        //we specify it explicitly because in the worst case we should have at least this analyzer
        //but may be we should not specify it, because nobody guarantees that this will be included 
        //in the future lucene implementations also, and then the lucene.jar could not be changed 
        foundAnalyzersSet.add(StandardAnalyzer.class.getName());
        //we search just in jars
        //(in the classes folder not, because it is not probable that a new analyzer will be written inside the Genji)
        foundAnalyzersSet.addAll(PluginUtils.getAnalyzersFromJars(servletContext));

        //create the analyzer beans to be shown to the user
        for (String className : foundAnalyzersSet) {
            int nameIndex = className.lastIndexOf(".");
            analyzersBeans.add(new LabelValueBean(className.substring(nameIndex + 1), className));
        }
        return analyzersBeans;
    }

    /**
     * Initializes the preferences field of a TSite object with default lucene parameters 
     * It is used the first time the application is launched before the new TSite object is saved 
     *
     */
    public static void initLuceneParameters() {
        TSiteBean siteBean = siteDAO.load1();
        //use lucene by default
        String useLuceneStr = siteBean.getUseLucene();
        if (useLuceneStr == null || "".equals(useLuceneStr.trim())) {
            useLuceneStr = "true";
            Map<Integer, Object> siteBeanValues = new HashMap<Integer, Object>();
            siteBeanValues.put(TSiteBean.COLUMNIDENTIFIERS.USELUCENE, useLuceneStr);
            siteDAO.loadAndSaveSynchronized(siteBeanValues);
        }
        //index attachments by default
        String indexAttachmentsStr = siteBean.getIndexAttachments();
        if (indexAttachmentsStr == null || "".equals(indexAttachmentsStr.trim())) {
            indexAttachmentsStr = "true";
            Map<Integer, Object> siteBeanValues = new HashMap<Integer, Object>();
            siteBeanValues.put(TSiteBean.COLUMNIDENTIFIERS.INDEXATTACHMENTS, indexAttachmentsStr);
            siteDAO.loadAndSaveSynchronized(siteBeanValues);
        }
        //do not reindex by default
        String reindexOnStartup = siteBean.getReindexOnStartup();
        if (reindexOnStartup == null || "".equals(reindexOnStartup.trim())) {
            reindexOnStartup = "false";
            Map<Integer, Object> siteBeanValues = new HashMap<Integer, Object>();
            siteBeanValues.put(TSiteBean.COLUMNIDENTIFIERS.REINDEXONSTARTUP, reindexOnStartup);
            siteDAO.loadAndSaveSynchronized(siteBeanValues);
        }
        //set the standard analyzer by default
        String analyzer = siteBean.getAnalyzer();
        if (analyzer == null || "".equals(analyzer.trim())) {
            analyzer = StandardAnalyzer.class.getName();
            Map<Integer, Object> siteBeanValues = new HashMap<Integer, Object>();
            siteBeanValues.put(TSiteBean.COLUMNIDENTIFIERS.ANALYZER, analyzer);
            siteDAO.loadAndSaveSynchronized(siteBeanValues);
        }
    }

    /**
     * Initializes the lucene parameters from the the database 
     * (table TSite, field Preferences)  
     * @param site
     */
    public static void configLuceneParameters(TSiteBean site) {
        //get useLucene 
        String useLuceneStr = site.getUseLucene();
        if (useLuceneStr == null || "".equals(useLuceneStr.trim())) {
            useLuceneStr = "false";
        }
        boolean useLucene = Boolean.valueOf(useLuceneStr).booleanValue();
        LuceneUtil.setUseLucene(useLucene);
        //get indexAttachments
        String indexAttachmentsStr = site.getIndexAttachments();
        if (indexAttachmentsStr == null || "".equals(indexAttachmentsStr.trim())) {
            indexAttachmentsStr = "false";
        }
        boolean indexAttachments = Boolean.valueOf(indexAttachmentsStr).booleanValue();
        LuceneUtil.setIndexAttachments(indexAttachments);
        //get reindexOnStartup
        String reindexOnStartupStr = site.getReindexOnStartup();
        if (reindexOnStartupStr == null || "".equals(reindexOnStartupStr.trim())) {
            reindexOnStartupStr = "false";
        }
        boolean reindexOnStartup = Boolean.valueOf(reindexOnStartupStr).booleanValue();
        LuceneUtil.setReindexOnStartup(reindexOnStartup);
        //get analyzerStr
        String analyzerStr = site.getAnalyzer();
        if (analyzerStr == null || "".equals(analyzerStr.trim())) {
            analyzerStr = StandardAnalyzer.class.getName();
        }
        //get the analyzer class
        Class analyzerClass = null;
        try {
            analyzerClass = Class.forName(analyzerStr.trim());
        } catch (ClassNotFoundException e) {
            LOGGER.error("Analyzer class not found. Fall back to StandardAnalyzer." + e.getMessage());
            LOGGER.debug(ExceptionUtils.getStackTrace(e));
        }
        if (analyzerClass != null) {
            Class partypes[] = new Class[0];
            Constructor ct = null;
            try {
                ct = analyzerClass.getConstructor(partypes);
            } catch (Exception e) {
                LOGGER.info(
                        "Getting the Version based constructor for " + analyzerStr.trim() + " failed with " + e);
            }
            if (ct != null) {
                //Object arglist[] = new Object[1];
                //arglist[0] = LuceneUtil.VERSION;
                try {
                    analyzer = (Analyzer) ct.newInstance(/*arglist*/);
                } catch (Exception e) {
                    LOGGER.error("Instanciationg the Version based constructor for " + analyzerStr.trim()
                            + " failed with " + e);
                }
            }
            //then try it with implicit constructor (for earlier lucene versions)
            if (analyzer == null) {
                try {
                    analyzer = (Analyzer) analyzerClass.newInstance();
                    LOGGER.info("Instantiating the Analyzer through default constructor");
                } catch (Exception e) {
                    LOGGER.error(
                            "Instantiating the Analyzer through default constructor failed with " + e.getMessage());
                    LOGGER.debug(ExceptionUtils.getStackTrace(e));
                }
            }
        }
        if (analyzer == null) {
            LOGGER.warn("Fall back on creating a StandardAnalyzer instance");
            analyzer = new StandardAnalyzer();
        }
        LuceneUtil.setAnalyzer(analyzer);
        //get indexPath
        String indexPath = site.getIndexPath();
        if (indexPath == null) {
            indexPath = "";
        }
        LuceneUtil.setPath(indexPath);
    }

    /**
     * Typically the value itself converted to string
     * But there are some exceptions where the toString()
     * doesn't work as expected. 
     * It should be implemented
     * specific to the lucene requirement to be indexable
     * set the date according to offset from the GMT
     * see http://www.gossamer-threads.com/lists/lucene/java-user/39303?search_string=DateTools;#39303
     * @param value
     * @return
     */
    public static String getLuceneDateValue(Object value) {
        Calendar cal = new GregorianCalendar();
        int minutesOffset = (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / (60 * 1000);
        if (value != null) {
            Date dateValue = null;
            try {
                dateValue = (Date) value;
            } catch (Exception e) {
                LOGGER.error("The type of the lucene value is " + value.getClass().getName()
                        + ". Casting it to Date failed with " + e.getMessage());
                LOGGER.debug(ExceptionUtils.getStackTrace(e));
            }
            if (dateValue != null) {
                cal.setTime(dateValue);
                cal.add(Calendar.MINUTE, minutesOffset);
                return DateTools.dateToString(cal.getTime(), DateTools.Resolution.DAY);
            }
        }
        return null;
    }

    /**
     * Whether to add the highlighted field for this item type
     * @param itemTypeID
     * @return
     */
    public static boolean isHighlightedItemType(Integer itemTypeID) {
        boolean withHighlighter = false;
        if (itemTypeID != null) {
            TListTypeBean itemTypeBean = LookupContainer.getItemTypeBean(itemTypeID);
            if (itemTypeBean != null) {
                Integer typeFlag = itemTypeBean.getTypeflag();
                if (typeFlag != null && (typeFlag.equals(TListTypeBean.TYPEFLAGS.DOCUMENT)
                        || typeFlag.equals(TListTypeBean.TYPEFLAGS.DOCUMENT_SECTION))) {
                    withHighlighter = true;
                }
            }
        }
        return withHighlighter;
    }

}