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

com.google.api.server.spi.config.model.ApiParameterConfig Maven / Gradle / Ivy

There is a newer version: 2.2.2
Show newest version
/*
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * 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.api.server.spi.config.model;

import com.google.api.server.spi.TypeLoader;
import com.google.api.server.spi.config.Nullable;
import com.google.api.server.spi.config.ResourceTransformer;
import com.google.api.server.spi.config.Transformer;

import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * Configuration for a single parameter of a Swarm Endpoint method.
 */
public class ApiParameterConfig {
  private final ApiMethodConfig apiMethodConfig;
  private final String name;
  private final boolean nullable;
  private final String defaultValue;
  private final Type type;

  private Class> serializer;
  private Class> repeatedItemSerializer;

  private final TypeLoader typeLoader;

  /**
   * Classification of how the parameter is used within Endpoints method calls.
   */
  public enum Classification {
    /** Parameter that will be automatically injected by the SPI framework.*/
    INJECTED,
    /** Parameter that will be filled by the value of an API parameter.  Generally used for simple
     *  values like an ID. */
    API_PARAMETER,
    /** Parameter that will be filled with an API entity.  Generally used for the resource object
     *  in REST-style APIs. */
    RESOURCE,
    /** Parameter that could not be classified because its type is unknown.*/
    UNKNOWN
  }

  public ApiParameterConfig(ApiMethodConfig apiMethodConfig, String name, boolean nullable,
      String defaultValue, Type type, TypeLoader typeLoader) {
    this.apiMethodConfig = apiMethodConfig;
    this.name = name;
    this.nullable = nullable;
    this.defaultValue = defaultValue;
    this.type = type;
    this.serializer = null;
    this.repeatedItemSerializer = null;
    this.typeLoader = typeLoader;
  }

  public ApiParameterConfig(ApiParameterConfig original, ApiMethodConfig apiMethodConfig) {
    this.apiMethodConfig = apiMethodConfig;
    this.name = original.name;
    this.nullable = original.nullable;
    this.defaultValue = original.defaultValue;
    this.type = original.type;
    this.serializer = original.serializer;
    this.repeatedItemSerializer = original.repeatedItemSerializer;
    this.typeLoader = original.typeLoader;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    } else if (o instanceof ApiParameterConfig) {
      ApiParameterConfig parameter = (ApiParameterConfig) o;
      return Objects.equals(name, parameter.name)
          && nullable == parameter.nullable
          && Objects.equals(defaultValue, parameter.defaultValue)
          && Objects.equals(type, parameter.type)
          && Objects.equals(serializer, parameter.serializer)
          && Objects.equals(repeatedItemSerializer, parameter.repeatedItemSerializer)
          && Objects.equals(typeLoader, parameter.typeLoader);
    } else {
      return false;
    }
  }

  @Override
  public int hashCode() {
    return Objects.hash(name, nullable, defaultValue, type, serializer, repeatedItemSerializer,
        typeLoader);
  }

  public ApiMethodConfig getApiMethodConfig() {
    return apiMethodConfig;
  }

  public String getName() {
    return name;
  }

  public boolean getNullable() {
    return nullable;
  }

  public String getDefaultValue() {
    return defaultValue;
  }

  public Type getType() {
    return type;
  }

  /**
   * If the serialized type of the parameter is a repeated type, returns the individual item type.
   * Otherwise returns {@code null}.
   */
  public Type getRepeatedItemType() {
    return TypeLoader.getArrayItemType(getSchemaBaseType());
  }

  /**
   * @return {@code true} iff the serialized type of the parameter is a repeated type.
   */
  public boolean isRepeated() {
    if (typeLoader.isInjectedType(getType())) {
      return false;
    } else {
      return TypeLoader.isArrayType(getSchemaBaseType());
    }
  }

  /**
   * @return {@code true} iff the serialized type (or serialized item type) of the parameter is an
   * enum type.
   */
  public boolean isEnum() {
    if (typeLoader.isInjectedType(getType())) {
      return false;
    }

    Type type;
    if (isRepeated()) {
      type = getRepeatedItemSerializedType();
    } else {
      type = getSchemaBaseType();
    }

    return TypeLoader.isEnumType(type);
  }

  private List>> tryFindDefaultSerializers(
      @Nullable Type type) {
    ApiSerializationConfig serializerConfig =
        apiMethodConfig.getApiClassConfig().getApiConfig().getSerializationConfig();
    return Serializers.getSerializerClasses(type, serializerConfig);
  }

  /**
   * @return The serializer to be used on the parameter.
   */
  public List>> getSerializers() {
    if (serializer != null) {
      return Collections.>>singletonList(serializer);
    } else {
      return tryFindDefaultSerializers(getType());
    }
  }

  public void setSerializer(Class> serializer) {
    this.serializer = serializer;
  }

  /**
   * If the serialized type of the parameter is a repeated type, returns the serializer to be used
   * on each individual item.  Otherwise returns {@code null}.
   */
  public List>> getRepeatedItemSerializers() {
    if (repeatedItemSerializer != null) {
      return Collections.>>singletonList(repeatedItemSerializer);
    } else {
      return tryFindDefaultSerializers(TypeLoader.getArrayItemType(getSchemaBaseType()));
    }
  }

  public void setRepeatedItemSerializer(Class> repeatedItemSerializer) {
    this.repeatedItemSerializer = repeatedItemSerializer;
  }

  /**
   * Gets the type that acts as the source for schema generation. In the case of resource
   * serialization, the schema is based on the type being serialized. Simple serializers just
   * convert from one type to another, in which case the schema would be derived from the target
   * type instead.
   */
  public Type getSchemaBaseType() {
    List>> serializers = getSerializers();
    if (serializers.isEmpty()) {
      return getType();
    } else if (ResourceTransformer.class.isAssignableFrom(serializers.get(0))) {
      return getType();
    } else {
      return Serializers.getTargetType(serializers.get(0));
    }
  }

  /**
   * If the serialized type of the parameter is a repeated type, returns the serialized individual
   * item type.  Otherwise returns {@code null}.
   */
  public Type getRepeatedItemSerializedType() {
    List>> serializers = getRepeatedItemSerializers();
    if (serializers.isEmpty()) {
      return getRepeatedItemType();
    } else {
      return Serializers.getTargetType(serializers.get(0));
    }
  }

  /**
   * Generates an API parameter classifcation based on the type.
   */
  public Classification getClassification() {
    if (typeLoader.isInjectedType(type) || StandardParameters.isStandardParamName(name)) {
      return Classification.INJECTED;
    }

    Type type;
    if (isRepeated()) {
      type = getRepeatedItemSerializedType();
    } else {
      type = getSchemaBaseType();
    }

    if (typeLoader.isParameterType(type) || TypeLoader.isEnumType(type)) {
      return Classification.API_PARAMETER;
    } else if (TypeLoader.isGenericType(type)) {
      return Classification.UNKNOWN;
    } else {
      return Classification.RESOURCE;
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy