LCOV - code coverage report
Current view: top level - extensions/restapi - RestApiModule.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 44 68 64.7 %
Date: 2022-11-19 15:00:39 Functions: 28 46 60.9 %

          Line data    Source code
       1             : // Copyright (C) 2012 The Android Open Source Project
       2             : //
       3             : // Licensed under the Apache License, Version 2.0 (the "License");
       4             : // you may not use this file except in compliance with the License.
       5             : // You may obtain a copy of the License at
       6             : //
       7             : // http://www.apache.org/licenses/LICENSE-2.0
       8             : //
       9             : // Unless required by applicable law or agreed to in writing, software
      10             : // distributed under the License is distributed on an "AS IS" BASIS,
      11             : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             : // See the License for the specific language governing permissions and
      13             : // limitations under the License.
      14             : 
      15             : package com.google.gerrit.extensions.restapi;
      16             : 
      17             : import com.google.gerrit.extensions.annotations.Export;
      18             : import com.google.gerrit.extensions.annotations.Exports;
      19             : import com.google.gerrit.extensions.config.FactoryModule;
      20             : import com.google.inject.Provider;
      21             : import com.google.inject.TypeLiteral;
      22             : import com.google.inject.binder.LinkedBindingBuilder;
      23             : import com.google.inject.binder.ScopedBindingBuilder;
      24             : 
      25             : /** Guice DSL for binding {@link RestView} implementations. */
      26         153 : public abstract class RestApiModule extends FactoryModule {
      27             :   protected static final String GET = "GET";
      28             :   protected static final String PUT = "PUT";
      29             :   protected static final String DELETE = "DELETE";
      30             :   protected static final String POST = "POST";
      31             :   protected static final String CREATE = "CREATE";
      32             :   protected static final String DELETE_MISSING = "DELETE_MISSING";
      33             :   protected static final String DELETE_ON_COLLECTION = "DELETE_ON_COLLECTION";
      34             :   protected static final String POST_ON_COLLECTION = "POST_ON_COLLECTION";
      35             : 
      36             :   protected <R extends RestResource> ReadViewBinder<R> get(TypeLiteral<RestView<R>> viewType) {
      37         152 :     return get(viewType, "/");
      38             :   }
      39             : 
      40             :   protected <R extends RestResource> ModifyViewBinder<R> put(TypeLiteral<RestView<R>> viewType) {
      41         152 :     return put(viewType, "/");
      42             :   }
      43             : 
      44             :   protected <R extends RestResource> ModifyViewBinder<R> post(TypeLiteral<RestView<R>> viewType) {
      45           0 :     return post(viewType, "/");
      46             :   }
      47             : 
      48             :   protected <R extends RestResource> ModifyViewBinder<R> delete(TypeLiteral<RestView<R>> viewType) {
      49         152 :     return delete(viewType, "/");
      50             :   }
      51             : 
      52             :   protected <R extends RestResource> RestCollectionViewBinder<R> postOnCollection(
      53             :       TypeLiteral<RestView<R>> viewType) {
      54         152 :     return new RestCollectionViewBinder<>(
      55         152 :         bind(viewType).annotatedWith(export(POST_ON_COLLECTION, "/")));
      56             :   }
      57             : 
      58             :   /**
      59             :    * Creates a binder that allows to bind a REST view to handle {@code DELETE} on the REST
      60             :    * collection of the provided view type.
      61             :    *
      62             :    * <p>This binding is ignored if the provided view type belongs to a root collection.
      63             :    *
      64             :    * @param viewType the type of the resources in the REST collection on which {@code DELETE} should
      65             :    *     be handled
      66             :    * @return binder that allows to bind an implementation for the REST view that should handle
      67             :    *     {@code DELETE} on the REST collection of the provided view type
      68             :    */
      69             :   protected <R extends RestResource> RestCollectionViewBinder<R> deleteOnCollection(
      70             :       TypeLiteral<RestView<R>> viewType) {
      71         152 :     return new RestCollectionViewBinder<>(
      72         152 :         bind(viewType).annotatedWith(export(DELETE_ON_COLLECTION, "/")));
      73             :   }
      74             : 
      75             :   protected <R extends RestResource> CreateViewBinder<R> create(TypeLiteral<RestView<R>> viewType) {
      76         152 :     return new CreateViewBinder<>(bind(viewType).annotatedWith(export(CREATE, "/")));
      77             :   }
      78             : 
      79             :   protected <R extends RestResource> DeleteViewBinder<R> deleteMissing(
      80             :       TypeLiteral<RestView<R>> viewType) {
      81         152 :     return new DeleteViewBinder<>(bind(viewType).annotatedWith(export(DELETE_MISSING, "/")));
      82             :   }
      83             : 
      84             :   protected <R extends RestResource> ReadViewBinder<R> get(
      85             :       TypeLiteral<RestView<R>> viewType, String name) {
      86         152 :     return new ReadViewBinder<>(view(viewType, GET, name));
      87             :   }
      88             : 
      89             :   protected <R extends RestResource> ModifyViewBinder<R> put(
      90             :       TypeLiteral<RestView<R>> viewType, String name) {
      91         152 :     return new ModifyViewBinder<>(view(viewType, PUT, name));
      92             :   }
      93             : 
      94             :   protected <R extends RestResource> ModifyViewBinder<R> post(
      95             :       TypeLiteral<RestView<R>> viewType, String name) {
      96         152 :     return new ModifyViewBinder<>(view(viewType, POST, name));
      97             :   }
      98             : 
      99             :   protected <R extends RestResource> ModifyViewBinder<R> delete(
     100             :       TypeLiteral<RestView<R>> viewType, String name) {
     101         152 :     return new ModifyViewBinder<>(view(viewType, DELETE, name));
     102             :   }
     103             : 
     104             :   protected <P extends RestResource> ChildCollectionBinder<P> child(
     105             :       TypeLiteral<RestView<P>> type, String name) {
     106         152 :     return new ChildCollectionBinder<>(view(type, GET, name));
     107             :   }
     108             : 
     109             :   private <R extends RestResource> LinkedBindingBuilder<RestView<R>> view(
     110             :       TypeLiteral<RestView<R>> viewType, String method, String name) {
     111         152 :     return bind(viewType).annotatedWith(export(method, name));
     112             :   }
     113             : 
     114             :   private static Export export(String method, String name) {
     115         152 :     if (name.length() > 1 && name.startsWith("/")) {
     116             :       // Views may be bound as "/" to mean the resource itself, or
     117             :       // as "status" as in "/type/{id}/status". Don't bind "/status"
     118             :       // if the caller asked for that, bind what the server expects.
     119           0 :       name = name.substring(1);
     120             :     }
     121         152 :     return Exports.named(method + "." + name);
     122             :   }
     123             : 
     124             :   public static class ReadViewBinder<P extends RestResource> {
     125             :     private final LinkedBindingBuilder<RestView<P>> binder;
     126             : 
     127         152 :     private ReadViewBinder(LinkedBindingBuilder<RestView<P>> binder) {
     128         152 :       this.binder = binder;
     129         152 :     }
     130             : 
     131             :     public <T extends RestReadView<P>> ScopedBindingBuilder to(Class<T> impl) {
     132         152 :       return binder.to(impl);
     133             :     }
     134             : 
     135             :     public <T extends RestReadView<P>> void toInstance(T impl) {
     136           0 :       binder.toInstance(impl);
     137           0 :     }
     138             : 
     139             :     public <T extends RestReadView<P>> ScopedBindingBuilder toProvider(
     140             :         Class<? extends Provider<? extends T>> providerType) {
     141           0 :       return binder.toProvider(providerType);
     142             :     }
     143             : 
     144             :     public <T extends RestReadView<P>> ScopedBindingBuilder toProvider(
     145             :         Provider<? extends T> provider) {
     146           0 :       return binder.toProvider(provider);
     147             :     }
     148             :   }
     149             : 
     150             :   public static class ModifyViewBinder<P extends RestResource> {
     151             :     private final LinkedBindingBuilder<RestView<P>> binder;
     152             : 
     153         152 :     private ModifyViewBinder(LinkedBindingBuilder<RestView<P>> binder) {
     154         152 :       this.binder = binder;
     155         152 :     }
     156             : 
     157             :     public <T extends RestModifyView<P, ?>> ScopedBindingBuilder to(Class<T> impl) {
     158         152 :       return binder.to(impl);
     159             :     }
     160             : 
     161             :     public <T extends RestModifyView<P, ?>> void toInstance(T impl) {
     162           0 :       binder.toInstance(impl);
     163           0 :     }
     164             : 
     165             :     public <T extends RestModifyView<P, ?>> ScopedBindingBuilder toProvider(
     166             :         Class<? extends Provider<? extends T>> providerType) {
     167           0 :       return binder.toProvider(providerType);
     168             :     }
     169             : 
     170             :     public <T extends RestModifyView<P, ?>> ScopedBindingBuilder toProvider(
     171             :         Provider<? extends T> provider) {
     172           0 :       return binder.toProvider(provider);
     173             :     }
     174             :   }
     175             : 
     176             :   public static class RestCollectionViewBinder<C extends RestResource> {
     177             :     private final LinkedBindingBuilder<RestView<C>> binder;
     178             : 
     179         152 :     private RestCollectionViewBinder(LinkedBindingBuilder<RestView<C>> binder) {
     180         152 :       this.binder = binder;
     181         152 :     }
     182             : 
     183             :     public <P extends RestResource, T extends RestCollectionModifyView<P, C, ?>>
     184             :         ScopedBindingBuilder to(Class<T> impl) {
     185         152 :       return binder.to(impl);
     186             :     }
     187             : 
     188             :     public <P extends RestResource, T extends RestCollectionModifyView<P, C, ?>> void toInstance(
     189             :         T impl) {
     190           1 :       binder.toInstance(impl);
     191           1 :     }
     192             : 
     193             :     public <P extends RestResource, T extends RestCollectionModifyView<P, C, ?>>
     194             :         ScopedBindingBuilder toProvider(Class<? extends Provider<? extends T>> providerType) {
     195           0 :       return binder.toProvider(providerType);
     196             :     }
     197             : 
     198             :     public <P extends RestResource, T extends RestCollectionModifyView<P, C, ?>>
     199             :         ScopedBindingBuilder toProvider(Provider<? extends T> provider) {
     200           0 :       return binder.toProvider(provider);
     201             :     }
     202             :   }
     203             : 
     204             :   public static class CreateViewBinder<C extends RestResource> {
     205             :     private final LinkedBindingBuilder<RestView<C>> binder;
     206             : 
     207         152 :     private CreateViewBinder(LinkedBindingBuilder<RestView<C>> binder) {
     208         152 :       this.binder = binder;
     209         152 :     }
     210             : 
     211             :     public <P extends RestResource, T extends RestCollectionCreateView<P, C, ?>>
     212             :         ScopedBindingBuilder to(Class<T> impl) {
     213         152 :       return binder.to(impl);
     214             :     }
     215             : 
     216             :     public <P extends RestResource, T extends RestCollectionCreateView<P, C, ?>> void toInstance(
     217             :         T impl) {
     218           0 :       binder.toInstance(impl);
     219           0 :     }
     220             : 
     221             :     public <P extends RestResource, T extends RestCollectionCreateView<P, C, ?>>
     222             :         ScopedBindingBuilder toProvider(Class<? extends Provider<? extends T>> providerType) {
     223           0 :       return binder.toProvider(providerType);
     224             :     }
     225             : 
     226             :     public <P extends RestResource, T extends RestCollectionCreateView<P, C, ?>>
     227             :         ScopedBindingBuilder toProvider(Provider<? extends T> provider) {
     228           0 :       return binder.toProvider(provider);
     229             :     }
     230             :   }
     231             : 
     232             :   public static class DeleteViewBinder<C extends RestResource> {
     233             :     private final LinkedBindingBuilder<RestView<C>> binder;
     234             : 
     235         152 :     private DeleteViewBinder(LinkedBindingBuilder<RestView<C>> binder) {
     236         152 :       this.binder = binder;
     237         152 :     }
     238             : 
     239             :     public <P extends RestResource, T extends RestCollectionDeleteMissingView<P, C, ?>>
     240             :         ScopedBindingBuilder to(Class<T> impl) {
     241         152 :       return binder.to(impl);
     242             :     }
     243             : 
     244             :     public <P extends RestResource, T extends RestCollectionDeleteMissingView<P, C, ?>>
     245             :         void toInstance(T impl) {
     246           0 :       binder.toInstance(impl);
     247           0 :     }
     248             : 
     249             :     public <P extends RestResource, T extends RestCollectionDeleteMissingView<P, C, ?>>
     250             :         ScopedBindingBuilder toProvider(Class<? extends Provider<? extends T>> providerType) {
     251           0 :       return binder.toProvider(providerType);
     252             :     }
     253             : 
     254             :     public <P extends RestResource, T extends RestCollectionDeleteMissingView<P, C, ?>>
     255             :         ScopedBindingBuilder toProvider(Provider<? extends T> provider) {
     256           0 :       return binder.toProvider(provider);
     257             :     }
     258             :   }
     259             : 
     260             :   public static class ChildCollectionBinder<P extends RestResource> {
     261             :     private final LinkedBindingBuilder<RestView<P>> binder;
     262             : 
     263         152 :     private ChildCollectionBinder(LinkedBindingBuilder<RestView<P>> binder) {
     264         152 :       this.binder = binder;
     265         152 :     }
     266             : 
     267             :     public <C extends RestResource, T extends ChildCollection<P, C>> ScopedBindingBuilder to(
     268             :         Class<T> impl) {
     269         152 :       return binder.to(impl);
     270             :     }
     271             : 
     272             :     public <C extends RestResource, T extends ChildCollection<P, C>> void toInstance(T impl) {
     273           0 :       binder.toInstance(impl);
     274           0 :     }
     275             : 
     276             :     public <C extends RestResource, T extends ChildCollection<P, C>>
     277             :         ScopedBindingBuilder toProvider(Class<? extends Provider<? extends T>> providerType) {
     278           0 :       return binder.toProvider(providerType);
     279             :     }
     280             : 
     281             :     public <C extends RestResource, T extends ChildCollection<P, C>>
     282             :         ScopedBindingBuilder toProvider(Provider<? extends T> provider) {
     283           0 :       return binder.toProvider(provider);
     284             :     }
     285             :   }
     286             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750