List<RuntimeFacetHandlerFactory<?, ?>> runtimeFacets,
PluggableSearchEngineManager pluggableSearchEngineManager,
int invertedIndexPenalty)
throws JSONException, ConfigurationException {
Set<String> pluggableSearchEngineFacetNames = pluggableSearchEngineManager.getFacetNames();
SenseiSystemInfo sysInfo = new SenseiSystemInfo();
JSONArray facetsList = schemaObj.optJSONArray("facets");
int count = 0;
if (facetsList != null) {
count = facetsList.length();
}
if (count <= 0) {
return sysInfo;
}
JSONObject table = schemaObj.optJSONObject("table");
if (table == null) {
throw new ConfigurationException("Empty schema");
}
JSONArray columns = table.optJSONArray("columns");
Map<String, JSONObject> columnMap = new HashMap<String, JSONObject>();
for (int i = 0; i < columns.length(); ++i) {
JSONObject column = columns.getJSONObject(i);
try {
String name = column.getString("name");
columnMap.put(name, column);
} catch (Exception e) {
throw new ConfigurationException("Error parsing schema: ", e);
}
}
Map<String, TermListFactory<?>> termListFactoryMap = getPredefinedTermListFactoryMap(schemaObj);
Set<SenseiSystemInfo.SenseiFacetInfo> facetInfos = new HashSet<SenseiSystemInfo.SenseiFacetInfo>();
for (int i = 0; i < count; ++i) {
JSONObject facet = facetsList.getJSONObject(i);
try {
String name = facet.getString("name");
if (UID_FACET_NAME.equals(name)) {
logger.error("facet name: " + UID_FACET_NAME + " is reserved, skipping...");
continue;
}
String type = facet.getString("type");
String fieldName = facet.optString("column", name);
Set<String> dependSet = new HashSet<String>();
JSONArray dependsArray = facet.optJSONArray("depends");
if (dependsArray != null) {
int depCount = dependsArray.length();
for (int k = 0; k < depCount; ++k) {
dependSet.add(dependsArray.getString(k));
}
}
SenseiSystemInfo.SenseiFacetInfo facetInfo = new SenseiSystemInfo.SenseiFacetInfo(name);
Map<String, String> facetProps = new HashMap<String, String>();
facetProps.put("type", type);
facetProps.put("column", fieldName);
JSONObject column = columnMap.get(fieldName);
String columnType = (column == null) ? "" : column.optString("type", "");
if (column != null && column.opt("activity") != null && column.optBoolean("activity")) {
columnType = "aint";
}
facetProps.put("column_type", columnType);
facetProps.put("depends", dependSet.toString());
JSONArray paramList = facet.optJSONArray("params");
Map<String, List<String>> paramMap = parseParams(paramList);
for (Entry<String, List<String>> entry : paramMap.entrySet()) {
facetProps.put(entry.getKey(), entry.getValue().toString());
}
facetInfo.setProps(facetProps);
facetInfos.add(facetInfo);
if (pluggableSearchEngineFacetNames.contains(name)) {
continue;
}
FacetHandler<?> facetHandler = null;
if (type.equals("simple")) {
facetHandler = buildSimpleFacetHandler(name, fieldName, dependSet, termListFactoryMap.get(fieldName), invertedIndexPenalty);
} else if (type.equals("path")) {
facetHandler = buildPathHandler(name, fieldName, paramMap, invertedIndexPenalty);
} else if (type.equals("range")) {
if (column.optBoolean("multi")) {
facetHandler = new MultiRangeFacetHandler(name, fieldName, null, termListFactoryMap.get(fieldName),
buildPredefinedRanges(paramMap));
} else {
facetHandler = buildRangeHandler(name, fieldName, termListFactoryMap.get(fieldName), paramMap);
}
} else if (type.equals("multi")) {
facetHandler = buildMultiHandler(name, fieldName, termListFactoryMap.get(fieldName), dependSet, invertedIndexPenalty);
} else if (type.equals("compact-multi")) {
facetHandler = buildCompactMultiHandler(name, fieldName, dependSet, termListFactoryMap.get(fieldName));
} else if (type.equals("weighted-multi")) {
facetHandler = buildWeightedMultiHandler(name, fieldName, termListFactoryMap.get(fieldName), dependSet,
invertedIndexPenalty);
} else if (type.equals("attribute")) {
facetHandler = new AttributesFacetHandler(name, fieldName, termListFactoryMap.get(fieldName), null,
facetProps);
} else if (type.equals("histogram")) {
// A histogram facet handler is always dynamic
RuntimeFacetHandlerFactory<?, ?> runtimeFacetFactory = getHistogramFacetHandlerFactory(facet, name, paramMap);
runtimeFacets.add(runtimeFacetFactory);
facetInfo.setRunTime(true);
} else if (type.equals("dynamicTimeRange")) {
if (dependSet.isEmpty()) {
Assert.isTrue(fieldName != null && fieldName.length() > 0, "Facet handler " + name + " requires either depends or column attributes");
RangeFacetHandler internalFacet = new RangeFacetHandler(name + "_internal", fieldName, new PredefinedTermListFactory(Long.class, DynamicTimeRangeFacetHandler.NUMBER_FORMAT), null);
facets.add(internalFacet);
dependSet.add(internalFacet.getName());
}
RuntimeFacetHandlerFactory<?, ?> runtimeFacetFactory = getDynamicTimeFacetHandlerFactory(name, fieldName, dependSet, paramMap);
runtimeFacets.add(runtimeFacetFactory);
facetInfo.setRunTime(true);
} else if (type.equals("custom")) {
boolean isDynamic = facet.optBoolean("dynamic");
// Load from custom-facets spring configuration.
if (isDynamic) {
RuntimeFacetHandlerFactory<?, ?> runtimeFacetFactory = pluginRegistry.getRuntimeFacet(name);
runtimeFacets.add(runtimeFacetFactory);
facetInfo.setRunTime(true);
} else {
facetHandler = pluginRegistry.getFacet(name);
}
} else {
throw new IllegalArgumentException("type not supported: " + type);
}
if (facetHandler != null) {
facets.add(facetHandler);
}
} catch (Exception e) {
throw new ConfigurationException("Error parsing schema: "
+ facet, e);
}
}
facets.addAll((Collection<? extends FacetHandler<?>>) pluggableSearchEngineManager.createFacetHandlers());
// uid facet handler to be added by default
UIDFacetHandler uidHandler = new UIDFacetHandler(UID_FACET_NAME);
facets.add(uidHandler);
sysInfo.setFacetInfos(facetInfos);
return sysInfo;
}