示例#1
0
        @Override
        public Mapper.Builder<?, ?> parse(
            String name, Map<String, Object> node, ParserContext parserContext)
            throws MapperParsingException {
          ContentPath.Type pathType = null;
          FieldMapper.Builder mainFieldBuilder = null;
          List<FieldMapper.Builder> fields = null;
          String firstType = null;

          for (Iterator<Map.Entry<String, Object>> iterator = node.entrySet().iterator();
              iterator.hasNext(); ) {
            Map.Entry<String, Object> entry = iterator.next();
            String fieldName = Strings.toUnderscoreCase(entry.getKey());
            Object fieldNode = entry.getValue();
            if (fieldName.equals("path")
                && parserContext.indexVersionCreated().before(Version.V_2_0_0_beta1)) {
              pathType = parsePathType(name, fieldNode.toString());
              iterator.remove();
            } else if (fieldName.equals("fields")) {
              Map<String, Object> fieldsNode = (Map<String, Object>) fieldNode;
              for (Iterator<Map.Entry<String, Object>> fieldsIterator =
                      fieldsNode.entrySet().iterator();
                  fieldsIterator.hasNext(); ) {
                Map.Entry<String, Object> entry1 = fieldsIterator.next();
                String propName = entry1.getKey();
                Map<String, Object> propNode = (Map<String, Object>) entry1.getValue();

                String type;
                Object typeNode = propNode.get("type");
                if (typeNode != null) {
                  type = typeNode.toString();
                  if (firstType == null) {
                    firstType = type;
                  }
                } else {
                  throw new MapperParsingException(
                      "no type specified for property [" + propName + "]");
                }

                Mapper.TypeParser typeParser = parserContext.typeParser(type);
                if (typeParser == null) {
                  throw new MapperParsingException(
                      "no handler for type [" + type + "] declared on field [" + fieldName + "]");
                }
                if (propName.equals(name)) {
                  mainFieldBuilder =
                      (FieldMapper.Builder) typeParser.parse(propName, propNode, parserContext);
                  fieldsIterator.remove();
                } else {
                  if (fields == null) {
                    fields = new ArrayList<>(2);
                  }
                  fields.add(
                      (FieldMapper.Builder) typeParser.parse(propName, propNode, parserContext));
                  fieldsIterator.remove();
                }
              }
              fieldsNode.remove("type");
              DocumentMapperParser.checkNoRemainingFields(
                  fieldName, fieldsNode, parserContext.indexVersionCreated());
              iterator.remove();
            }
          }

          if (mainFieldBuilder == null) {
            if (fields == null) {
              // No fields at all were specified in multi_field, so lets return a non indexed string
              // field.
              return new StringFieldMapper.Builder(name).index(false);
            }
            Mapper.TypeParser typeParser = parserContext.typeParser(firstType);
            if (typeParser == null) {
              // The first multi field's type is unknown
              mainFieldBuilder = new StringFieldMapper.Builder(name).index(false);
            } else {
              Mapper.Builder substitute =
                  typeParser.parse(name, Collections.<String, Object>emptyMap(), parserContext);
              if (substitute instanceof FieldMapper.Builder) {
                mainFieldBuilder = ((FieldMapper.Builder) substitute).index(false);
              } else {
                // The first multi isn't a core field type
                mainFieldBuilder = new StringFieldMapper.Builder(name).index(false);
              }
            }
          }

          if (fields != null && pathType != null) {
            for (Mapper.Builder field : fields) {
              mainFieldBuilder.addMultiField(field);
            }
            mainFieldBuilder.multiFieldPathType(pathType);
          } else if (fields != null) {
            for (Mapper.Builder field : fields) {
              mainFieldBuilder.addMultiField(field);
            }
          } else if (pathType != null) {
            mainFieldBuilder.multiFieldPathType(pathType);
          }
          return mainFieldBuilder;
        }
示例#2
0
  public static boolean parseMultiField(
      FieldMapper.Builder builder,
      String name,
      Mapper.TypeParser.ParserContext parserContext,
      String propName,
      Object propNode) {
    parserContext = parserContext.createMultiFieldContext(parserContext);
    if (propName.equals("path")
        && parserContext.indexVersionCreated().before(Version.V_2_0_0_beta1)) {
      builder.multiFieldPathType(parsePathType(name, propNode.toString()));
      return true;
    } else if (propName.equals("fields")) {

      final Map<String, Object> multiFieldsPropNodes;

      if (propNode instanceof List && ((List<?>) propNode).isEmpty()) {
        multiFieldsPropNodes = Collections.emptyMap();
      } else if (propNode instanceof Map) {
        multiFieldsPropNodes = (Map<String, Object>) propNode;
      } else {
        throw new MapperParsingException(
            "expected map for property [fields] on field ["
                + propNode
                + "] or "
                + "["
                + propName
                + "] but got a "
                + propNode.getClass());
      }

      for (Map.Entry<String, Object> multiFieldEntry : multiFieldsPropNodes.entrySet()) {
        String multiFieldName = multiFieldEntry.getKey();
        if (multiFieldName.contains(".")) {
          throw new MapperParsingException(
              "Field name ["
                  + multiFieldName
                  + "] which is a multi field of ["
                  + name
                  + "] cannot contain '.'");
        }
        if (!(multiFieldEntry.getValue() instanceof Map)) {
          throw new MapperParsingException(
              "illegal field [" + multiFieldName + "], only fields can be specified inside fields");
        }
        @SuppressWarnings("unchecked")
        Map<String, Object> multiFieldNodes = (Map<String, Object>) multiFieldEntry.getValue();

        String type;
        Object typeNode = multiFieldNodes.get("type");
        if (typeNode != null) {
          type = typeNode.toString();
        } else {
          throw new MapperParsingException(
              "no type specified for property [" + multiFieldName + "]");
        }
        if (type.equals(ObjectMapper.CONTENT_TYPE)
            || type.equals(ObjectMapper.NESTED_CONTENT_TYPE)) {
          throw new MapperParsingException("Type [" + type + "] cannot be used in multi field");
        }

        Mapper.TypeParser typeParser = parserContext.typeParser(type);
        if (typeParser == null) {
          throw new MapperParsingException(
              "no handler for type [" + type + "] declared on field [" + multiFieldName + "]");
        }
        builder.addMultiField(typeParser.parse(multiFieldName, multiFieldNodes, parserContext));
        multiFieldNodes.remove("type");
        DocumentMapperParser.checkNoRemainingFields(
            propName, multiFieldNodes, parserContext.indexVersionCreated());
      }
      return true;
    }
    return false;
  }