001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.geronimo.deployment.cli;
018
019 import java.io.IOException;
020 import java.net.URL;
021 import java.util.ArrayList;
022 import java.util.Collection;
023 import java.util.Comparator;
024 import java.util.List;
025 import java.util.Map;
026 import java.util.TreeMap;
027 import java.util.TreeSet;
028
029 import javax.enterprise.deploy.spi.DeploymentManager;
030 import javax.security.auth.login.FailedLoginException;
031
032 import jline.ConsoleReader;
033 import org.apache.geronimo.cli.deployer.CommandArgs;
034 import org.apache.geronimo.common.DeploymentException;
035 import org.apache.geronimo.deployment.plugin.GeronimoDeploymentManager;
036 import org.apache.geronimo.kernel.config.NoSuchStoreException;
037 import org.apache.geronimo.system.plugin.DownloadResults;
038 import org.apache.geronimo.system.plugin.PluginInstallerGBean;
039 import org.apache.geronimo.system.plugin.model.PluginArtifactType;
040 import org.apache.geronimo.system.plugin.model.PluginListType;
041 import org.apache.geronimo.system.plugin.model.PluginType;
042
043 /**
044 * The CLI deployer logic to start.
045 *
046 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
047 */
048 public class CommandListConfigurations extends AbstractCommand {
049
050 //todo: provide a way to handle a username and password for the remote repo?
051
052 public void execute(ConsoleReader consoleReader, ServerConnection connection, CommandArgs commandArgs) throws DeploymentException {
053 DeploymentManager dmgr = connection.getDeploymentManager();
054 if (dmgr instanceof GeronimoDeploymentManager) {
055 GeronimoDeploymentManager mgr = (GeronimoDeploymentManager) dmgr;
056 try {
057 String repo;
058 if (commandArgs.getArgs().length == 1) {
059 repo = commandArgs.getArgs()[0];
060 } else {
061 repo = getRepository(consoleReader, mgr);
062 }
063 PluginListType plugins = getPluginCategories(repo, mgr, consoleReader);
064 if (plugins == null) {
065 return;
066 }
067
068 PluginListType list = getInstallList(plugins, consoleReader, repo);
069 if (list == null) {
070 return;
071 }
072
073 installPlugins(mgr, list, repo, consoleReader, connection);
074 } catch (IOException e) {
075 throw new DeploymentException("Unable to install configuration", e);
076 } catch (NumberFormatException e) {
077 throw new DeploymentException("Invalid response");
078 }
079 } else {
080 throw new DeploymentException("Cannot list repositories using " + dmgr.getClass().getName() + " deployment manager");
081 }
082 }
083
084 public String getRepository(ConsoleReader consoleReader, GeronimoDeploymentManager mgr) throws IOException, DeploymentException {
085 URL[] all = mgr.getRepositories();
086 if (all.length == 0) {
087 throw new DeploymentException("No default repositories available. Please either specify the repository " +
088 "URL on the command line, or go into the console Plugin page and update the list of available " +
089 "repositories.");
090 }
091 // no need to ask for input if only one repo exists
092 if (all.length == 1) {
093 String repo = all[0].toString();
094 consoleReader.printNewline();
095 consoleReader.printString("Selected repository: " + repo);
096 consoleReader.printNewline();
097 return repo;
098 }
099
100 consoleReader.printNewline();
101 consoleReader.printString("Select repository:");
102 consoleReader.printNewline();
103 for (int i = 0; i < all.length; i++) {
104 URL url = all[i];
105 DeployUtils.printTo(" " + (i + 1) + ". ", 8, consoleReader);
106 DeployUtils.println(url.toString(), 0, consoleReader);
107 }
108 String entry = consoleReader.readLine("Enter Repository Number: ").trim();
109 if (entry.length() == 0) {
110 return null;
111 }
112 try {
113 int index = Integer.parseInt(entry);
114 return all[index - 1].toString();
115 } catch (NumberFormatException e) {
116 throw new DeploymentException("Invalid selection");
117 } catch (ArrayIndexOutOfBoundsException e) {
118 throw new DeploymentException("Invalid selection");
119 }
120 }
121
122 public PluginListType getPluginCategories(String repo, GeronimoDeploymentManager mgr, ConsoleReader consoleReader) throws DeploymentException, IOException {
123 if (repo == null) {
124 return null;
125 }
126 PluginListType data;
127 URL repository;
128 try {
129 repository = new URL(repo);
130 data = mgr.listPlugins(repository, null, null);
131 } catch (IOException e) {
132 throw new DeploymentException("Unable to list configurations", e);
133 } catch (FailedLoginException e) {
134 throw new DeploymentException("Invalid login for Maven repository '" + repo + "'", e);
135 }
136 if (data == null || data.getPlugin().size() == 0) {
137 return null;
138 }
139 return data;
140 }
141
142 public PluginListType getLocalPluginCategories(GeronimoDeploymentManager mgr, ConsoleReader consoleReader) throws DeploymentException, IOException {
143 PluginListType data;
144 try {
145 data = mgr.createPluginListForRepositories(null);
146 } catch (NoSuchStoreException e) {
147 throw new DeploymentException("Unable to list configurations", e);
148 }
149 if (data == null || data.getPlugin().size() == 0) {
150 return null;
151 }
152 return data;
153 }
154
155 private Map<String, Collection<PluginType>> writePluginList(PluginListType data, ConsoleReader consoleReader) throws IOException {
156 if (data == null) {
157 consoleReader.printNewline();
158 consoleReader.printString("No plugins were returned from this site.");
159 consoleReader.printNewline();
160 consoleReader.flushConsole();
161 return null;
162 }
163 Map<String, Collection<PluginType>> categories = new TreeMap<String, Collection<PluginType>>();
164 Comparator<PluginType> comp = new Comparator<PluginType>() {
165
166 public int compare(PluginType o1, PluginType o2) {
167 return o1.getName().compareTo(o2.getName());
168 }
169 };
170 for (PluginType metadata : data.getPlugin()) {
171 String category = metadata.getCategory();
172 if (category == null) {
173 category = "<no category>";
174 }
175 Collection<PluginType> list = categories.get(category);
176 if (list == null) {
177 list = new TreeSet<PluginType>(comp);
178 categories.put(category, list);
179 }
180 list.add(metadata);
181 }
182 return categories;
183 }
184
185 public PluginListType getInstallList(PluginListType plugins, ConsoleReader consoleReader, String repo) throws IOException {
186 Map<String, Collection<PluginType>> categories = writePluginList(plugins, consoleReader);
187 if (categories == null) {
188 return null;
189 }
190 List<PluginType> available = new ArrayList<PluginType>();
191 for (Map.Entry<String, Collection<PluginType>> entry : categories.entrySet()) {
192 String category = entry.getKey();
193 Collection<PluginType> items = entry.getValue();
194 consoleReader.printString(category);
195 consoleReader.printNewline();
196 for (PluginType metadata : items) {
197 for (PluginArtifactType instance : metadata.getPluginArtifact()) {
198 PluginType copy = PluginInstallerGBean.copy(metadata, instance);
199 available.add(copy);
200 DeployUtils.printTo(" " + available.size() + ": ", 10, consoleReader);
201 DeployUtils.println(metadata.getName() + " (" + instance.getModuleId().getVersion() + ")", 0, consoleReader);
202 }
203 }
204 }
205 if (available.size() == 0) {
206 consoleReader.printNewline();
207 consoleReader.printString("No plugins from this site are eligible for installation.");
208 consoleReader.printNewline();
209 return null;
210 }
211 consoleReader.printNewline();
212 consoleReader.flushConsole();
213 String answer = consoleReader.readLine("Install Services [enter a comma separated list of numbers or 'q' to quit]: ").trim();
214 if (answer.equalsIgnoreCase("q")) {
215 return null;
216 }
217 PluginListType list = new PluginListType();
218 for (String instance : answer.split(",")) {
219 int selection = Integer.parseInt(instance.trim());
220 PluginType target = available.get(selection - 1);
221 list.getPlugin().add(target);
222 }
223 if (repo != null) {
224 list.getDefaultRepository().add(repo);
225 }
226 return list;
227 }
228
229 public void installPlugins(GeronimoDeploymentManager mgr, PluginListType list, String defaultRepository, ConsoleReader consoleReader, ServerConnection connection) throws IOException, DeploymentException {
230 long start = System.currentTimeMillis();
231 Object key = mgr.startInstall(list, defaultRepository, false, null, null);
232 DownloadResults results = CommandInstallCAR.showProgress(consoleReader, mgr, key);
233 int time = (int) (System.currentTimeMillis() - start) / 1000;
234 CommandInstallCAR.printResults(consoleReader, results, time);
235 }
236
237 public void installPlugins(GeronimoDeploymentManager mgr, List<String> list, PluginListType all, String defaultRepository, ConsoleReader consoleReader, ServerConnection connection) throws IOException, DeploymentException {
238 PluginListType selected = getPluginsFromIds(list, all);
239 installPlugins(mgr, selected, defaultRepository, consoleReader, connection);
240 }
241
242 private static PluginListType getPluginsFromIds(List<String> configIds, PluginListType list) throws IllegalStateException {
243 PluginListType installList = new PluginListType();
244 for (String configId : configIds) {
245 PluginType plugin = null;
246 for (PluginType metadata : list.getPlugin()) {
247 for (PluginArtifactType testInstance : metadata.getPluginArtifact()) {
248 if (PluginInstallerGBean.toArtifact(testInstance.getModuleId()).toString().equals(configId)) {
249 plugin = PluginInstallerGBean.copy(metadata, testInstance);
250 installList.getPlugin().add(plugin);
251 break;
252 }
253 }
254 }
255 if (plugin == null) {
256 throw new IllegalStateException("No configuration found for '" + configId + "'");
257 }
258 }
259 return installList;
260 }
261
262
263 public void assembleServer(GeronimoDeploymentManager mgr, PluginListType list, String repositoryPath, String relativeServerPath, ConsoleReader consoleReader) throws Exception {
264 long start = System.currentTimeMillis();
265 DownloadResults results = mgr.installPluginList(repositoryPath, relativeServerPath, list);
266 int time = (int) (System.currentTimeMillis() - start) / 1000;
267 CommandInstallCAR.printResults(consoleReader, results, time);
268 }
269 public void assembleServer(GeronimoDeploymentManager mgr, List<String> list, PluginListType all, String repositoryPath, String relativeServerPath, ConsoleReader consoleReader) throws Exception {
270 PluginListType selected = getPluginsFromIds(list, all);
271 assembleServer(mgr, selected, repositoryPath, relativeServerPath, consoleReader);
272 }
273
274 }