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.server.plugins; 16 : 17 : import com.google.gerrit.common.data.GlobalCapability; 18 : import com.google.gerrit.extensions.annotations.RequiresCapability; 19 : import com.google.gerrit.extensions.api.plugins.InstallPluginInput; 20 : import com.google.gerrit.extensions.common.PluginInfo; 21 : import com.google.gerrit.extensions.restapi.BadRequestException; 22 : import com.google.gerrit.extensions.restapi.IdString; 23 : import com.google.gerrit.extensions.restapi.Response; 24 : import com.google.gerrit.extensions.restapi.RestApiException; 25 : import com.google.gerrit.extensions.restapi.RestCollectionCreateView; 26 : import com.google.gerrit.extensions.restapi.RestModifyView; 27 : import com.google.gerrit.extensions.restapi.TopLevelResource; 28 : import com.google.inject.Inject; 29 : import com.google.inject.Provider; 30 : import com.google.inject.Singleton; 31 : import java.io.IOException; 32 : import java.io.InputStream; 33 : import java.io.PrintWriter; 34 : import java.io.StringWriter; 35 : import java.net.URL; 36 : import java.util.zip.ZipException; 37 : 38 : @RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER) 39 : public class InstallPlugin implements RestModifyView<TopLevelResource, InstallPluginInput> { 40 : private final PluginLoader loader; 41 : 42 : private String name; 43 : private boolean created; 44 : 45 : @Inject 46 3 : InstallPlugin(PluginLoader loader) { 47 3 : this.loader = loader; 48 3 : } 49 : 50 : public InstallPlugin setName(String name) { 51 3 : this.name = name; 52 3 : return this; 53 : } 54 : 55 : public InstallPlugin setCreated(boolean created) { 56 1 : this.created = created; 57 1 : return this; 58 : } 59 : 60 : @Override 61 : public Response<PluginInfo> apply(TopLevelResource resource, InstallPluginInput input) 62 : throws RestApiException, IOException { 63 3 : loader.checkRemoteAdminEnabled(); 64 : try { 65 3 : try (InputStream in = openStream(input)) { 66 3 : String pluginName = loader.installPluginFromStream(name, in); 67 3 : PluginInfo info = ListPlugins.toPluginInfo(loader.get(pluginName)); 68 3 : return created ? Response.created(info) : Response.ok(info); 69 : } 70 1 : } catch (PluginInstallException e) { 71 1 : StringWriter buf = new StringWriter(); 72 1 : buf.write(String.format("cannot install %s", name)); 73 1 : if (e.getCause() instanceof ZipException) { 74 0 : buf.write(": "); 75 0 : buf.write(e.getCause().getMessage()); 76 : } else { 77 1 : buf.write(":\n"); 78 1 : PrintWriter pw = new PrintWriter(buf); 79 1 : e.printStackTrace(pw); 80 1 : pw.flush(); 81 : } 82 1 : throw new BadRequestException(buf.toString()); 83 : } 84 : } 85 : 86 : private InputStream openStream(InstallPluginInput input) throws IOException, BadRequestException { 87 3 : if (input.raw != null) { 88 3 : return input.raw.getInputStream(); 89 : } 90 : try { 91 0 : return new URL(input.url).openStream(); 92 0 : } catch (IOException e) { 93 0 : throw new BadRequestException(e.getMessage()); 94 : } 95 : } 96 : 97 : @RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER) 98 : @Singleton 99 : static class Create 100 : implements RestCollectionCreateView<TopLevelResource, PluginResource, InstallPluginInput> { 101 : private final PluginLoader loader; 102 : private final Provider<InstallPlugin> install; 103 : 104 : @Inject 105 138 : Create(PluginLoader loader, Provider<InstallPlugin> install) { 106 138 : this.loader = loader; 107 138 : this.install = install; 108 138 : } 109 : 110 : @Override 111 : public Response<PluginInfo> apply( 112 : TopLevelResource parentResource, IdString id, InstallPluginInput input) throws Exception { 113 1 : loader.checkRemoteAdminEnabled(); 114 0 : return install.get().setName(id.get()).setCreated(true).apply(parentResource, input); 115 : } 116 : } 117 : 118 : @RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER) 119 : @Singleton 120 : static class Overwrite implements RestModifyView<PluginResource, InstallPluginInput> { 121 : private final Provider<InstallPlugin> install; 122 : 123 : @Inject 124 138 : Overwrite(Provider<InstallPlugin> install) { 125 138 : this.install = install; 126 138 : } 127 : 128 : @Override 129 : public Response<PluginInfo> apply(PluginResource resource, InstallPluginInput input) 130 : throws RestApiException, IOException { 131 0 : return install.get().setName(resource.getName()).apply(TopLevelResource.INSTANCE, input); 132 : } 133 : } 134 : }