/* * Copyright (c) 2004, KNOPFLERFISH project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * - Neither the name of the KNOPFLERFISH project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.knopflerfish.bundle.oscarshell; import org.knopflerfish.service.console.*; import org.ungoverned.osgi.service.shell.*; import java.io.*; import java.util.*; import org.osgi.framework.*; /** *
* Wrapper class that exposes all Oscar shell commands * as a singel Knopflerfish console command group. *
* ** This class will only get commands on demand (help and execute), and * will not keep them for longer than necessary. *
*/ public class OscarShellCommandGroup implements CommandGroup { /** * The group name is always "oscar" */ public String getGroupName() { return "oscar"; } public String getShortHelp() { return "Commands available via the Oscar shell API"; } /** * Build the long help text by listing all registered * Oscar commands. */ public String getLongHelp() { StringBuffer sb = new StringBuffer(); sb.append(getShortHelp()); sb.append("\n"); ServiceReference[] srl = getCommandReferences(null); if(srl.length == 0) { sb.append(" No Oscar commands installed\n"); } for(int i = 0; i < srl.length; i++) { StringBuffer line = new StringBuffer(); line.append(" "); try { Command cmd = (Command)Activator.bc.getService(srl[i]); line.append(cmd.getName()); while(line.length() < 12) { line.append(" "); } line.append(" - "); line.append(cmd.getShortDescription()); } catch (Exception e) { sb.append("Failed to get command service #" + srl[i].getProperty("service.id")); } finally { Activator.bc.ungetService(srl[i]); } sb.append(line.toString()); sb.append("\n"); } return sb.toString(); } /** ** Execute a single Oscar shell command by using the first * argument string as command name, try to get this command * service, (re)build the command line, and finally call * Command.execute *
** Arguments containing spaces are surrounded with " * before calling Command.execute *
** If the command does not exist, or fails, print this on the * output stream and return 1. *
*/ public int execute(String[] args, Reader in, PrintWriter out, Session session) { String name = args[0].trim(); ServiceReference[] srl = getCommandReferences(name); if(srl == null || srl.length == 0) { out.println("ERROR: No oscar command: " + name); return 1; } StringBuffer sb = new StringBuffer(); for(int i = 0; i < args.length; i++) { boolean bCit = -1 != args[i].indexOf(" "); if(bCit) { sb.append("\""); } sb.append(args[i]); if(bCit) { sb.append("\""); } if(i < args.length - 1) { sb.append(" "); } } try { Command cmd = (Command)Activator.bc.getService(srl[0]); // Create a wrapper stream for both output and error // streams ByteArrayOutputStream bout = new ByteArrayOutputStream(); PrintStream outStream = new PrintStream(bout); // ...and call the command cmd.execute(sb.toString(),outStream, outStream); // grab the resulting string and feed it to the console String result = bout.toString(); out.println(result); } catch (Exception e) { out.println("Failed to call " + args[0] + ": " + e); return 1; } finally { // alway unget the service Activator.bc.getService(srl[0]); } return 0; } /** ** Get the currently registered Oscar Command services matching a * given name. *
* * @param name name of command to get. If null, return * all commands. * @return array of ServiceReference to Command services. Zero * services is representes by a zero.sized array. * */ protected ServiceReference[] getCommandReferences(String name) { String filter = "(objectclass=" + Command.class.getName() + ")"; ServiceReference[] srl = null; Vector v = new Vector(); try { // Get all services, then filter if necessary. srl = Activator.bc.getServiceReferences(null, filter); if(name != null) { for(int i = 0; srl != null && i < srl.length; i++) { Command cmd = (Command)Activator.bc.getService(srl[i]); if(name.equals(cmd.getName())) { v.addElement(srl[i]); } } srl = new ServiceReference[v.size()]; v.copyInto(srl); } } catch(InvalidSyntaxException e) { throw new RuntimeException("Bad filter: " + filter + ", " + e); } if(srl == null) { srl = new ServiceReference[0]; } return srl; } }