001/* 002 * (C) Copyright 2006-2010 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * bstefanescu 018 */ 019package org.nuxeo.shell.equinox; 020 021import java.io.IOException; 022import java.io.InputStreamReader; 023import java.io.PrintWriter; 024import java.io.Reader; 025import java.net.Socket; 026import java.util.ArrayList; 027 028import org.nuxeo.shell.ShellException; 029import org.nuxeo.shell.cmds.Interactive; 030import org.nuxeo.shell.utils.StringUtils; 031 032/** 033 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 034 */ 035public class Connector { 036 037 protected String[] commands; 038 039 protected Socket socket; 040 041 protected Reader in; 042 043 protected PrintWriter out; 044 045 public static Connector newConnector(String address) { 046 int p = address.indexOf(':'); 047 if (p == -1) { 048 throw new ShellException("Illegal address '" + address + "'. Must be in format 'host:port'"); 049 } 050 return new Connector(address.substring(0, p), Integer.parseInt(address.substring(p + 1))); 051 } 052 053 public Connector(String host, int port) { 054 try { 055 socket = new Socket(host, port); 056 socket.setReuseAddress(true); 057 in = new InputStreamReader(socket.getInputStream()); 058 out = new PrintWriter(socket.getOutputStream()); 059 initConnection(); 060 } catch (Exception e) { 061 throw new ShellException("Failed to connect to " + host + ':' + port); 062 } 063 } 064 065 protected void initConnection() throws IOException { 066 readAll(); 067 String r = send("help"); 068 String[] lines = StringUtils.split(r, '\n', true); 069 ArrayList<String> cmds = new ArrayList<String>(); 070 for (String line : lines) { 071 if (line.length() == 0 || line.startsWith("---")) { 072 continue; 073 } 074 int i = line.indexOf(' '); 075 cmds.add(line.substring(0, i)); 076 } 077 commands = cmds.toArray(new String[cmds.size()]); 078 } 079 080 public String[] getBundles() { 081 String r = send("ss"); 082 String[] lines = StringUtils.split(r, '\n', true); 083 ArrayList<String> bundles = new ArrayList<String>(); 084 for (String line : lines) { 085 if (line.length() == 0 || line.startsWith("id")) { 086 continue; 087 } 088 String[] ar = line.split("\\s"); 089 String b = ar[ar.length - 1]; 090 int i = b.indexOf('_'); 091 if (i > -1) { 092 b = b.substring(0, i); 093 } 094 bundles.add(b); 095 } 096 return bundles.toArray(new String[bundles.size()]); 097 } 098 099 public String[] getCommands() { 100 return commands; 101 } 102 103 public Reader getIn() { 104 return in; 105 } 106 107 public PrintWriter getOut() { 108 return out; 109 } 110 111 public void println(String text) { 112 out.println(text); 113 out.flush(); 114 } 115 116 public void println() { 117 out.println(); 118 out.flush(); 119 } 120 121 public String sendCurrentCommand() { 122 return send(Interactive.getCurrentCmdLine()); 123 } 124 125 public String send(String command) { 126 try { 127 println(command); 128 return readAll(); 129 } catch (IOException e) { 130 throw new ShellException("Failed to read response", e); 131 } 132 } 133 134 /** 135 * Get the response and remove the ending "osgi>" if present - also trim the string before returning. (CRLF is not 136 * included at the end) 137 * 138 * @return 139 * @throws IOException 140 */ 141 public String readAll() throws IOException { 142 StringBuilder result = new StringBuilder(); 143 char[] cbuf = new char[4096]; 144 int r = in.read(cbuf); 145 while (r > 0) { 146 result.append(new String(cbuf, 0, r)); 147 if (result.lastIndexOf("osgi> ") == result.length() - "osgi> ".length()) { 148 break; 149 } 150 r = in.read(cbuf); 151 } 152 String str = result.toString().trim(); 153 if (str.endsWith("osgi>")) { 154 str = str.substring(0, str.length() - "osgi>".length()); 155 str = str.trim(); 156 } 157 return str; 158 } 159 160 public void disconnect() { 161 try { 162 socket.close(); 163 } catch (Exception e) { 164 throw new ShellException("Failed to disconnect", e); 165 } 166 } 167 168 public Socket getSocket() { 169 return socket; 170 } 171 172}