All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.solr.common.MapWriter Maven / Gradle / Ivy

There is a newer version: 9.8.1
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.solr.common;


import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.BiPredicate;

import org.apache.solr.common.util.Utils;

/**
 * Use this class to push all entries of a Map into an output.
 * This avoids creating map instances and is supposed to be memory efficient.
 * If the entries are primitives, unnecessary boxing is also avoided.
 */
public interface MapWriter extends MapSerializable , NavigableObject {

  default String jsonStr(){
    return Utils.toJSONString(this);
  }

  @Override
  @SuppressWarnings({"unchecked", "rawtypes"})
  default Map toMap(Map map) {
    try {
      writeMap(new EntryWriter() {
        @Override
        public EntryWriter put(CharSequence k, Object v) {
          if (v instanceof MapWriter) v = ((MapWriter) v).toMap(new LinkedHashMap<>());
          if (v instanceof IteratorWriter) v = ((IteratorWriter) v).toList(new ArrayList<>());
          if (v instanceof Iterable) {
            List lst = new ArrayList();
            for (Object vv : (Iterable)v) {
              if (vv instanceof MapWriter) vv = ((MapWriter) vv).toMap(new LinkedHashMap<>());
              if (vv instanceof IteratorWriter) vv = ((IteratorWriter) vv).toList(new ArrayList<>());
              lst.add(vv);
            }
            v = lst;
          }
          if (v instanceof Map) {
            Map map = new LinkedHashMap();
            for (Map.Entry entry : ((Map)v).entrySet()) {
              Object vv = entry.getValue();
              if (vv instanceof MapWriter) vv = ((MapWriter) vv).toMap(new LinkedHashMap<>());
              if (vv instanceof IteratorWriter) vv = ((IteratorWriter) vv).toList(new ArrayList<>());
              map.put(entry.getKey(), vv);
            }
            v = map;
          }
          map.put(k==null? null : k.toString(), v);
          // note: It'd be nice to assert that there is no previous value at 'k' but it's possible the passed in
          // map is already populated and the intention is to overwrite.
          return this;
        }

      });
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
    return map;
  }

  void writeMap(EntryWriter ew) throws IOException;

  /**
   * An interface to push one entry at a time to the output.
   * The order of the keys is not defined, but we assume they are distinct -- don't call {@code put} more than once
   * for the same key.
   */
  interface EntryWriter {

    /**
     * Writes a key value into the map
     *
     * @param k The key
     * @param v The value can be any supported object
     */
    EntryWriter put(CharSequence k, Object v) throws IOException;
    default EntryWriter putNoEx(CharSequence k, Object v) {
      try {
        put(k,v);
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
      return this;
    }

    default EntryWriter put(CharSequence k, Object v, BiPredicate p) throws IOException {
      if (p.test(k,v)) put(k, v);
      return this;
    }

    default EntryWriter putIfNotNull(CharSequence k, Object v) throws IOException {
      if(v != null) put(k,v);
      return this;
    }

    default EntryWriter putStringIfNotNull(CharSequence k, Object v) throws IOException {
      if(v != null) put(k,String.valueOf(v));
      return this;
    }


    default EntryWriter put(CharSequence k, int v) throws IOException {
      put(k, (Integer) v);
      return this;
    }


    default EntryWriter put(CharSequence k, long v) throws IOException {
      put(k, (Long) v);
      return this;
    }


    default EntryWriter put(CharSequence k, float v) throws IOException {
      put(k, (Float) v);
      return this;
    }

    default EntryWriter put(CharSequence k, double v) throws IOException {
      put(k, (Double) v);
      return this;
    }

    default EntryWriter put(CharSequence k, boolean v) throws IOException {
      put(k, (Boolean) v);
      return this;
    }

    /**This is an optimization to avoid the instanceof checks.
     *
     */
    default EntryWriter put(CharSequence k, CharSequence v) throws IOException {
      put(k, (Object)v);
      return this;

    }

    default BiConsumer getBiConsumer(){
      return (k, v) -> putNoEx(k,v);
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy