diff --git a/src/main/scala/com/neowit/apex/Runner.scala b/src/main/scala/com/neowit/apex/Runner.scala
index db04ce34..6e263ffe 100644
--- a/src/main/scala/com/neowit/apex/Runner.scala
+++ b/src/main/scala/com/neowit/apex/Runner.scala
@@ -62,7 +62,7 @@ class Executor extends Logging {
} catch {
case ex: InvalidCommandLineException =>
if (null != ex.getMessage) {
- basicConfig.getResponseWriter.send(ex.getMessage)
+ basicConfig.getResponseWriter.sendError("Invalid parameter: ", ex)
logger.error(ex.getMessage)
}
basicConfig.help()
@@ -78,7 +78,7 @@ class Executor extends Logging {
System.out.println(stackTraceStr)
*/
if (ex.message.nonEmpty) {
- basicConfig.getResponseWriter.send(ex.message)
+ basicConfig.getResponseWriter.sendError("", ex)
logger.error(ex.message)
}
help(ex.help)
diff --git a/src/main/scala/com/neowit/apex/lsp/ApexLanguageServerBase.scala b/src/main/scala/com/neowit/apex/lsp/ApexLanguageServerBase.scala
index a3469eb8..d771d245 100644
--- a/src/main/scala/com/neowit/apex/lsp/ApexLanguageServerBase.scala
+++ b/src/main/scala/com/neowit/apex/lsp/ApexLanguageServerBase.scala
@@ -27,6 +27,7 @@ import com.neowit.apex.{Executor, ProjectsCache, Session}
import com.neowit.apexscanner.Project
import com.neowit.apexscanner.server.LanguageServerDefault
import com.neowit.apexscanner.server.protocol.messages._
+import com.neowit.response.protocols.lsp.ResponseWriterLsp
import com.neowit.utils.{BasicConfig, FileUtils}
import scala.concurrent.{ExecutionContext, Future}
@@ -132,20 +133,40 @@ class ApexLanguageServerBase(inputStream: InputStream, outputStream: OutputStrea
}
}
- override def executeCommand(messageId: Int, params: MessageParams.ExecuteCommandParams, projectOpt: Option[Project]): Future[Either[ResponseError, ResponseMessage]] = {
- logger.debug("execute command: " + params.command + " with arguments: " + params.arguments + " in project: " + projectOpt.map(_.path).getOrElse(""))
+ override def executeCommand(messageId: Int, params: MessageParams.ExecuteCommandParams, projectOpt: Option[Project]): Future[ResponseMessage] = {
+ val logMsg = "execute command: " + params.command + " with arguments: " + params.arguments + " in project: " + projectOpt.map(_.path).getOrElse("")
+ logger.debug(logMsg)
+ sendLogMessageNotification(MessageType.Log, logMsg)
+
val commandLineArgsMap: Map[String, String] = messageParamsToMap(params, projectOpt)
+ val responseWriter = new ResponseWriterLsp(messageId, this)
val runner = new Executor()
-
+ runner.basicConfig.setResponseWriter(responseWriter)
runner.execute(commandLineArgsMap)
- super.executeCommand(messageId, params, projectOpt)
+ responseWriter.result() match {
+ case Some(msg) =>
+ Future.successful(msg)
+ case None =>
+ Future.successful(ResponseMessage(messageId, result = None, error = None))
+ }
}
- override def executeCommand(messageId: Int, command: String): Future[Either[ResponseError, ResponseMessage]] = {
- logger.debug("execute command: " + command + " without arguments")
+ override def executeCommand(messageId: Int, command: String): Future[ResponseMessage] = {
+ val logMsg = "execute command: " + command + " without arguments"
+ logger.debug(logMsg)
+ sendLogMessageNotification(MessageType.Log, logMsg)
+
val commandLineArgs: Array[String] = Array("--action=" + command)
+ val responseWriter = new ResponseWriterLsp(messageId, this)
+
val runner = new Executor()
+ runner.basicConfig.setResponseWriter(responseWriter)
runner.execute(commandLineArgs)
- Future.successful(Right(ResponseMessage(messageId, result = None, error = None)))
+ responseWriter.result() match {
+ case Some(msg) =>
+ Future.successful(msg)
+ case None =>
+ Future.successful(ResponseMessage(messageId, result = None, error = None))
+ }
}
private def messageParamsToMap(params: MessageParams.ExecuteCommandParams, projectOpt: Option[Project]): Map[String, String] = {
diff --git a/src/main/scala/com/neowit/response/ResponseWriter.scala b/src/main/scala/com/neowit/response/ResponseWriter.scala
index 2c799c7e..4f98cfe8 100644
--- a/src/main/scala/com/neowit/response/ResponseWriter.scala
+++ b/src/main/scala/com/neowit/response/ResponseWriter.scala
@@ -22,7 +22,7 @@ package com.neowit.response
import java.io.File
import com.neowit.apex.actions.ActionResult
-import com.neowit.utils.{FileUtils, JsonSupport, Logging}
+import com.neowit.utils.{FileUtils, Logging}
object ResponseWriter {
@@ -74,10 +74,13 @@ object ResponseWriter {
}
-trait ResponseWriter extends Logging with JsonSupport {
+trait ResponseWriter extends Logging {
def sendResponse(result: ActionResult): Unit
def send(msg: Message): Message
+ def sendError(msg: String, ex: Exception): Unit = {
+ send(msg + " " + ex.getMessage)
+ }
def send(msg: String): Unit
def send(msg: RESULT): Unit
diff --git a/src/main/scala/com/neowit/response/protocols/lsp/AppVersion.scala b/src/main/scala/com/neowit/response/protocols/lsp/AppVersion.scala
new file mode 100644
index 00000000..51939bf5
--- /dev/null
+++ b/src/main/scala/com/neowit/response/protocols/lsp/AppVersion.scala
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018 Andrey Gavrikov.
+ * this file is part of tooling-force.com application
+ * https://github.com/neowit/tooling-force.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.neowit.response.protocols.lsp
+
+import com.neowit.apex.actions.ActionSuccess
+import com.neowit.response._
+
+class AppVersion(writer: ResponseWriterLsp) extends LspProtocol[AppVersionResult] {
+ def send(result: AppVersionResult): Unit = {
+ val msg =
+ result.appName + " - version: " + result.appVersion +
+ "; SFDC API Version: " + result.sfdcApiVersion +
+ "; java: " + result.javaVersion +
+ "; OS: " + result.os
+
+ writer.sendResponse(ActionSuccess(msg))
+
+ val mb = 1024*1024
+ val runtime = Runtime.getRuntime
+
+ writer.debug( s"Used Memory: ${(runtime.totalMemory - runtime.freeMemory) / mb} MB")
+ writer.debug( s"Free Memory: ${runtime.freeMemory / mb} MB")
+ writer.debug( s"Total Memory: ${runtime.totalMemory / mb} MB")
+ writer.debug( s"Max Memory: ${runtime.maxMemory / mb} MB")
+ }
+}
diff --git a/src/main/scala/com/neowit/response/protocols/lsp/ResponseWriterLsp.scala b/src/main/scala/com/neowit/response/protocols/lsp/ResponseWriterLsp.scala
new file mode 100644
index 00000000..40ce8327
--- /dev/null
+++ b/src/main/scala/com/neowit/response/protocols/lsp/ResponseWriterLsp.scala
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018 Andrey Gavrikov.
+ * this file is part of tooling-force.com application
+ * https://github.com/neowit/tooling-force.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.neowit.response.protocols.lsp
+
+import java.io.{PrintWriter, StringWriter}
+
+import com.neowit.apex.actions.{ActionFailure, ActionResult, ActionSuccess}
+import com.neowit.apexscanner.server.protocol.LanguageServer
+import com.neowit.apexscanner.server.protocol.messages._
+import com.neowit.response
+import com.neowit.response.{BaseResult, RESULT, ResponseWriter}
+import com.neowit.utils.Logging
+
+import io.circe.syntax._
+/**
+ * Created by Andrey Gavrikov
+ */
+trait LspProtocol[A <: BaseResult] {
+ def send(result: A): Unit
+}
+class ResponseWriterLsp(messageId: Int, server: LanguageServer) extends ResponseWriter with Logging with MessageJsonSupport {
+ private var _responseMessage: Option[ResponseMessage] = None
+
+ override def sendResponse(result: ActionResult): Unit = {
+ // TODO - implement proper handling of messages and resultOpt
+
+ result match {
+ case ActionSuccess(messages, resultOpt) =>
+ val totalMessage = messages.mkString("; ")
+ _responseMessage = Option(ResponseMessage(messageId, result = Option(totalMessage.asJson), error = None))
+ case ActionFailure(messages, resultOpt) =>
+ val totalMessage = messages.mkString("; ")
+ val error = ResponseError(0, totalMessage, messageId = Option(messageId))
+ _responseMessage = Option(ResponseMessage(messageId, result = None, Option(error)))
+ }
+ }
+
+ override def send(msg: response.Message): response.Message = throw new UnsupportedOperationException
+
+ override def send(msg: String): Unit = throw new UnsupportedOperationException
+
+ override def send(msg: RESULT): Unit = throw new UnsupportedOperationException
+
+ override def sendError(msg: String, ex: Exception): Unit = {
+ val sw = new StringWriter
+ ex.printStackTrace(new PrintWriter(sw))
+ val stackTraceStr = sw.toString
+ // dump exception information to log
+ logger.error(ex.getMessage)
+ logger.error(stackTraceStr)
+
+ val err = ResponseError(0, msg + ex.getMessage + "\n" + stackTraceStr)
+ _responseMessage = Option(ResponseMessage(messageId, result = None, error = Option(err)))
+ }
+
+ override def close(): Unit = ()
+
+ def debug(msg: String): Unit = {
+ server.sendLogMessageNotification(MessageType.Log, msg)
+ }
+
+ def result(): Option[ResponseMessage] = _responseMessage
+}