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);
}
}
}