/*
* Copyright 2010 The Apache Software Foundation
*
* 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 com.bizosys.hsearch.dictionary;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import com.bizosys.oneline.SystemFault;
import com.bizosys.oneline.conf.Configuration;
import com.bizosys.oneline.services.Request;
import com.bizosys.oneline.services.Response;
import com.bizosys.oneline.services.Service;
import com.bizosys.oneline.services.ServiceMetaData;
import com.bizosys.oneline.services.scheduler.ExpressionBuilder;
import com.bizosys.oneline.services.scheduler.ScheduleTask;
import com.bizosys.oneline.util.StringUtils;
/**
* This is the Facade for the dictionry service. It's responsible for
* initializing dictionry service as well as serving clients. This is the
* single entry point for outside clients to perform dictionry operations.
* @author karan
*
*/
public class DictionaryManager implements Service{
/**
* Dictionry Refresh Task. In a multi machine environment, this keeps
* loading the dictionry to in memory locally in interval to ensure
* fuzzy and regex searches.
*/
ScheduleTask scheduledRefresh = null;
/**
* The dictionry instance
*/
Dictionary dict = null;
/**
* Singleton
*/
private static DictionaryManager instance = null;
/**
* Constructor is private. This ensures singleton
* @return DictionaryManager
* @throws SystemFault
*/
public static final DictionaryManager getInstance() throws SystemFault {
if ( null == instance) throw new SystemFault(
"DisctionaryManager is not initialized");
return instance;
}
/**
* Default Constructor
* Needs to be initialized only once. Done by ServiceFacade.
*/
public DictionaryManager() {
instance = this;
}
/**
* Service name - Dictionarymanager
*/
public String getName() {
return "Dictionarymanager";
}
/**
* Launches dictionry refresh task and initializes the dictionry.
*/
public boolean init(Configuration conf, ServiceMetaData arg1) {
DictionaryLog.l.info("Initializing Dictionary Service");
DictionaryRefresh refreshTask = new DictionaryRefresh();
int refreshInteral = conf.getInt("dictionary.refresh", 30);
ExpressionBuilder expr = new ExpressionBuilder();
expr.setMinute(refreshInteral, true);
long startTime = new Date().getTime() + 10 * 60 * 1000 /** After 10 minutes */;
try {
scheduledRefresh = new ScheduleTask(refreshTask, expr.getExpression(),
new Date(startTime), new Date(Long.MAX_VALUE));
DictionaryLog.l.info("DisctionaryManager > Dictionry Refresh task is scheduled.");
int mergeCount = conf.getInt("dictionary.merge.words", 1000);
int pageSize = conf.getInt("dictionary.page.Size", 1000);
this.dict = new Dictionary(mergeCount, pageSize);
DictionaryLog.l.info("DisctionaryManager > Initializing the dictionry for first time.");
this.dict.buildTerms();
return true;
} catch (Exception ex) {
DictionaryLog.l.fatal("DisctionaryManager >", ex);
return false;
}
}
public void process(Request arg0, Response arg1) {
}
/**
* Stop the refresh task
*/
public void stop() {
if ( null != this.scheduledRefresh)
this.scheduledRefresh.endDate = new Date(System.currentTimeMillis());
}
/**
* Get the first page words from the dictionary
* @return List of words
* @throws SystemFault
*/
public List<String> getKeywords() throws SystemFault {
if ( null == this.dict) throw new SystemFault("DictionryManager not initialized");
return this.dict.getAll();
}
public List<String> getKeywords(String fromWord) throws SystemFault {
if ( null == this.dict) throw new SystemFault("DictionryManager not initialized");
return this.dict.getAll(fromWord);
}
/**
* Add a single entry to the dictionry
* @param entry
* @throws SystemFault
*/
public void add(DictEntry entry) throws SystemFault {
if ( null == this.dict) throw new SystemFault("DictionryManager not initialized");
Hashtable<String, DictEntry> entries = new Hashtable<String, DictEntry>(1);
entries.put(entry.fldWord, entry);
this.dict.add(entries);
}
/**
* Add bunch of entries to the dictionry
* @param entries
* @throws SystemFault
*/
public void add(Hashtable<String, DictEntry> entries) throws SystemFault {
if ( null == this.dict) throw new SystemFault("DictionryManager not initialized");
this.dict.add(entries);
}
public void refresh() throws SystemFault {
this.dict.buildTerms();
}
/**
* Get directly the keyword
* @param keyword
* @return Dictionary Entry
* @throws SystemFault
*/
public DictEntry get(String keyword) throws SystemFault {
if ( null == this.dict) throw new SystemFault("DictionryManager not initialized");
if ( StringUtils.isEmpty(keyword)) return null;
return this.dict.get(keyword);
}
/**
* Check for the right spelling for the given keyword
* @param keyword
* @return List of matching words
* @throws SystemFault
*/
public List<String> getSpelled(String keyword) throws SystemFault {
if ( null == this.dict) throw new SystemFault("DictionryManager not initialized");
if ( StringUtils.isEmpty(keyword)) return null;
return this.dict.fuzzy(keyword, 3);
}
/**
* Gets matching keywords for the given wildcard keyword.
* @param keyword The regular expression
* @return List of matching words
* @throws SystemFault
*/
public List<String> getWildCard(String keyword) throws SystemFault {
if ( null == this.dict) throw new SystemFault("DictionryManager not initialized");
if ( StringUtils.isEmpty(keyword)) return null;
return this.dict.regex(keyword);
}
/**
* This completely removes the keywords from the dictionry
* @param keywords
* @throws SystemFault
*/
public void delete(List<String> keywords) throws SystemFault {
if ( null == this.dict) throw new SystemFault("DictionryManager not initialized");
this.dict.delete(keywords);
}
/**
* This removes all entries from the dictionry.
* One should be careful before calling this function.
* @throws SystemFault
*/
public void deleteAll() throws SystemFault, SystemFault {
if ( null == this.dict) throw new SystemFault("DictionryManager not initialized");
this.dict.purge();
}
/**
* Once a document is removed, substract it's keywords from the dictionry
* If there are more
* @param entries
* @throws SystemFault
*/
public void substract(Hashtable<String, DictEntry> entries) throws SystemFault {
if ( null == this.dict) throw new SystemFault("DictionryManager not initialized");
if ( null == entries) return;
this.dict.substract(entries);
}
public Dictionary getDictionary() {
return this.dict;
}
}