public static SenseiSystemInfo buildFacets( JSONObject schemaObj, SenseiPluginRegistry pluginRegistry, List<FacetHandler<?>> facets, List<RuntimeFacetHandlerFactory<?, ?>> runtimeFacets, PluggableSearchEngineManager pluggableSearchEngineManager) 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")) { if (columnType.equalsIgnoreCase("int")) { columnType = "aint"; } else if (columnType.equalsIgnoreCase("long")) { columnType = "along"; } else if (columnType.equalsIgnoreCase("float")) { columnType = "afloat"; } } 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)); } else if (type.equals("path")) { facetHandler = buildPathHandler(name, fieldName, paramMap, false); } else if (type.equals("multi-path")) { facetHandler = buildPathHandler(name, fieldName, paramMap, true); } 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); } 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); } 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>( 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(pluggableSearchEngineManager.createFacetHandlers()); // uid facet handler to be added by default UIDFacetHandler uidHandler = new UIDFacetHandler(UID_FACET_NAME); SumGroupByFacetHandler sumGroupByFacetHandler = new SumGroupByFacetHandler(SUM_GROUP_BY_FACET_NAME); facets.add(uidHandler); facets.add(sumGroupByFacetHandler); sysInfo.setFacetInfos(facetInfos); return sysInfo; }