001/* 002 * (C) Copyright 2006-2010 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * bstefanescu 016 */ 017package org.nuxeo.shell.equinox; 018 019import java.io.IOException; 020import java.io.InputStreamReader; 021import java.io.PrintWriter; 022import java.io.Reader; 023import java.net.Socket; 024import java.util.ArrayList; 025 026import org.nuxeo.shell.ShellException; 027import org.nuxeo.shell.cmds.Interactive; 028import org.nuxeo.shell.utils.StringUtils; 029 030/** 031 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 032 */ 033public class Connector { 034 035 protected String[] commands; 036 037 protected Socket socket; 038 039 protected Reader in; 040 041 protected PrintWriter out; 042 043 public static Connector newConnector(String address) { 044 int p = address.indexOf(':'); 045 if (p == -1) { 046 throw new ShellException("Illegal address '" + address + "'. Must be in format 'host:port'"); 047 } 048 return new Connector(address.substring(0, p), Integer.parseInt(address.substring(p + 1))); 049 } 050 051 public Connector(String host, int port) { 052 try { 053 socket = new Socket(host, port); 054 socket.setReuseAddress(true); 055 in = new InputStreamReader(socket.getInputStream()); 056 out = new PrintWriter(socket.getOutputStream()); 057 initConnection(); 058 } catch (Exception e) { 059 throw new ShellException("Failed to connect to " + host + ':' + port); 060 } 061 } 062 063 protected void initConnection() throws IOException { 064 readAll(); 065 String r = send("help"); 066 String[] lines = StringUtils.split(r, '\n', true); 067 ArrayList<String> cmds = new ArrayList<String>(); 068 for (String line : lines) { 069 if (line.length() == 0 || line.startsWith("---")) { 070 continue; 071 } 072 int i = line.indexOf(' '); 073 cmds.add(line.substring(0, i)); 074 } 075 commands = cmds.toArray(new String[cmds.size()]); 076 } 077 078 public String[] getBundles() { 079 String r = send("ss"); 080 String[] lines = StringUtils.split(r, '\n', true); 081 ArrayList<String> bundles = new ArrayList<String>(); 082 for (String line : lines) { 083 if (line.length() == 0 || line.startsWith("id")) { 084 continue; 085 } 086 String[] ar = line.split("\\s"); 087 String b = ar[ar.length - 1]; 088 int i = b.indexOf('_'); 089 if (i > -1) { 090 b = b.substring(0, i); 091 } 092 bundles.add(b); 093 } 094 return bundles.toArray(new String[bundles.size()]); 095 } 096 097 public String[] getCommands() { 098 return commands; 099 } 100 101 public Reader getIn() { 102 return in; 103 } 104 105 public PrintWriter getOut() { 106 return out; 107 } 108 109 public void println(String text) { 110 out.println(text); 111 out.flush(); 112 } 113 114 public void println() { 115 out.println(); 116 out.flush(); 117 } 118 119 public String sendCurrentCommand() { 120 return send(Interactive.getCurrentCmdLine()); 121 } 122 123 public String send(String command) { 124 try { 125 println(command); 126 return readAll(); 127 } catch (IOException e) { 128 throw new ShellException("Failed to read response", e); 129 } 130 } 131 132 /** 133 * Get the response and remove the ending "osgi>" if present - also trim the string before returning. (CRLF is not 134 * included at the end) 135 * 136 * @return 137 * @throws IOException 138 */ 139 public String readAll() throws IOException { 140 StringBuilder result = new StringBuilder(); 141 char[] cbuf = new char[4096]; 142 int r = in.read(cbuf); 143 while (r > 0) { 144 result.append(new String(cbuf, 0, r)); 145 if (result.lastIndexOf("osgi> ") == result.length() - "osgi> ".length()) { 146 break; 147 } 148 r = in.read(cbuf); 149 } 150 String str = result.toString().trim(); 151 if (str.endsWith("osgi>")) { 152 str = str.substring(0, str.length() - "osgi>".length()); 153 str = str.trim(); 154 } 155 return str; 156 } 157 158 public void disconnect() { 159 try { 160 socket.close(); 161 } catch (Exception e) { 162 throw new ShellException("Failed to disconnect", e); 163 } 164 } 165 166 public Socket getSocket() { 167 return socket; 168 } 169 170}