package org.fastcatsearch.http.action.management.collections;
import java.io.File;
import java.util.Collection;
import java.util.List;
import org.fastcatsearch.http.ActionAuthority;
import org.fastcatsearch.http.ActionAuthorityLevel;
import org.fastcatsearch.http.ActionMapping;
import org.fastcatsearch.http.action.ActionRequest;
import org.fastcatsearch.http.action.ActionResponse;
import org.fastcatsearch.http.action.AuthAction;
import org.fastcatsearch.ir.IRService;
import org.fastcatsearch.ir.config.CollectionContext;
import org.fastcatsearch.ir.settings.AnalyzerSetting;
import org.fastcatsearch.ir.settings.Schema;
import org.fastcatsearch.ir.settings.SchemaInvalidateException;
import org.fastcatsearch.ir.settings.SchemaSetting;
import org.fastcatsearch.plugin.Plugin;
import org.fastcatsearch.plugin.PluginService;
import org.fastcatsearch.plugin.analysis.AnalysisPlugin;
import org.fastcatsearch.plugin.analysis.AnalysisPluginSetting;
import org.fastcatsearch.plugin.analysis.AnalysisPluginSetting.Analyzer;
import org.fastcatsearch.service.ServiceManager;
import org.fastcatsearch.settings.SettingFileNames;
import org.fastcatsearch.util.FilePaths;
import org.fastcatsearch.util.JAXBConfigs;
import org.fastcatsearch.util.ResponseWriter;
import org.fastcatsearch.util.SchemaSettingUtil;
import org.json.JSONObject;
/**
*
* */
@ActionMapping(value = "/management/collections/schema/update", authority = ActionAuthority.Collections, authorityLevel = ActionAuthorityLevel.WRITABLE)
public class UpdateCollectionSchemaAction extends AuthAction {
@Override
public void doAuthAction(ActionRequest request, ActionResponse response) throws Exception {
String collectionId = request.getParameter("collectionId");
String type = request.getParameter("type");
String schemaJSONString = request.getParameter("schemaObject");
boolean isSuccess = true;
String errorMessage = "";
try {
IRService irService = ServiceManager.getInstance().getService(IRService.class);
CollectionContext collectionContext = irService.collectionContext(collectionId);
FilePaths collectionFilePaths = collectionContext.collectionFilePaths();
File collectionDir = collectionFilePaths.file();
File schemaFile = null;
SchemaSetting schemaSetting = null;
JSONObject schemaObject = new JSONObject(schemaJSONString);
// logger.debug("schemaObject > {}", schemaObject.toString(4));
// schema json string으로 SchemaSetting을 만든다.
schemaSetting = SchemaSettingUtil.convertSchemaSetting(schemaObject);
// 일단 json object를 schema validation체크수행한다.
schemaSetting.isValid();
isValidAnalyzer(schemaSetting);
// schemaSetting.getAnalyzerSettingList();
if ("workSchema".equalsIgnoreCase(type)) {
schemaFile = new File(collectionDir, SettingFileNames.workSchema);
} else {
schemaFile = new File(collectionDir, SettingFileNames.schema);
}
// 저장한다.
JAXBConfigs.writeConfig(schemaFile, schemaSetting, SchemaSetting.class);
//
if ("workSchema".equalsIgnoreCase(type)) {
collectionContext.setWorkSchemaSetting(schemaSetting);
} else {
collectionContext.setSchema(new Schema(schemaSetting));
}
} catch (SchemaInvalidateException e) {
// 스키마 오류의 각종 정보를 추출하여 호출자에 전달해 준다.
// logger.debug("", e);
isSuccess = false;
errorMessage = e.getMessage();
} catch (Exception e) {
logger.error("", e);
isSuccess = false;
errorMessage = e.getMessage();
}
ResponseWriter responseWriter = getDefaultResponseWriter(response.getWriter());
responseWriter.object();
responseWriter.key("success").value(isSuccess);
if (errorMessage != null) {
responseWriter.key("errorMessage").value(errorMessage);
}
responseWriter.endObject();
responseWriter.done();
}
/**
* 플러그인 세팅이 정상적인지 확인한다.
*
* @param schemaSetting
* @throws SchemaInvalidateException
*/
private void isValidAnalyzer(SchemaSetting schemaSetting) throws SchemaInvalidateException {
boolean found = false;
String section = "Analyzers";
String fieldId = "";
String attributeId = "analyzer";
String value = null;
List<AnalyzerSetting> analyzerSettingList = schemaSetting.getAnalyzerSettingList();
if(analyzerSettingList == null || analyzerSettingList.size() == 0){
//설정이 없을수도 있다.
return;
}
PluginService pluginService = ServiceManager.getInstance().getService(PluginService.class);
Collection<Plugin> plugins = pluginService.getPlugins();
for (AnalyzerSetting analyzerSetting : analyzerSettingList) {
fieldId = analyzerSetting.getId();
value = analyzerSetting.getClassName();
String[] className = value.split("[.]");
logger.trace("class name : {}", value);
// 플러그인 세팅 중 className 은 {플러그인ID}.{분석기ID} 로 이루어 져 있으며,
// 이 둘을 모두 확인 하려면 다음과 같은 과정을 거친다.
if (className.length == 2) {
String pluginId = className[0];
String analyzerId = className[1];
for (Plugin plugin : plugins) {
if (plugin instanceof AnalysisPlugin) {
@SuppressWarnings("rawtypes")
AnalysisPlugin analysisPlugin = (AnalysisPlugin) plugin;
AnalysisPluginSetting pluginSetting = analysisPlugin.getPluginSetting();
List<Analyzer> analyzerList = pluginSetting.getAnalyzerList();
logger.trace("compare plugin {} : setting {}", pluginId, pluginSetting.getId());
if (pluginId.equalsIgnoreCase(pluginSetting.getId())) {
for (Analyzer analyzer : analyzerList) {
logger.trace("compare analyzer {} : setting {}", analyzerId, analyzer.getId());
value = analyzerId;
if (analyzerId.equalsIgnoreCase(analyzer.getId())) {
found = true;
break;
}
}
}
}
if (found) {
break;
}
}
}
}
if (!found) {
throw new SchemaInvalidateException(section, fieldId, attributeId, value, "is not found");
}
}
}