Ejemplo n.º 1
0
  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;
  }