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

com.google.cloud.Structs Maven / Gradle / Ivy

There is a newer version: 2.49.0
Show newest version
/*
 * Copyright 2016 Google LLC
 *
 * Licensed 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 com.google.cloud;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.api.client.util.Types;
import com.google.api.core.InternalApi;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.protobuf.ListValue;
import com.google.protobuf.NullValue;
import com.google.protobuf.Struct;
import com.google.protobuf.Value;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * This class contains static utility methods that operate on or return protobuf's {@code Struct}
 * objects. This is considered an internal class and implementation detail.
 */
@InternalApi
public final class Structs {

  private Structs() {}

  /**
   * This class wraps a protobuf's {@code Struct} object and offers a map interface to it, hiding
   * protobuf types.
   */
  private static final class StructMap extends AbstractMap {

    private final Set> entrySet;

    private StructMap(Struct struct) {
      this.entrySet = new StructSet(struct);
    }

    private static final class StructSet extends AbstractSet> {

      private static Entry valueToObject(Entry entry) {
        return new AbstractMap.SimpleEntry<>(
            entry.getKey(), Structs.valueToObject(entry.getValue()));
      }

      private final Struct struct;

      private StructSet(Struct struct) {
        this.struct = struct;
      }

      @Override
      public Iterator> iterator() {
        return Iterators.transform(
            struct.getFieldsMap().entrySet().iterator(), StructSet::valueToObject);
      }

      @Override
      public int size() {
        return struct.getFieldsMap().size();
      }
    }

    @Override
    public Set> entrySet() {
      return entrySet;
    }
  }

  /** Returns an unmodifiable map view of the {@link Struct} parameter. */
  public static Map asMap(Struct struct) {
    return new StructMap(checkNotNull(struct));
  }

  /**
   * Creates a new {@link Struct} object given the content of the provided {@code map} parameter.
   *
   * 

Notice that all numbers (int, long, float and double) are serialized as double values. Enums * are serialized as strings. */ public static Struct newStruct(Map map) { Map valueMap = Maps.transformValues(checkNotNull(map), Structs::objectToValue); return Struct.newBuilder().putAllFields(valueMap).build(); } private static Object valueToObject(Value value) { switch (value.getKindCase()) { case NULL_VALUE: return null; case NUMBER_VALUE: return value.getNumberValue(); case STRING_VALUE: return value.getStringValue(); case BOOL_VALUE: return value.getBoolValue(); case STRUCT_VALUE: return new StructMap(value.getStructValue()); case LIST_VALUE: return Lists.transform(value.getListValue().getValuesList(), Structs::valueToObject); default: throw new IllegalArgumentException(String.format("Unsupported protobuf value %s", value)); } } @SuppressWarnings("unchecked") private static Value objectToValue(final Object obj) { Value.Builder builder = Value.newBuilder(); if (obj == null) { builder.setNullValue(NullValue.NULL_VALUE); return builder.build(); } Class objClass = obj.getClass(); if (obj instanceof String) { builder.setStringValue((String) obj); } else if (obj instanceof Number) { builder.setNumberValue(((Number) obj).doubleValue()); } else if (obj instanceof Boolean) { builder.setBoolValue((Boolean) obj); } else if (obj instanceof Iterable || objClass.isArray()) { builder.setListValue( ListValue.newBuilder() .addAllValues(Iterables.transform(Types.iterableOf(obj), Structs::objectToValue))); } else if (objClass.isEnum()) { builder.setStringValue(((Enum) obj).name()); } else if (obj instanceof Map) { Map map = (Map) obj; builder.setStructValue(newStruct(map)); } else { throw new IllegalArgumentException(String.format("Unsupported protobuf value %s", obj)); } return builder.build(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy