/** * Copyright (C) 2010-2017 Structr GmbH * * This file is part of Structr <http://structr.org>. * * Structr is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * Structr is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Structr. If not, see <http://www.gnu.org/licenses/>. */ package org.structr.websocket.command; import com.google.gson.JsonArray; import com.google.gson.JsonPrimitive; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.List; import org.apache.commons.io.output.ByteArrayOutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.structr.common.VersionHelper; import org.structr.console.Console; import org.structr.console.tabcompletion.TabCompletionResult; import org.structr.util.Writable; import org.structr.websocket.StructrWebSocket; import org.structr.websocket.message.MessageBuilder; import org.structr.websocket.message.WebSocketMessage; //~--- classes ---------------------------------------------------------------- /** * Command to interact with a multi-mode server console. */ public class ConsoleCommand extends AbstractCommand { private static final Logger logger = LoggerFactory.getLogger(ConsoleCommand.class.getName()); static { StructrWebSocket.addCommand(ConsoleCommand.class); } @Override public void processMessage(final WebSocketMessage webSocketData) { final String sessionId = webSocketData.getSessionId(); logger.debug("CONSOLE received from session {}", sessionId); final String line = (String) webSocketData.getNodeData().get("line"); final Boolean completion = (Boolean) webSocketData.getNodeData().get("completion"); final Console console = getWebSocket().getConsole(); ByteArrayOutputStream out = new ByteArrayOutputStream(); OutputStreamWritable writeable = new OutputStreamWritable(out); try { if (Boolean.TRUE.equals(completion)) { final List<TabCompletionResult> tabCompletionResult = console.getTabCompletion(line); final JsonArray commands = new JsonArray(); for (final TabCompletionResult res : tabCompletionResult) { commands.add(new JsonPrimitive(res.getCommand())); } getWebSocket().send(MessageBuilder.forName(getCommand()) .callback(webSocketData.getCallback()) .data("commands", commands) .data("prompt", console.getPrompt()) .data("mode", console.getMode()) .data("versionInfo", VersionHelper.getFullVersionInfo()) .message(out.toString("UTF-8")) .build(), true); } else { console.run(line, writeable); getWebSocket().send(MessageBuilder.forName(getCommand()) .callback(webSocketData.getCallback()) .data("prompt", console.getPrompt()) .data("mode", console.getMode()) .data("versionInfo", VersionHelper.getFullVersionInfo()) .message(out.toString("UTF-8")) .build(), true); } } catch (Exception ex) { logger.debug("Error while executing console line {}", line, ex); getWebSocket().send(MessageBuilder.forName(getCommand()) .callback(webSocketData.getCallback()) .data("mode", console.getMode()) .data("versionInfo", VersionHelper.getFullVersionInfo()) .message(ex.getMessage()) .build(), true); } } @Override public boolean requiresEnclosingTransaction() { return false; } //~--- get methods ---------------------------------------------------- @Override public String getCommand() { return "CONSOLE"; } // ----- nested classes ----- private static class OutputStreamWritable implements Writable { private Writer writer = null; public OutputStreamWritable(final OutputStream out) { this.writer = new OutputStreamWriter(out); } @Override public void print(final Object... text) throws IOException { if (text != null) { for (final Object o : text) { if (o != null) { writer.write(o.toString().replaceAll("\n", "\r\n")); } else { writer.write("null"); } } } writer.flush(); } @Override public void println(final Object... text) throws IOException { print(text); println(); writer.flush(); } @Override public void println() throws IOException { writer.write(10); writer.write(13); } @Override public void flush() throws IOException { writer.flush(); } } }