com.google.gerrit.extensions.restapi.RestApiModule Maven / Gradle / Ivy
// Copyright (C) 2012 The Android Open Source Project
//
// 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.gerrit.extensions.restapi;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.gerrit.extensions.annotations.Export;
import com.google.gerrit.extensions.annotations.Exports;
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;
import com.google.inject.binder.LinkedBindingBuilder;
import com.google.inject.binder.ScopedBindingBuilder;
/** Guice DSL for binding {@link RestView} implementations. */
public abstract class RestApiModule extends FactoryModule {
  protected static final String GET = "GET";
  protected static final String PUT = "PUT";
  protected static final String DELETE = "DELETE";
  protected static final String POST = "POST";
  protected static final String CREATE = "CREATE";
  protected static final String DELETE_MISSING = "DELETE_MISSING";
  protected static final String DELETE_ON_COLLECTION = "DELETE_ON_COLLECTION";
  protected static final String POST_ON_COLLECTION = "POST_ON_COLLECTION";
  protected  ReadViewBinder get(TypeLiteral> viewType) {
    return get(viewType, "/");
  }
  protected  ModifyViewBinder put(TypeLiteral> viewType) {
    return put(viewType, "/");
  }
  protected  ModifyViewBinder post(TypeLiteral> viewType) {
    return post(viewType, "/");
  }
  protected  ModifyViewBinder delete(TypeLiteral> viewType) {
    return delete(viewType, "/");
  }
  protected  RestCollectionViewBinder postOnCollection(
      TypeLiteral> viewType) {
    return new RestCollectionViewBinder<>(
        bind(viewType).annotatedWith(export(POST_ON_COLLECTION, "/")));
  }
  /**
   * Creates a binder that allows to bind a REST view to handle {@code DELETE} on the REST
   * collection of the provided view type.
   *
   * This binding is ignored if the provided view type belongs to a root collection.
   *
   * @param viewType the type of the resources in the REST collection on which {@code DELETE} should
   *     be handled
   * @return binder that allows to bind an implementation for the REST view that should handle
   *     {@code DELETE} on the REST collection of the provided view type
   */
  protected  RestCollectionViewBinder deleteOnCollection(
      TypeLiteral> viewType) {
    return new RestCollectionViewBinder<>(
        bind(viewType).annotatedWith(export(DELETE_ON_COLLECTION, "/")));
  }
  protected  CreateViewBinder create(TypeLiteral> viewType) {
    return new CreateViewBinder<>(bind(viewType).annotatedWith(export(CREATE, "/")));
  }
  protected  DeleteViewBinder deleteMissing(
      TypeLiteral> viewType) {
    return new DeleteViewBinder<>(bind(viewType).annotatedWith(export(DELETE_MISSING, "/")));
  }
  protected  ReadViewBinder get(
      TypeLiteral> viewType, String name) {
    return new ReadViewBinder<>(view(viewType, GET, name));
  }
  protected  ModifyViewBinder put(
      TypeLiteral> viewType, String name) {
    return new ModifyViewBinder<>(view(viewType, PUT, name));
  }
  protected  ModifyViewBinder post(
      TypeLiteral> viewType, String name) {
    return new ModifyViewBinder<>(view(viewType, POST, name));
  }
  protected  ModifyViewBinder delete(
      TypeLiteral> viewType, String name) {
    return new ModifyViewBinder<>(view(viewType, DELETE, name));
  }
  protected  ChildCollectionBinder
 child(
      TypeLiteral> type, String name) {
    return new ChildCollectionBinder<>(view(type, GET, name));
  }
  private  LinkedBindingBuilder> view(
      TypeLiteral> viewType, String method, String name) {
    return bind(viewType).annotatedWith(export(method, name));
  }
  private static Export export(String method, String name) {
    if (name.length() > 1 && name.startsWith("/")) {
      // Views may be bound as "/" to mean the resource itself, or
      // as "status" as in "/type/{id}/status". Don't bind "/status"
      // if the caller asked for that, bind what the server expects.
      name = name.substring(1);
    }
    return Exports.named(method + "." + name);
  }
  public static class ReadViewBinder {
    private final LinkedBindingBuilder> binder;
    private ReadViewBinder(LinkedBindingBuilder> binder) {
      this.binder = binder;
    }
    @CanIgnoreReturnValue
    public > ScopedBindingBuilder to(Class impl) {
      return binder.to(impl);
    }
    public > void toInstance(T impl) {
      binder.toInstance(impl);
    }
    @CanIgnoreReturnValue
    public > ScopedBindingBuilder toProvider(
        Class extends Provider extends T>> providerType) {
      return binder.toProvider(providerType);
    }
    @CanIgnoreReturnValue
    public > ScopedBindingBuilder toProvider(
        Provider extends T> provider) {
      return binder.toProvider(provider);
    }
  }
  public static class ModifyViewBinder {
    private final LinkedBindingBuilder> binder;
    private ModifyViewBinder(LinkedBindingBuilder> binder) {
      this.binder = binder;
    }
    @CanIgnoreReturnValue
    public > ScopedBindingBuilder to(Class impl) {
      return binder.to(impl);
    }
    public > void toInstance(T impl) {
      binder.toInstance(impl);
    }
    @CanIgnoreReturnValue
    public > ScopedBindingBuilder toProvider(
        Class extends Provider extends T>> providerType) {
      return binder.toProvider(providerType);
    }
    @CanIgnoreReturnValue
    public > ScopedBindingBuilder toProvider(
        Provider extends T> provider) {
      return binder.toProvider(provider);
    }
  }
  public static class RestCollectionViewBinder {
    private final LinkedBindingBuilder> binder;
    private RestCollectionViewBinder(LinkedBindingBuilder> binder) {
      this.binder = binder;
    }
    @CanIgnoreReturnValue
    public >
        ScopedBindingBuilder to(Class impl) {
      return binder.to(impl);
    }
    public > void toInstance(
        T impl) {
      binder.toInstance(impl);
    }
    @CanIgnoreReturnValue
    public 
>
        ScopedBindingBuilder toProvider(Class extends Provider extends T>> providerType) {
      return binder.toProvider(providerType);
    }
    @CanIgnoreReturnValue
    public 
>
        ScopedBindingBuilder toProvider(Provider extends T> provider) {
      return binder.toProvider(provider);
    }
  }
  public static class CreateViewBinder {
    private final LinkedBindingBuilder> binder;
    private CreateViewBinder(LinkedBindingBuilder> binder) {
      this.binder = binder;
    }
    @CanIgnoreReturnValue
    public >
        ScopedBindingBuilder to(Class impl) {
      return binder.to(impl);
    }
    public > void toInstance(
        T impl) {
      binder.toInstance(impl);
    }
    @CanIgnoreReturnValue
    public 
>
        ScopedBindingBuilder toProvider(Class extends Provider extends T>> providerType) {
      return binder.toProvider(providerType);
    }
    @CanIgnoreReturnValue
    public 
>
        ScopedBindingBuilder toProvider(Provider extends T> provider) {
      return binder.toProvider(provider);
    }
  }
  public static class DeleteViewBinder {
    private final LinkedBindingBuilder> binder;
    private DeleteViewBinder(LinkedBindingBuilder> binder) {
      this.binder = binder;
    }
    @CanIgnoreReturnValue
    public >
        ScopedBindingBuilder to(Class impl) {
      return binder.to(impl);
    }
    public >
        void toInstance(T impl) {
      binder.toInstance(impl);
    }
    @CanIgnoreReturnValue
    public 
>
        ScopedBindingBuilder toProvider(Class extends Provider extends T>> providerType) {
      return binder.toProvider(providerType);
    }
    @CanIgnoreReturnValue
    public 
>
        ScopedBindingBuilder toProvider(Provider extends T> provider) {
      return binder.toProvider(provider);
    }
  }
  public static class ChildCollectionBinder
 {
    private final LinkedBindingBuilder> binder;
    private ChildCollectionBinder(LinkedBindingBuilder> binder) {
      this.binder = binder;
    }
    @CanIgnoreReturnValue
    public > ScopedBindingBuilder to(
        Class impl) {
      return binder.to(impl);
    }
    public > void toInstance(T impl) {
      binder.toInstance(impl);
    }
    @CanIgnoreReturnValue
    public >
        ScopedBindingBuilder toProvider(Class extends Provider extends T>> providerType) {
      return binder.toProvider(providerType);
    }
    @CanIgnoreReturnValue
    public >
        ScopedBindingBuilder toProvider(Provider extends T> provider) {
      return binder.toProvider(provider);
    }
  }
}