private void handleObjectStart()

in solr/solrj/src/java/org/apache/solr/common/util/JsonRecordReader.java [312:448]


    private void handleObjectStart(
        final JSONParser parser,
        final Handler handler,
        final Map<String, Object> values,
        final ArrayDeque<Set<String>> stack,
        boolean recordStarted,
        MethodFrameWrapper frameWrapper)
        throws IOException {

      final boolean isRecordStarted = recordStarted || isRecord;
      Set<String> valuesAddedInThisFrame = null;
      if (isRecord || !recordStarted) {
        // This Node is a match for an PATH from a forEach attribute,
        // prepare for the cleanup that will occur when the record
        // is emitted after its END_ELEMENT is matched
        valuesAddedInThisFrame = new HashSet<>();
        stack.push(valuesAddedInThisFrame);
      } else if (recordStarted) {
        // This node is a child of some parent which matched against forEach
        // attribute. Continue to add values to an existing record.
        valuesAddedInThisFrame = stack.peek();
      }

      class Wrapper extends MethodFrameWrapper {
        Wrapper(Node node, MethodFrameWrapper parent, String name) {
          this.node = node;
          this.parent = parent;
          this.name = name;
        }

        @Override
        public void walk(int event) throws IOException {
          if (event == OBJECT_START) {
            walkObject();
          } else if (event == ARRAY_START) {
            for (; ; ) {
              event = parser.nextEvent();
              if (event == ARRAY_END) {
                // ensure that the value is of type List
                final Object val = values.get(name);
                if (val != null && !(val instanceof List)) {
                  final ArrayList<Object> listVal = new ArrayList<>(1);
                  listVal.add(val);
                  values.put(name, listVal);
                }
                break;
              }
              if (event == OBJECT_START) {
                walkObject();
              }
            }
          }
        }

        void walkObject() throws IOException {
          if (node.isChildRecord) {
            node.handleObjectStart(
                parser,
                (record, path) -> addChildDoc2ParentDoc(record, values, getPathSuffix(path)),
                new LinkedHashMap<>(),
                new ArrayDeque<>(),
                true,
                this);
          } else {
            node.handleObjectStart(parser, handler, values, stack, isRecordStarted, this);
          }
        }
      }

      try {
        for (; ; ) {
          int event = parser.nextEvent();
          if (event == OBJECT_END) {
            if (isRecord()) {
              handler.handle(values, splitPath);
            }
            return;
          }
          assert event == STRING;
          assert parser.wasKey();
          String name = parser.getString();

          Node node = childNodes.get(name);
          if (node == null) node = wildCardChild;
          if (node == null) node = recursiveWildCardChild;

          if (node != null) {
            if (node.isLeaf) { // this is a leaf. Collect data here
              event = parser.nextEvent();
              String nameInRecord =
                  node.fieldName == null
                      ? getNameInRecord(name, frameWrapper, node)
                      : node.fieldName;
              MethodFrameWrapper runnable = null;
              if (event == OBJECT_START || event == ARRAY_START) {
                if (node.recursiveWildCardChild != null)
                  runnable = new Wrapper(node, frameWrapper, name);
              }
              Object val = parseSingleFieldValue(event, parser, runnable);
              if (val != null) {
                putValue(values, nameInRecord, val);
                valuesAddedInThisFrame.add(nameInRecord);
              }

            } else {
              event = parser.nextEvent();
              new Wrapper(node, frameWrapper, name).walk(event);
            }
          } else {
            // this is not something we are interested in. Skip it
            event = parser.nextEvent();
            if (event == STRING
                || event == LONG
                || event == NUMBER
                || event == BIGNUMBER
                || event == BOOLEAN
                || event == NULL) {
              continue;
            }
            if (event == ARRAY_START) {
              consumeTillMatchingEnd(parser, 0, 1);
              continue;
            }
            if (event == OBJECT_START) {
              consumeTillMatchingEnd(parser, 1, 0);
              continue;
            } else throw new RuntimeException("unexpected token " + event);
          }
        }
      } finally {
        if ((isRecord() || !isRecordStarted)) {
          for (String fld : valuesAddedInThisFrame) {
            values.remove(fld);
          }
        }
      }
    }