Server.java
Home
/
src /
main /
java /
br /
ufrgs /
inf /
prosoft /
remoteexecutor /
Server.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package br.ufrgs.inf.prosoft.remoteexecutor;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
/**
*
* @author romulo
*/
public class Server {
private static final Logger LOGGER = Logger.getLogger(Server.class.getName());
private static class Tokenizer {
private int index;
private final String string;
public Tokenizer(String string) {
this.index = 0;
this.string = string;
}
public static List<String> split(String string) {
Tokenizer tokenizer = new Tokenizer(string);
List<String> list = new ArrayList<>();
while (tokenizer.hasMoreTokens()) {
list.add(tokenizer.getNextToken());
}
return list;
}
private boolean hasMoreTokens() {
if (this.string == null) {
return false;
}
if (this.string.isEmpty()) {
return false;
}
return this.index < string.length();
}
private String getNextToken() {
if (!hasMoreTokens()) {
return null;
}
while (this.index < this.string.length() && this.string.charAt(this.index) == ' ') {
this.index++;
}
char quoted = ' ';
int baseIndex = this.index;
while (this.index < this.string.length()) {
char nextChar = this.string.charAt(this.index);
if (nextChar == ' ' && quoted == ' ') {
break;
}
this.index++;
if (nextChar == '\'' || nextChar == '\"') {
if (quoted == ' ') {
quoted = nextChar;
} else if (nextChar == quoted) {
break;
}
}
}
return this.string.substring(baseIndex, this.index);
}
}
public static void listen(File home, int port) {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port);
LOGGER.log(Level.INFO, "start listening on port " + port);
boolean exit = false;
while (!exit) {
Socket socket = null;
InputStream inputStream = null;
OutputStream outputStream = null;
try {
socket = serverSocket.accept();
inputStream = socket.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String message = bufferedReader.readLine();
if (message == null) {
message = "";
}
LOGGER.log(Level.INFO, "> {0}", message);
if (message.startsWith("caching-approaches-comparison ")) {
String command = message.replaceFirst("caching-approaches-comparison ", "");
if (command.equals("exit")) {
exit = true;
} else {
try {
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.directory(home);
List<String> commandList = Tokenizer.split(command)
.stream().map(string -> {
if (string.charAt(0) == '\"' || string.charAt(0) == '\'') {
string = string.substring(1, string.length());
}
if (string.charAt(string.length()- 1) == '\"' || string.charAt(string.length()- 1) == '\'') {
string = string.substring(0, string.length()- 1);
}
return string;
}).collect(Collectors.toList());
for (Iterator<String> iterator = commandList.iterator(); iterator.hasNext();) {
String export = iterator.next();
if (!export.contains("=")) {
break;
}
String[] map = export.split("=");
if (map.length > 1) {
processBuilder.environment().put(map[0], map[1]);
} else {
processBuilder.environment().put(map[0], "");
}
iterator.remove();
}
processBuilder.command(commandList);
processBuilder.inheritIO();
processBuilder.start();
} catch (Exception ex) {
LOGGER.log(Level.WARNING, ex.getMessage());
message = "command failed";
}
}
}
message = "[RemoteExecutor] " + message;
LOGGER.log(Level.INFO, "< {0}", message);
message += "\n";
outputStream = socket.getOutputStream();
outputStream.write(message.getBytes());
} catch (IOException ex) {
LOGGER.log(Level.WARNING, "connection closed before echo is sent");
} catch (Exception ex) {
LOGGER.log(Level.WARNING, "exception: {0}", ex);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException ex) {
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException ex) {
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException ex) {
}
}
}
}
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, "port " + port + " is busy");
} finally {
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException ex) {
}
}
}
}
}