Skip to content
This repository was archived by the owner on Aug 18, 2020. It is now read-only.

Commit 671fb63

Browse files
committed
Merge branch 'in-out-impl'
2 parents e05ada0 + 193aef0 commit 671fb63

File tree

10 files changed

+225
-153
lines changed

10 files changed

+225
-153
lines changed

src/main/scala/org/codeoverflow/chatoverflow/configuration/ConfigurationService.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package org.codeoverflow.chatoverflow.configuration
22

3-
import java.io.File
3+
import java.io.{File, PrintWriter}
44

55
import org.codeoverflow.chatoverflow.WithLogger
66
import org.codeoverflow.chatoverflow.api.io
@@ -10,7 +10,7 @@ import org.codeoverflow.chatoverflow.framework.PluginFramework
1010
import org.codeoverflow.chatoverflow.instance.PluginInstanceRegistry
1111
import org.codeoverflow.chatoverflow.registry.TypeRegistry
1212

13-
import scala.xml.{Elem, Node}
13+
import scala.xml.{Elem, Node, PrettyPrinter}
1414

1515
/**
1616
* The configuration service provides methods to work with serialized state information.
@@ -153,7 +153,9 @@ class ConfigurationService(val configFilePath: String) extends WithLogger {
153153
* Saves the xml content to the config xml.
154154
*/
155155
private def saveXML(xmlContent: Node): Unit = {
156-
xml.XML.save(configFilePath, xmlContent)
156+
val writer = new PrintWriter(configFilePath)
157+
writer.print(new PrettyPrinter(120,2).format(xmlContent))
158+
writer.close()
157159
logger info "Saved config file."
158160
}
159161

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.codeoverflow.chatoverflow.requirement
2+
3+
import org.codeoverflow.chatoverflow.WithLogger
4+
import org.codeoverflow.chatoverflow.api.io.input.Input
5+
import org.codeoverflow.chatoverflow.connector.Connector
6+
7+
import scala.reflect.ClassTag
8+
9+
abstract class InputImpl[C <: Connector](implicit ct: ClassTag[C]) extends Connection[C] with Input with WithLogger {
10+
11+
/**
12+
* Inits this connection, checks if teh source connector is defined, and can be inited, then calls start
13+
*
14+
* @return if this input could be successfully inited
15+
*/
16+
override def init(): Boolean = {
17+
if (sourceConnector.isDefined) {
18+
if (sourceConnector.get.init()) {
19+
start()
20+
} else false
21+
} else {
22+
logger warn "Source connector not set."
23+
false
24+
}
25+
}
26+
27+
28+
/**
29+
* Start the input, called after source connector did init
30+
*
31+
* @return true if starting the input was successful, false if some problems occurred
32+
*/
33+
def start(): Boolean
34+
35+
36+
/**
37+
* Serializes this object into a string to save it to a config
38+
*
39+
* @return serialized
40+
*/
41+
override def serialize(): String = getSourceIdentifier
42+
43+
/**
44+
* Deserialize a string to apply provided config settings to this object
45+
*
46+
* @param value should be serialized
47+
*/
48+
override def deserialize(value: String): Unit = setSourceConnector(value)
49+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.codeoverflow.chatoverflow.requirement
2+
3+
import org.codeoverflow.chatoverflow.WithLogger
4+
import org.codeoverflow.chatoverflow.api.io.output.Output
5+
import org.codeoverflow.chatoverflow.connector.Connector
6+
7+
import scala.reflect.ClassTag
8+
9+
abstract class OutputImpl[C <: Connector](implicit ct: ClassTag[C]) extends Connection[C] with Output with WithLogger {
10+
11+
/**
12+
* Inits this connection, checks if teh source connector is defined, and can be inited, then calls start
13+
*
14+
* @return if this input could be successfully inited
15+
*/
16+
override def init(): Boolean = {
17+
if (sourceConnector.isDefined) {
18+
if (sourceConnector.get.init()) {
19+
start()
20+
} else false
21+
} else {
22+
logger warn "Source connector not set."
23+
false
24+
}
25+
}
26+
27+
28+
/**
29+
* Start the input, called after source connector did init
30+
*
31+
* @return true if starting the input was successful, false if some problems occurred
32+
*/
33+
def start(): Boolean
34+
35+
36+
/**
37+
* Serializes this object into a string to save it to a config
38+
*
39+
* @return serialized
40+
*/
41+
override def serialize(): String = getSourceIdentifier
42+
43+
/**
44+
* Deserialize a string to apply provided config settings to this object
45+
*
46+
* @param value should be serialized
47+
*/
48+
override def deserialize(value: String): Unit = setSourceConnector(value)
49+
}

src/main/scala/org/codeoverflow/chatoverflow/requirement/service/discord/impl/DiscordChatInputImpl.scala

Lines changed: 50 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
package org.codeoverflow.chatoverflow.requirement.service.discord.impl
22

3-
import java.awt.Color
43
import java.util
54
import java.util.Calendar
65
import java.util.function.{BiConsumer, Consumer}
76

8-
import net.dv8tion.jda.api.entities.{ChannelType, Message, MessageType, PrivateChannel, TextChannel}
7+
import net.dv8tion.jda.api.entities._
98
import net.dv8tion.jda.api.events.message.{MessageDeleteEvent, MessageReceivedEvent, MessageUpdateEvent}
109
import org.codeoverflow.chatoverflow.WithLogger
1110
import org.codeoverflow.chatoverflow.api.io.dto.chat.discord.{DiscordChannel, DiscordChatCustomEmoticon, DiscordChatMessage, DiscordChatMessageAuthor}
1211
import org.codeoverflow.chatoverflow.api.io.input.chat.DiscordChatInput
1312
import org.codeoverflow.chatoverflow.registry.Impl
14-
import org.codeoverflow.chatoverflow.requirement.Connection
13+
import org.codeoverflow.chatoverflow.requirement.InputImpl
1514
import org.codeoverflow.chatoverflow.requirement.service.discord.DiscordChatConnector
1615

1716
import scala.collection.JavaConverters._
@@ -21,9 +20,9 @@ import scala.collection.mutable.ListBuffer
2120
* This is the implementation of the discord chat input, using the discord connector.
2221
*/
2322
@Impl(impl = classOf[DiscordChatInput], connector = classOf[DiscordChatConnector])
24-
class DiscordChatInputImpl extends Connection[DiscordChatConnector] with DiscordChatInput with WithLogger {
23+
class DiscordChatInputImpl extends InputImpl[DiscordChatConnector] with DiscordChatInput with WithLogger {
2524

26-
private var channelId = getSourceIdentifier
25+
private var channelId: Option[String] = None
2726
private val messages: ListBuffer[DiscordChatMessage] = ListBuffer[DiscordChatMessage]()
2827
private val privateMessages: ListBuffer[DiscordChatMessage] = ListBuffer[DiscordChatMessage]()
2928
private val messageHandler = ListBuffer[Consumer[DiscordChatMessage]]()
@@ -33,19 +32,11 @@ class DiscordChatInputImpl extends Connection[DiscordChatConnector] with Discord
3332
private val privateMessageEditHandler = ListBuffer[BiConsumer[DiscordChatMessage, DiscordChatMessage]]()
3433
private val privateMessageDeleteHandler = ListBuffer[Consumer[DiscordChatMessage]]()
3534

36-
override def init(): Boolean = {
37-
if (sourceConnector.isDefined) {
38-
if (sourceConnector.get.isRunning || sourceConnector.get.init()) {
39-
setChannel(getSourceIdentifier)
40-
sourceConnector.get.addMessageReceivedListener(onMessage)
41-
sourceConnector.get.addMessageUpdateListener(onMessageUpdate)
42-
sourceConnector.get.addMessageDeleteListener(onMessageDelete)
43-
true
44-
} else false
45-
} else {
46-
logger warn "Source connector not set."
47-
false
48-
}
35+
override def start(): Boolean = {
36+
sourceConnector.get.addMessageReceivedListener(onMessage)
37+
sourceConnector.get.addMessageUpdateListener(onMessageUpdate)
38+
sourceConnector.get.addMessageDeleteListener(onMessageDelete)
39+
true
4940
}
5041

5142
/**
@@ -55,15 +46,17 @@ class DiscordChatInputImpl extends Connection[DiscordChatConnector] with Discord
5546
*/
5647
private def onMessage(event: MessageReceivedEvent): Unit = {
5748
if (event.getMessage.getType == MessageType.DEFAULT) {
58-
val message = DiscordChatInputImpl.parse(event.getMessage)
59-
event.getChannelType match {
60-
case ChannelType.TEXT if event.getTextChannel.getId == channelId =>
61-
messageHandler.foreach(_.accept(message))
62-
messages += message
63-
case ChannelType.PRIVATE =>
64-
privateMessageHandler.foreach(_.accept(message))
65-
privateMessages += message
66-
case _ => //Unknown channel, do nothing
49+
if (channelId.isDefined) {
50+
val message = DiscordChatInputImpl.parse(event.getMessage)
51+
event.getChannelType match {
52+
case ChannelType.TEXT if event.getTextChannel.getId == channelId.get =>
53+
messageHandler.foreach(_.accept(message))
54+
messages += message
55+
case ChannelType.PRIVATE =>
56+
privateMessageHandler.foreach(_.accept(message))
57+
privateMessages += message
58+
case _ => //Unknown channel, do nothing
59+
}
6760
}
6861
}
6962
}
@@ -102,20 +95,22 @@ class DiscordChatInputImpl extends Connection[DiscordChatConnector] with Discord
10295
* @param event a event with an deleted message
10396
*/
10497
private def onMessageDelete(event: MessageDeleteEvent): Unit = {
105-
val id = event.getMessageId
106-
event.getChannelType match {
107-
case ChannelType.TEXT if event.getTextChannel.getId == channelId =>
108-
val i = messages.indexWhere(_.getId == id)
109-
if (i != -1) {
110-
val oldMessage = messages.remove(i)
111-
messageDeleteHandler.foreach(_.accept(oldMessage))
112-
}
113-
case ChannelType.PRIVATE =>
114-
val i = privateMessages.indexWhere(_.getId == id)
115-
if (i != -1) {
116-
val oldMessage = privateMessages.remove(i)
117-
privateMessageDeleteHandler.foreach(_.accept(oldMessage))
118-
}
98+
if (channelId.isDefined) {
99+
val id = event.getMessageId
100+
event.getChannelType match {
101+
case ChannelType.TEXT if event.getTextChannel.getId == channelId.get =>
102+
val i = messages.indexWhere(_.getId == id)
103+
if (i != -1) {
104+
val oldMessage = messages.remove(i)
105+
messageDeleteHandler.foreach(_.accept(oldMessage))
106+
}
107+
case ChannelType.PRIVATE =>
108+
val i = privateMessages.indexWhere(_.getId == id)
109+
if (i != -1) {
110+
val oldMessage = privateMessages.remove(i)
111+
privateMessageDeleteHandler.foreach(_.accept(oldMessage))
112+
}
113+
}
119114
}
120115
}
121116

@@ -130,32 +125,35 @@ class DiscordChatInputImpl extends Connection[DiscordChatConnector] with Discord
130125

131126
privateMessages.filter(_.getTimestamp > currentTime - lastMilliseconds).toList.asJava
132127
}
133-
override def registerMessageHandler(handler: Consumer[DiscordChatMessage]): Unit = messageHandler += handler
128+
override def registerMessageHandler(handler: Consumer[DiscordChatMessage]): Unit = {
129+
if (channelId.isEmpty) throw new IllegalStateException("first set the channel for this input")
130+
messageHandler += handler
131+
}
134132

135133
override def registerPrivateMessageHandler(handler : Consumer[DiscordChatMessage]): Unit = privateMessageHandler += handler
136134

137-
override def registerMessageEditHandler(handler: BiConsumer[DiscordChatMessage, DiscordChatMessage]): Unit = messageEditHandler += handler
135+
override def registerMessageEditHandler(handler: BiConsumer[DiscordChatMessage, DiscordChatMessage]): Unit = {
136+
if (channelId.isEmpty) throw new IllegalStateException("first set the channel for this input")
137+
messageEditHandler += handler
138+
}
138139

139140
override def registerPrivateMessageEditHandler(handler: BiConsumer[DiscordChatMessage, DiscordChatMessage]): Unit = privateMessageEditHandler += handler
140141

141-
override def registerMessageDeleteHandler(handler: Consumer[DiscordChatMessage]): Unit = messageDeleteHandler += handler
142+
override def registerMessageDeleteHandler(handler: Consumer[DiscordChatMessage]): Unit = {
143+
if (channelId.isEmpty) throw new IllegalStateException("first set the channel for this input")
144+
messageDeleteHandler += handler
145+
}
142146

143147
override def registerPrivateMessageDeleteHandler(handler: Consumer[DiscordChatMessage]): Unit = privateMessageDeleteHandler += handler
144148

145149
override def setChannel(channelId: String): Unit = {
146150
sourceConnector.get.getTextChannel(channelId) match {
147-
case Some(_) => this.channelId = channelId
151+
case Some(_) => this.channelId = Some(channelId.trim)
148152
case None => throw new IllegalArgumentException("Channel with that id doesn't exist")
149153
}
150154
}
151155

152-
override def getChannelId: String = channelId
153-
154-
override def serialize(): String = getSourceIdentifier
155-
156-
override def deserialize(value: String): Unit = {
157-
setSourceConnector(value)
158-
}
156+
override def getChannelId: String = channelId.get
159157

160158
override def getMessage(messageId: String): DiscordChatMessage =
161159
messages.find(_.getId == messageId).getOrElse(privateMessages.find(_.getId == messageId).orNull)

src/main/scala/org/codeoverflow/chatoverflow/requirement/service/discord/impl/DiscordChatOutputImpl.scala

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,30 @@ package org.codeoverflow.chatoverflow.requirement.service.discord.impl
33
import org.codeoverflow.chatoverflow.WithLogger
44
import org.codeoverflow.chatoverflow.api.io.output.chat.DiscordChatOutput
55
import org.codeoverflow.chatoverflow.registry.Impl
6-
import org.codeoverflow.chatoverflow.requirement.Connection
6+
import org.codeoverflow.chatoverflow.requirement.OutputImpl
77
import org.codeoverflow.chatoverflow.requirement.service.discord.DiscordChatConnector
88

99
/**
1010
* This is the implementation of the discord chat output, using the discord connector.
1111
*/
1212
@Impl(impl = classOf[DiscordChatOutput], connector = classOf[DiscordChatConnector])
13-
class DiscordChatOutputImpl extends Connection[DiscordChatConnector] with DiscordChatOutput with WithLogger {
13+
class DiscordChatOutputImpl extends OutputImpl[DiscordChatConnector] with DiscordChatOutput with WithLogger {
1414

15-
private var channelId: String = _
15+
private var channelId: Option[String] = None
1616

17+
override def start(): Boolean = true
1718

1819
override def setChannel(channelId: String): Unit = {
1920
sourceConnector.get.getTextChannel(channelId) match {
20-
case Some(_) => this.channelId = channelId
21+
case Some(_) => this.channelId = Some(channelId.trim)
2122
case None => throw new IllegalArgumentException("Channel with that id doesn't exist")
2223
}
2324
}
2425

25-
override def getChannelId: String = channelId
26+
override def getChannelId: String = channelId.get
2627

27-
override def init(): Boolean = {
28-
if (sourceConnector.isDefined) {
29-
if (sourceConnector.get.isRunning || sourceConnector.get.init()) {
30-
setChannel(getSourceIdentifier)
31-
true
32-
} else false
33-
} else {
34-
logger warn "Source Connector not set."
35-
false
36-
}
37-
}
38-
39-
override def sendChatMessage(message: String): Unit = sourceConnector.get.sendChatMessage(channelId, message)
40-
41-
override def serialize(): String = getSourceIdentifier
42-
43-
override def deserialize(value: String): Unit = {
44-
setSourceConnector(value)
28+
override def sendChatMessage(message: String): Unit = {
29+
val channel = channelId.getOrElse(throw new IllegalStateException("first set the channel for this output"))
30+
sourceConnector.get.sendChatMessage(channel, message)
4531
}
4632
}

src/main/scala/org/codeoverflow/chatoverflow/requirement/service/mockup/impl/MockUpChatInputImpl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import scala.collection.mutable.ListBuffer
1616
@Impl(impl = classOf[MockUpChatInput], connector = classOf[MockUpChatConnector])
1717
class MockUpChatInputImpl extends Connection[MockUpChatConnector] with MockUpChatInput with WithLogger {
1818

19-
// TODO: Rewrite code to fit to the new framework style using actors, a new parser, etc.
19+
// TODO: Rewrite code to fit to the new framework style using actors, a new parser, extend InputImpl etc.
2020

2121
private val messages: ListBuffer[ChatMessage[ChatMessageAuthor, Channel, ChatEmoticon]] = ListBuffer[ChatMessage[ChatMessageAuthor, Channel, ChatEmoticon]]()
2222
private val privateMessages: ListBuffer[ChatMessage[ChatMessageAuthor, Channel, ChatEmoticon]] = ListBuffer[ChatMessage[ChatMessageAuthor, Channel, ChatEmoticon]]()

src/main/scala/org/codeoverflow/chatoverflow/requirement/service/sample/impl/SampleInputImpl.scala

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,11 @@ package org.codeoverflow.chatoverflow.requirement.service.sample.impl
33
import org.codeoverflow.chatoverflow.WithLogger
44
import org.codeoverflow.chatoverflow.api.io.input.SampleInput
55
import org.codeoverflow.chatoverflow.registry.Impl
6-
import org.codeoverflow.chatoverflow.requirement.Connection
6+
import org.codeoverflow.chatoverflow.requirement.InputImpl
77
import org.codeoverflow.chatoverflow.requirement.service.sample.SampleConnector
88

99
@Impl(impl = classOf[SampleInput], connector = classOf[SampleConnector])
10-
class SampleInputImpl extends Connection[SampleConnector] with SampleInput with WithLogger {
11-
override def init(): Boolean = sourceConnector.get.init()
10+
class SampleInputImpl extends InputImpl[SampleConnector] with SampleInput with WithLogger {
1211

13-
override def serialize(): String = getSourceIdentifier
14-
15-
override def deserialize(value: String): Unit = setSourceConnector(value)
12+
override def start(): Boolean = true
1613
}

0 commit comments

Comments
 (0)