From e86b16f2d558139cc845b0a4becb54df5579700e Mon Sep 17 00:00:00 2001
From: Pjiesco <55349095+Pjiesco@users.noreply.github.com>
Date: Thu, 19 May 2022 11:54:12 +0200
Subject: [PATCH 01/41] [Feature] Dynamic state parent group (#48)
* feat: add parentGroup field in createState message
* bump SDK and TP Api version
* Change parameter order
* feat: use the name from the category of the categoryId if parentGroup isn't specified
* fix: typo's in stateId
fix: use correct categoryId
* fix: add check for category id from constants
* fix: break outer loop
* feat: add CategoryHelper.getCategoryShortId method
---
.../touchportal/annotations/Category.java | 2 +-
.../touchportal/helpers/CategoryHelper.java | 23 ++++++++
.../touchportal/helpers/PluginHelper.java | 2 +-
.../helpers/SentMessageHelper.java | 1 +
.../touchportal/TouchPortalPlugin.java | 50 +++++++++++++++++-
.../touchportal/test/LibraryTests.java | 52 +++++++++++--------
build.gradle | 4 +-
7 files changed, 106 insertions(+), 28 deletions(-)
diff --git a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Category.java b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Category.java
index 43c843f..e6b622b 100644
--- a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Category.java
+++ b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Category.java
@@ -33,7 +33,7 @@
*
* @see TP Documentation: Categories
*/
-@Retention(RetentionPolicy.SOURCE)
+@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Category {
/**
diff --git a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/CategoryHelper.java b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/CategoryHelper.java
index 42e7bb6..c4eba79 100644
--- a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/CategoryHelper.java
+++ b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/CategoryHelper.java
@@ -23,6 +23,7 @@
import com.christophecvb.touchportal.annotations.Category;
import javax.lang.model.element.Element;
+import java.lang.reflect.Field;
/**
* Touch Portal Plugin Category Helper
@@ -48,6 +49,17 @@ public static String getCategoryId(Element pluginElement, Element categoryElemen
return CategoryHelper._getCategoryId(PluginHelper.getPluginId(pluginElement), category.id().isEmpty() ? categoryElement.getSimpleName().toString() : category.id());
}
+ /**
+ * Get Category Short ID
+ *
+ * @param categoryField {@link Field}
+ * @param category {@link Category}
+ * @return String categoryId
+ */
+ public static String getCategoryShortId(Field categoryField, Category category) {
+ return category.id().isEmpty() ? categoryField.getName() : category.id();
+ }
+
/**
* Get the generated Category Name
*
@@ -59,6 +71,17 @@ public static String getCategoryName(Element categoryElement, Category category)
return category.name().isEmpty() ? categoryElement.getSimpleName().toString() : category.name();
}
+ /**
+ * Get the generated Category Name
+ *
+ * @param categoryField {@link Field}
+ * @param category {@link Category}
+ * @return String categoryName
+ */
+ public static String getCategoryName(Field categoryField, Category category) {
+ return category.name().isEmpty() ? categoryField.getName() : category.name();
+ }
+
/**
* Get the generated Category ID
*
diff --git a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
index 0c615b3..b4706d6 100644
--- a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
+++ b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
@@ -43,7 +43,7 @@ public class PluginHelper {
/**
* Touch Portal Plugin System version
*/
- public static final int TOUCH_PORTAL_PLUGIN_VERSION = 5;
+ public static final int TOUCH_PORTAL_PLUGIN_VERSION = 6;
/**
* Argument passed to the jar to start the plugin
*/
diff --git a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/SentMessageHelper.java b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/SentMessageHelper.java
index a5a8d2c..a852b12 100644
--- a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/SentMessageHelper.java
+++ b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/SentMessageHelper.java
@@ -47,5 +47,6 @@ public class SentMessageHelper {
public static final String OPTIONS = "options";
public static final String CONNECTOR_ID = "connectorId";
public static final String SHORT_ID = "shortId";
+ public static final String PARENT_GROUP = "parentGroup";
}
\ No newline at end of file
diff --git a/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java b/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
index ae58cf0..37865d0 100644
--- a/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
+++ b/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
@@ -712,7 +712,21 @@ public boolean sendStateUpdate(String stateId, Object value, boolean allowEmptyV
* @return boolean stateUpdateMessageSent
*/
public boolean sendCreateState(String categoryId, String stateId, String description, Object value) {
- return this.sendCreateState(categoryId, stateId, description, value, false, false);
+ return this.sendCreateState(categoryId, stateId, null, description, value, false, false);
+ }
+
+ /**
+ * Send a Create a State Message to the Touch Portal Plugin System not allowing empty value
+ *
+ * @param categoryId String
+ * @param stateId String
+ * @param parentGroup String
+ * @param description String
+ * @param value Object
+ * @return boolean stateUpdateMessageSent
+ */
+ public boolean sendCreateState(String categoryId, String stateId, String parentGroup, String description, Object value) {
+ return this.sendCreateState(categoryId, stateId, parentGroup, description, value, false, false);
}
/**
@@ -727,6 +741,22 @@ public boolean sendCreateState(String categoryId, String stateId, String descrip
* @return boolean stateCreateSent
*/
public boolean sendCreateState(String categoryId, String stateId, String description, Object value, boolean allowEmptyValue, boolean forceUpdate) {
+ return this.sendCreateState(categoryId, stateId, null, description, value, allowEmptyValue, forceUpdate);
+ }
+
+ /**
+ * Send a Create a State Message to the Touch Portal Plugin System
+ *
+ * @param categoryId String
+ * @param stateId String
+ * @param parentGroup String
+ * @param description String
+ * @param value Object
+ * @param allowEmptyValue boolean
+ * @param forceUpdate boolean
+ * @return boolean stateCreateSent
+ */
+ public boolean sendCreateState(String categoryId, String stateId, String parentGroup, String description, Object value, boolean allowEmptyValue, boolean forceUpdate) {
boolean sent = false;
String valueStr = value != null ? String.valueOf(value) : null;
if (categoryId != null && !categoryId.isEmpty() && stateId != null && !stateId.isEmpty() && description != null && !description.isEmpty() && valueStr != null && (allowEmptyValue || !valueStr.isEmpty())) {
@@ -737,6 +767,24 @@ public boolean sendCreateState(String categoryId, String stateId, String descrip
createStateMessage.addProperty(SentMessageHelper.ID, stateId);
createStateMessage.addProperty(SentMessageHelper.DESCRIPTION, description);
createStateMessage.addProperty(SentMessageHelper.DEFAULT_VALUE, valueStr);
+ if (parentGroup == null || parentGroup.isEmpty()) {
+ classLoop:
+ for (Class> subClass : this.pluginClass.getDeclaredClasses()) {
+ for (Field subClassField : subClass.getDeclaredFields()) {
+ if (subClassField.isAnnotationPresent(Category.class)) {
+ Category category = subClassField.getAnnotation(Category.class);
+
+ if(categoryId.equals(CategoryHelper.getCategoryShortId(subClassField, category))) {
+ createStateMessage.addProperty(SentMessageHelper.PARENT_GROUP, CategoryHelper.getCategoryName(subClassField, category));
+ break classLoop;
+ }
+ }
+ }
+ }
+ } else {
+ createStateMessage.addProperty(SentMessageHelper.PARENT_GROUP, parentGroup);
+ }
+
sent = this.send(createStateMessage);
if (sent) {
this.currentStates.put(stateId, valueStr);
diff --git a/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java b/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java
index db68892..2f85477 100644
--- a/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java
+++ b/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java
@@ -321,37 +321,43 @@ public void testDynamicStates() {
assertFalse(this.touchPortalPluginTest.sendCreateState(null, null, null, ""));
assertFalse(this.touchPortalPluginTest.sendCreateState("", "", "", ""));
- assertFalse(this.touchPortalPluginTest.sendCreateState("CategoryId", null, null, null));
- assertFalse(this.touchPortalPluginTest.sendCreateState("CategoryId", "", null, null));
- assertFalse(this.touchPortalPluginTest.sendCreateState("CategoryId", null, "", null));
- assertFalse(this.touchPortalPluginTest.sendCreateState("CategoryId", null, null, ""));
- assertFalse(this.touchPortalPluginTest.sendCreateState("CategoryId", "", "", ""));
+ assertFalse(this.touchPortalPluginTest.sendCreateState("BaseCategory", null, null, null));
+ assertFalse(this.touchPortalPluginTest.sendCreateState("BaseCategory", "", null, null));
+ assertFalse(this.touchPortalPluginTest.sendCreateState("BaseCategory", null, "", null));
+ assertFalse(this.touchPortalPluginTest.sendCreateState("BaseCategory", null, null, ""));
+ assertFalse(this.touchPortalPluginTest.sendCreateState("BaseCategory", "", "", ""));
- assertFalse(this.touchPortalPluginTest.sendCreateState("CategoryId", "SateId", null, null));
- assertFalse(this.touchPortalPluginTest.sendCreateState("CategoryId", "SateId", "", null));
- assertFalse(this.touchPortalPluginTest.sendCreateState("CategoryId", "SateId", null, ""));
- assertFalse(this.touchPortalPluginTest.sendCreateState("CategoryId", "SateId", "", ""));
+ assertFalse(this.touchPortalPluginTest.sendCreateState("BaseCategory", "StateId", null, null));
+ assertFalse(this.touchPortalPluginTest.sendCreateState("BaseCategory", "StateId", "", null));
+ assertFalse(this.touchPortalPluginTest.sendCreateState("BaseCategory", "StateId", null, ""));
+ assertFalse(this.touchPortalPluginTest.sendCreateState("BaseCategory", "StateId", "", ""));
- assertFalse(this.touchPortalPluginTest.sendCreateState("CategoryId", "SateId", "Dynamically Created State", null));
- assertFalse(this.touchPortalPluginTest.sendCreateState("CategoryId", "SateId", "Dynamically Created State", ""));
+ assertFalse(this.touchPortalPluginTest.sendCreateState("BaseCategory", "StateId", "Dynamically Created State", null));
+ assertFalse(this.touchPortalPluginTest.sendCreateState("BaseCategory", "StateId", "Dynamically Created State", ""));
- assertFalse(this.touchPortalPluginTest.sendCreateState("CategoryId", "StateId", "Dynamically Created State", null, true, false));
- assertTrue(this.touchPortalPluginTest.sendCreateState("CategoryId", "StateId", "Dynamically Created State", "", true, false));
- assertFalse(this.touchPortalPluginTest.sendCreateState("CategoryId", "StateId", "Dynamically Created State", "", true, false));
- assertTrue(this.touchPortalPluginTest.sendCreateState("CategoryId", "StateId", "Dynamically Created State", "", true, true));
+ assertFalse(this.touchPortalPluginTest.sendCreateState("BaseCategory", "StateId", "Dynamically Created State", null, true, false));
+ assertTrue(this.touchPortalPluginTest.sendCreateState("BaseCategory", "StateId", "Dynamically Created State", "", true, false));
+ assertFalse(this.touchPortalPluginTest.sendCreateState("BaseCategory", "StateId", "Dynamically Created State", "", true, false));
+ assertTrue(this.touchPortalPluginTest.sendCreateState("BaseCategory", "StateId", "Dynamically Created State", "", true, true));
+
+ assertTrue(this.touchPortalPluginTest.sendCreateState("BaseCategory", "StateId", "Dynamically Created State", "Default Value 01"));
+ assertFalse(this.touchPortalPluginTest.sendCreateState("BaseCategory", "StateId", "Dynamically Created State", "Default Value 01"));
+ assertTrue(this.touchPortalPluginTest.sendCreateState("BaseCategory", "StateId", "Dynamically Created State", "Default Value 02"));
+
+ assertTrue(this.touchPortalPluginTest.sendCreateState("BaseCategory", "StateId", "Parent", "Dynamically Created State", "Default Value 01"));
+ assertTrue(this.touchPortalPluginTest.sendCreateState("BaseCategory", "StateId", "", "Dynamically Created State", "Default Value 02"));
+ assertTrue(this.touchPortalPluginTest.sendCreateState("BaseCategory", "StateId", null, "Dynamically Created State", "Default Value 03"));
+ assertTrue(this.touchPortalPluginTest.sendCreateState("BaseCategory", "StateId", "Parent", "Dynamically Created State", "Default Value 04", true, false));
- assertTrue(this.touchPortalPluginTest.sendCreateState("CategoryId", "SateId", "Dynamically Created State", "Default Value 01"));
- assertFalse(this.touchPortalPluginTest.sendCreateState("CategoryId", "SateId", "Dynamically Created State", "Default Value 01"));
- assertTrue(this.touchPortalPluginTest.sendCreateState("CategoryId", "SateId", "Dynamically Created State", "Default Value 02"));
assertFalse(this.touchPortalPluginTest.sendRemoveState(null, null));
assertFalse(this.touchPortalPluginTest.sendRemoveState("", null));
assertFalse(this.touchPortalPluginTest.sendRemoveState(null, ""));
assertFalse(this.touchPortalPluginTest.sendRemoveState("", ""));
- assertFalse(this.touchPortalPluginTest.sendRemoveState("CategoryId", null));
- assertFalse(this.touchPortalPluginTest.sendRemoveState("CategoryId", ""));
+ assertFalse(this.touchPortalPluginTest.sendRemoveState("BaseCategory", null));
+ assertFalse(this.touchPortalPluginTest.sendRemoveState("BaseCategory", ""));
- assertTrue(this.touchPortalPluginTest.sendRemoveState("CategoryId", "SateId"));
+ assertTrue(this.touchPortalPluginTest.sendRemoveState("BaseCategory", "StateId"));
}
@Test
@@ -360,8 +366,8 @@ public void testSendFail() {
assertFalse(this.touchPortalPluginTest.sendStateUpdate(TouchPortalPluginTestConstants.BaseCategory.States.CustomState.ID, "New Value"));
assertFalse(this.touchPortalPluginTest.sendChoiceUpdate("listId", null, true));
assertFalse(this.touchPortalPluginTest.sendSpecificChoiceUpdate("listId", "instanceId", null, true));
- assertFalse(this.touchPortalPluginTest.sendCreateState("CategoryId", "SateId", "Dynamically Created State", "Default Value 01"));
- assertFalse(this.touchPortalPluginTest.sendRemoveState("CategoryId", "SateId"));
+ assertFalse(this.touchPortalPluginTest.sendCreateState("BaseCategory", "StateId", "Dynamically Created State", "Default Value 01"));
+ assertFalse(this.touchPortalPluginTest.sendRemoveState("BaseCategory", "StateId"));
}
@Test
diff --git a/build.gradle b/build.gradle
index 03f26fb..0af9408 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,8 +5,8 @@ allprojects {
}
ext.versionMajor = 8
-ext.versionMinor = 1
-ext.versionPatch = 2
+ext.versionMinor = 2
+ext.versionPatch = 0
ext.isRelease = System.getenv('IS_RELEASE') == 'YES'
From dbc0a35bed92677f6d3ebc7f51b2090c5dde3f52 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Mon, 23 May 2022 10:55:46 +0200
Subject: [PATCH 02/41] core: Upgrade dependencies
---
AnnotationsProcessor/build.gradle | 8 ++++----
Helpers/build.gradle | 2 +-
Library/build.gradle | 6 +++---
.../test/resources/TouchPortalPluginTest/plugin.config | 2 +-
SampleKotlin/build.gradle | 2 +-
build.gradle | 2 +-
6 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/AnnotationsProcessor/build.gradle b/AnnotationsProcessor/build.gradle
index 0b26306..67a555e 100644
--- a/AnnotationsProcessor/build.gradle
+++ b/AnnotationsProcessor/build.gradle
@@ -77,11 +77,11 @@ javadoc {
}
dependencies {
- implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
- implementation 'com.google.auto.service:auto-service:1.0-rc7'
- implementation group: 'com.squareup', name: 'javapoet', version: '1.12.1'
+ implementation group: 'com.google.code.gson', name: 'gson', version: '2.9.0'
+ implementation 'com.google.auto.service:auto-service:1.0.1'
+ implementation group: 'com.squareup', name: 'javapoet', version: '1.13.0'
implementation project(':Annotations')
implementation project(':Helpers')
- testImplementation group: 'junit', name: 'junit', version: '4.12'
+ testImplementation group: 'junit', name: 'junit', version: '4.13.2'
}
diff --git a/Helpers/build.gradle b/Helpers/build.gradle
index 1e8e3f0..5d24d20 100644
--- a/Helpers/build.gradle
+++ b/Helpers/build.gradle
@@ -77,6 +77,6 @@ javadoc {
}
dependencies {
- api group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
+ api group: 'com.google.code.gson', name: 'gson', version: '2.9.0'
api project(':Annotations')
}
diff --git a/Library/build.gradle b/Library/build.gradle
index 368be89..31acac3 100644
--- a/Library/build.gradle
+++ b/Library/build.gradle
@@ -81,11 +81,11 @@ dependencies {
api project(':Annotations')
api project(':Helpers')
- api group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
+ api group: 'com.google.code.gson', name: 'gson', version: '2.9.0'
- implementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.7.2'
+ implementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.9.3'
- testImplementation group: 'junit', name: 'junit', version: '4.12'
+ testImplementation group: 'junit', name: 'junit', version: '4.13.2'
testAnnotationProcessor project(':AnnotationsProcessor')
}
diff --git a/Library/src/test/resources/TouchPortalPluginTest/plugin.config b/Library/src/test/resources/TouchPortalPluginTest/plugin.config
index e646ad3..09a2603 100644
--- a/Library/src/test/resources/TouchPortalPluginTest/plugin.config
+++ b/Library/src/test/resources/TouchPortalPluginTest/plugin.config
@@ -1,4 +1,4 @@
#TouchPortalPluginTest
-#Fri Jan 21 19:02:31 CET 2022
+#Mon May 23 10:54:55 CEST 2022
samplekey=Sample Value
plugin.version=1
diff --git a/SampleKotlin/build.gradle b/SampleKotlin/build.gradle
index 87e1fd0..67b7048 100644
--- a/SampleKotlin/build.gradle
+++ b/SampleKotlin/build.gradle
@@ -24,7 +24,7 @@ buildConfig {
}
dependencies {
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
+ implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
implementation project(':Library')
diff --git a/build.gradle b/build.gradle
index 0af9408..1218721 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ allprojects {
ext.versionMajor = 8
ext.versionMinor = 2
-ext.versionPatch = 0
+ext.versionPatch = 1
ext.isRelease = System.getenv('IS_RELEASE') == 'YES'
From 821de0218ee3d83896e0bc1574f36aa8a3c4f081 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Thu, 15 Sep 2022 20:09:50 +0200
Subject: [PATCH 03/41] core: Upgrade Gradle version to 7.5.1
---
.../packager/TouchPortalPluginPackager.groovy | 2 ++
build.gradle | 6 +++---
gradle/wrapper/gradle-wrapper.properties | 2 +-
settings.gradle | 9 ++++++++-
4 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/Packager/src/main/groovy/com/christophecvb/touchportal/packager/TouchPortalPluginPackager.groovy b/Packager/src/main/groovy/com/christophecvb/touchportal/packager/TouchPortalPluginPackager.groovy
index d96b273..453e64e 100644
--- a/Packager/src/main/groovy/com/christophecvb/touchportal/packager/TouchPortalPluginPackager.groovy
+++ b/Packager/src/main/groovy/com/christophecvb/touchportal/packager/TouchPortalPluginPackager.groovy
@@ -37,6 +37,8 @@ class TouchPortalPluginPackager implements Plugin {
project.tasks.withType(Jar) { task ->
task.dependsOn project.configurations.runtimeClasspath
+ task.duplicatesStrategy = DuplicatesStrategy.EXCLUDE
+
task.doFirst {
manifest {
attributes 'Implementation-Title': "${extension.mainClassSimpleName.get()}",
diff --git a/build.gradle b/build.gradle
index 1218721..f66e5da 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,8 +5,8 @@ allprojects {
}
ext.versionMajor = 8
-ext.versionMinor = 2
-ext.versionPatch = 1
+ext.versionMinor = 3
+ext.versionPatch = 0
ext.isRelease = System.getenv('IS_RELEASE') == 'YES'
@@ -16,4 +16,4 @@ ext.versionName = "${versionMajor}.${versionMinor}.${versionPatch}" + (ext.isRel
ext.envOrPropOrEmpty = { String name ->
def value = System.getenv(name) ? System.getenv(name) : findProperty(name)
return value ? value.toString() : ''
-}
\ No newline at end of file
+}
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 28ff446..ae04661 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/settings.gradle b/settings.gradle
index 1702027..2fcdf04 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,3 +1,11 @@
+pluginManagement {
+ repositories {
+ mavenLocal()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+
rootProject.name = 'TouchPortalPluginSDK'
include 'Annotations'
include 'Helpers'
@@ -6,4 +14,3 @@ include 'Library'
include 'SampleJava'
include 'SampleKotlin'
include 'Packager'
-
From 038c1786b0098fb4ccb7ba0955060ee49ae0a5e3 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Thu, 15 Sep 2022 20:20:57 +0200
Subject: [PATCH 04/41] core: Upgrade Gradle version to 7.5.1
---
SampleJava/build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/SampleJava/build.gradle b/SampleJava/build.gradle
index c392e71..c1c0707 100644
--- a/SampleJava/build.gradle
+++ b/SampleJava/build.gradle
@@ -1,7 +1,7 @@
plugins {
id 'java'
id 'com.github.gmazzo.buildconfig' version '3.0.0'
- id 'com.christophecvb.touchportal.plugin-packager' version '8.0.0-SNAPSHOT'
+ id 'com.christophecvb.touchportal.plugin-packager' version '8.3.0-SNAPSHOT'
}
def mainClassSimpleName = 'TouchPortalSampleJavaPlugin'
From d0432b599cd005fd181c0c832ecd67d86c47462b Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Thu, 15 Sep 2022 20:32:02 +0200
Subject: [PATCH 05/41] core: Upgrade Gradle version to 7.5.1
---
.github/workflows/develop.yml | 16 ++++++++++++++++
SampleJava/build.gradle | 2 +-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml
index 6f35ad6..0d8244e 100644
--- a/.github/workflows/develop.yml
+++ b/.github/workflows/develop.yml
@@ -5,8 +5,24 @@ on:
branches: [ develop ]
jobs:
+ prepare-maven-local:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up JDK 1.8
+ uses: actions/setup-java@v1
+ with:
+ java-version: 1.8
+ java-package: jdk
+ - name: Gradle Plugin Publish Local
+ run: |
+ ./gradlew :Packager:publishToMavenLocal
+
build:
+ needs: prepare-maven-local
runs-on: ubuntu-latest
steps:
diff --git a/SampleJava/build.gradle b/SampleJava/build.gradle
index c1c0707..f79a792 100644
--- a/SampleJava/build.gradle
+++ b/SampleJava/build.gradle
@@ -1,7 +1,7 @@
plugins {
id 'java'
id 'com.github.gmazzo.buildconfig' version '3.0.0'
- id 'com.christophecvb.touchportal.plugin-packager' version '8.3.0-SNAPSHOT'
+ id 'com.christophecvb.touchportal.plugin-packager' version '8.3.0-SNAPSHOT+'
}
def mainClassSimpleName = 'TouchPortalSampleJavaPlugin'
From 03ca14a7139bf09ded21c029106d65678d9d22f4 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Thu, 15 Sep 2022 20:39:52 +0200
Subject: [PATCH 06/41] core: Upgrade Gradle version to 7.5.1
---
SampleJava/build.gradle | 2 +-
SampleKotlin/build.gradle | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/SampleJava/build.gradle b/SampleJava/build.gradle
index f79a792..bcae488 100644
--- a/SampleJava/build.gradle
+++ b/SampleJava/build.gradle
@@ -1,7 +1,7 @@
plugins {
id 'java'
id 'com.github.gmazzo.buildconfig' version '3.0.0'
- id 'com.christophecvb.touchportal.plugin-packager' version '8.3.0-SNAPSHOT+'
+ id 'com.christophecvb.touchportal.plugin-packager' version "$versionName+"
}
def mainClassSimpleName = 'TouchPortalSampleJavaPlugin'
diff --git a/SampleKotlin/build.gradle b/SampleKotlin/build.gradle
index 67b7048..0516225 100644
--- a/SampleKotlin/build.gradle
+++ b/SampleKotlin/build.gradle
@@ -3,7 +3,7 @@ plugins {
id 'org.jetbrains.kotlin.kapt' version '1.5.0'
id 'java'
id 'com.github.gmazzo.buildconfig' version '3.0.0'
- id 'com.christophecvb.touchportal.plugin-packager' version '8.0.0-SNAPSHOT'
+ id 'com.christophecvb.touchportal.plugin-packager' version "$versionName+"
}
def mainClassSimpleName = 'TouchPortalSampleKotlinPlugin'
From 324fb2e49338ec4360351b65b66c97b7f01031aa Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Thu, 15 Sep 2022 20:48:33 +0200
Subject: [PATCH 07/41] core: Upgrade Gradle version to 7.5.1
---
Packager/build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Packager/build.gradle b/Packager/build.gradle
index bc372b3..42d58ab 100644
--- a/Packager/build.gradle
+++ b/Packager/build.gradle
@@ -7,7 +7,7 @@ plugins {
group 'com.christophecvb.touchportal'
def localArchiveBaseName = 'plugin-packager'
-version versionName + (isRelease ? '' : '-' + System.currentTimeMillis())
+version versionName
pluginBundle {
website = 'https://github.com/ChristopheCVB/TouchPortalPluginSDK'
From 25da3315b26783d03930bf1dfb44cbf275c92ac4 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Tue, 1 Nov 2022 12:14:03 +0100
Subject: [PATCH 08/41] core: Dependencies management
---
AnnotationsProcessor/build.gradle | 8 ++++----
Helpers/build.gradle | 2 +-
Library/build.gradle | 6 +++---
SampleKotlin/build.gradle | 2 +-
build.gradle | 2 +-
settings.gradle | 13 +++++++++++++
6 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/AnnotationsProcessor/build.gradle b/AnnotationsProcessor/build.gradle
index 67a555e..96232ca 100644
--- a/AnnotationsProcessor/build.gradle
+++ b/AnnotationsProcessor/build.gradle
@@ -77,11 +77,11 @@ javadoc {
}
dependencies {
- implementation group: 'com.google.code.gson', name: 'gson', version: '2.9.0'
- implementation 'com.google.auto.service:auto-service:1.0.1'
- implementation group: 'com.squareup', name: 'javapoet', version: '1.13.0'
+ implementation libs.gson
+ implementation libs.autoservice
+ implementation libs.javapoet
implementation project(':Annotations')
implementation project(':Helpers')
- testImplementation group: 'junit', name: 'junit', version: '4.13.2'
+ testImplementation libs.junit
}
diff --git a/Helpers/build.gradle b/Helpers/build.gradle
index 5d24d20..b19d282 100644
--- a/Helpers/build.gradle
+++ b/Helpers/build.gradle
@@ -77,6 +77,6 @@ javadoc {
}
dependencies {
- api group: 'com.google.code.gson', name: 'gson', version: '2.9.0'
+ api libs.gson
api project(':Annotations')
}
diff --git a/Library/build.gradle b/Library/build.gradle
index 31acac3..2125853 100644
--- a/Library/build.gradle
+++ b/Library/build.gradle
@@ -81,11 +81,11 @@ dependencies {
api project(':Annotations')
api project(':Helpers')
- api group: 'com.google.code.gson', name: 'gson', version: '2.9.0'
+ api libs.gson
- implementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.9.3'
+ implementation libs.okhttp
- testImplementation group: 'junit', name: 'junit', version: '4.13.2'
+ testImplementation libs.junit
testAnnotationProcessor project(':AnnotationsProcessor')
}
diff --git a/SampleKotlin/build.gradle b/SampleKotlin/build.gradle
index 0516225..affc3a1 100644
--- a/SampleKotlin/build.gradle
+++ b/SampleKotlin/build.gradle
@@ -24,7 +24,7 @@ buildConfig {
}
dependencies {
- implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
+ implementation libs.kotlinstdlibjdk8
implementation project(':Library')
diff --git a/build.gradle b/build.gradle
index f66e5da..0d0f82d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ allprojects {
}
ext.versionMajor = 8
-ext.versionMinor = 3
+ext.versionMinor = 4
ext.versionPatch = 0
ext.isRelease = System.getenv('IS_RELEASE') == 'YES'
diff --git a/settings.gradle b/settings.gradle
index 2fcdf04..2388470 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -6,6 +6,19 @@ pluginManagement {
}
}
+dependencyResolutionManagement {
+ versionCatalogs {
+ libs {
+ library('gson', 'com.google.code.gson:gson:2.9.0')
+ library('okhttp', 'com.squareup.okhttp3:okhttp:4.9.3')
+ library('autoservice', 'com.google.auto.service:auto-service:1.0.1')
+ library('javapoet', 'com.squareup:javapoet:1.13.0')
+ library('junit', 'junit:junit:4.13.2')
+ library('kotlinstdlibjdk8', 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.+')
+ }
+ }
+}
+
rootProject.name = 'TouchPortalPluginSDK'
include 'Annotations'
include 'Helpers'
From 8f92768ff0cd3ed782fbd55a1420a45f6a7592d7 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Tue, 1 Nov 2022 12:14:42 +0100
Subject: [PATCH 09/41] core: ActionTranslation annotation
---
.../annotations/ActionTranslation.java | 79 +++++++++++++++++++
.../annotations/ActionTranslations.java | 5 ++
.../touchportal/annotations/Language.java | 25 ++++++
.../TouchPortalPluginAnnotationProcessor.java | 19 +++++
.../packager/TouchPortalPluginPackager.groovy | 2 +
.../TouchPortalSampleJavaPlugin.java | 2 +
6 files changed, 132 insertions(+)
create mode 100644 Annotations/src/main/java/com/christophecvb/touchportal/annotations/ActionTranslation.java
create mode 100644 Annotations/src/main/java/com/christophecvb/touchportal/annotations/ActionTranslations.java
create mode 100644 Annotations/src/main/java/com/christophecvb/touchportal/annotations/Language.java
diff --git a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ActionTranslation.java b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ActionTranslation.java
new file mode 100644
index 0000000..1830a22
--- /dev/null
+++ b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ActionTranslation.java
@@ -0,0 +1,79 @@
+/*
+ * Touch Portal Plugin SDK
+ *
+ * Copyright 2020 Christophe Carvalho Vilas-Boas
+ * christophe.carvalhovilasboas@gmail.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.christophecvb.touchportal.annotations;
+
+import java.lang.annotation.*;
+
+/**
+ * ActionTranslation Annotation
+ *
+ * Target is a Method
+ *
+ */
+@Repeatable(ActionTranslations.class)
+public @interface ActionTranslation {
+ /**
+ * ActionTranslation Language
+ *
+ * @return Language language
+ */
+ Language language();
+
+ /**
+ * ActionTranslation name
+ *
+ * Default is ""
+ *
+ *
+ * @return String name
+ */
+ String name() default "";
+
+ /**
+ * ActionTranslation prefix
+ *
+ * Default is ""
+ *
+ *
+ * @return String prefix
+ */
+ String prefix() default "";
+
+ /**
+ * ActionTranslation description
+ *
+ * Default is ""
+ *
+ *
+ * @return String description
+ */
+ String description() default "";
+
+ /**
+ * ActionTranslation format
+ *
+ * Default is ""
+ *
+ *
+ * @return String format
+ */
+ String format() default "";
+}
diff --git a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ActionTranslations.java b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ActionTranslations.java
new file mode 100644
index 0000000..3efd044
--- /dev/null
+++ b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ActionTranslations.java
@@ -0,0 +1,5 @@
+package com.christophecvb.touchportal.annotations;
+
+public @interface ActionTranslations {
+ ActionTranslation[] value();
+}
diff --git a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Language.java b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Language.java
new file mode 100644
index 0000000..880e2db
--- /dev/null
+++ b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Language.java
@@ -0,0 +1,25 @@
+package com.christophecvb.touchportal.annotations;
+
+/**
+ * Languages supported by Touch Portal
+ */
+public enum Language {
+ //ENGLISH("en"), This is the default language to provide in Action annotation
+ GERMAN("de"),
+ SPANISH("es"),
+ FRENCH("fr"),
+ DUTCH("nl"),
+ PORTUGUESE("pt"),
+ TURKISH("tr");
+
+
+ private final String code;
+
+ Language(String code) {
+ this.code = code;
+ }
+
+ public String getCode() {
+ return this.code;
+ }
+}
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationProcessor.java
index 08ac3d9..d3344ed 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationProcessor.java
@@ -355,6 +355,25 @@ private Pair processAction(RoundEnvironment roundE
}
jsonAction.addProperty(ActionHelper.HAS_HOLD_FUNCTIONALITY, action.hasHoldFunctionality());
+ ActionTranslation[] actionTranslations = actionElement.getAnnotationsByType(ActionTranslation.class);
+ if (actionTranslations.length > 0) {
+ for (ActionTranslation actionTranslation : actionTranslations) {
+ String languageCode = actionTranslation.language().getCode();
+ if (!actionTranslation.name().isEmpty()) {
+ jsonAction.addProperty(ActionHelper.NAME + "_" + languageCode, actionTranslation.name());
+ }
+ if (!actionTranslation.prefix().isEmpty()) {
+ jsonAction.addProperty(ActionHelper.PREFIX + "_" + languageCode, actionTranslation.prefix());
+ }
+ if (!actionTranslation.description().isEmpty()) {
+ jsonAction.addProperty(ActionHelper.DESCRIPTION + "_" + languageCode, actionTranslation.description());
+ }
+ if (!actionTranslation.format().isEmpty()) {
+ jsonAction.addProperty(ActionHelper.FORMAT + "_" + languageCode, actionTranslation.format());
+ }
+ }
+ }
+
JsonArray jsonActionData = new JsonArray();
Set extends Element> dataElements = roundEnv.getElementsAnnotatedWith(Data.class);
for (Element dataElement : dataElements) {
diff --git a/Packager/src/main/groovy/com/christophecvb/touchportal/packager/TouchPortalPluginPackager.groovy b/Packager/src/main/groovy/com/christophecvb/touchportal/packager/TouchPortalPluginPackager.groovy
index 453e64e..4a1d305 100644
--- a/Packager/src/main/groovy/com/christophecvb/touchportal/packager/TouchPortalPluginPackager.groovy
+++ b/Packager/src/main/groovy/com/christophecvb/touchportal/packager/TouchPortalPluginPackager.groovy
@@ -53,6 +53,8 @@ class TouchPortalPluginPackager implements Plugin {
}
def copyResources = project.tasks.register('copyResources', Copy) {
+ dependsOn project.processResources
+
group = 'Touch Portal Plugin'
from(project.file("${project.buildDir}/resources/main/"))
into("${project.buildDir}/plugin/${extension.mainClassSimpleName.get()}/")
diff --git a/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java b/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
index 38ade3f..ca03977 100644
--- a/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
+++ b/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
@@ -147,6 +147,8 @@ public static void main(String... args) {
* Action example with no parameter
*/
@Action(description = "Long Description of Action Simple", format = "Do a simple action", categoryId = "BaseCategory")
+ @ActionTranslation(language = Language.FRENCH, description = "Description longue de Action Simple", format = "Exécute une action simple", prefix = "Mon préfixe", name = "Action Simple")
+ @ActionTranslation(language = Language.PORTUGUESE, description = "Descrição longa da Acção Simples", format = "Realiza uma acção simples", prefix = "Meu prefixo", name = "Acção Simples")
private void actionSimple() {
TouchPortalSampleJavaPlugin.LOGGER.log(Level.INFO, "Action actionSimple received");
}
From 0af69e12b746fc8515eeebafd32242ddf3eac813 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Tue, 1 Nov 2022 12:20:13 +0100
Subject: [PATCH 10/41] fix: Github Workflow
---
SampleJava/build.gradle | 2 +-
SampleKotlin/build.gradle | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/SampleJava/build.gradle b/SampleJava/build.gradle
index bcae488..8f0e6de 100644
--- a/SampleJava/build.gradle
+++ b/SampleJava/build.gradle
@@ -1,7 +1,7 @@
plugins {
id 'java'
id 'com.github.gmazzo.buildconfig' version '3.0.0'
- id 'com.christophecvb.touchportal.plugin-packager' version "$versionName+"
+ id 'com.christophecvb.touchportal.plugin-packager' version "+"
}
def mainClassSimpleName = 'TouchPortalSampleJavaPlugin'
diff --git a/SampleKotlin/build.gradle b/SampleKotlin/build.gradle
index affc3a1..6c2dda3 100644
--- a/SampleKotlin/build.gradle
+++ b/SampleKotlin/build.gradle
@@ -3,7 +3,7 @@ plugins {
id 'org.jetbrains.kotlin.kapt' version '1.5.0'
id 'java'
id 'com.github.gmazzo.buildconfig' version '3.0.0'
- id 'com.christophecvb.touchportal.plugin-packager' version "$versionName+"
+ id 'com.christophecvb.touchportal.plugin-packager' version "+"
}
def mainClassSimpleName = 'TouchPortalSampleKotlinPlugin'
From 531bcb1384379c17224c42e8350ceccbaa1bd8b6 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Tue, 1 Nov 2022 12:30:35 +0100
Subject: [PATCH 11/41] fix: Github Workflows
---
.github/workflows/develop.yml | 23 ++++++++++++++---------
.github/workflows/master.yml | 17 ++++++++++-------
.github/workflows/pr.yml | 12 ++++++------
settings.gradle | 2 +-
4 files changed, 31 insertions(+), 23 deletions(-)
diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml
index 0d8244e..ac557fd 100644
--- a/.github/workflows/develop.yml
+++ b/.github/workflows/develop.yml
@@ -10,12 +10,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Set up JDK 1.8
- uses: actions/setup-java@v1
+ uses: actions/setup-java@v3
with:
+ distribution: temurin
java-version: 1.8
- java-package: jdk
+ - name: Setup Gradle
+ uses: gradle/gradle-build-action@v2
- name: Gradle Plugin Publish Local
run: |
./gradlew :Packager:publishToMavenLocal
@@ -26,14 +28,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Set up JDK 1.8
- uses: actions/setup-java@v1
+ uses: actions/setup-java@v3
with:
+ distribution: temurin
java-version: 1.8
- java-package: jdk
- - name: Grant execute permission for gradlew
- run: chmod +x gradlew
+ - name: Setup Gradle
+ uses: gradle/gradle-build-action@v2
- name: Build with Gradle
run: ./gradlew build
@@ -45,9 +47,12 @@ jobs:
steps:
- uses: actions/checkout@v1
- name: Set up JDK 1.8
- uses: actions/setup-java@v1
+ uses: actions/setup-java@v3
with:
+ distribution: temurin
java-version: 1.8
+ - name: Setup Gradle
+ uses: gradle/gradle-build-action@v2
- name: Gradle Maven Publish
run: |
./gradlew publishMavenJavaPublicationToMavenRepository
diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml
index 6aff882..a09512a 100644
--- a/.github/workflows/master.yml
+++ b/.github/workflows/master.yml
@@ -10,14 +10,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Set up JDK 1.8
- uses: actions/setup-java@v1
+ uses: actions/setup-java@v3
with:
+ distribution: temurin
java-version: 1.8
- java-package: jdk
- - name: Grant execute permission for gradlew
- run: chmod +x gradlew
+ - name: Setup Gradle
+ uses: gradle/gradle-build-action@v2
- name: Build with Gradle
run: ./gradlew build
- name: JaCoco Test Report
@@ -33,11 +33,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v1
+ - uses: actions/checkout@v3
- name: Set up JDK 1.8
- uses: actions/setup-java@v1
+ uses: actions/setup-java@v3
with:
+ distribution: temurin
java-version: 1.8
+ - name: Setup Gradle
+ uses: gradle/gradle-build-action@v2
- name: Gradle Maven Publish
run: |
./gradlew publishMavenJavaPublicationToMavenRepository
diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
index 3e2e265..f82ce60 100644
--- a/.github/workflows/pr.yml
+++ b/.github/workflows/pr.yml
@@ -11,19 +11,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Set up JDK 1.8
- uses: actions/setup-java@v1
+ uses: actions/setup-java@v3
with:
+ distribution: temurin
java-version: 1.8
- java-package: jdk
- - name: Grant execute permission for gradlew
- run: chmod +x gradlew
+ - name: Setup Gradle
+ uses: gradle/gradle-build-action@v2
- name: Run unit tests
run: ./gradlew Library:test
- name: Upload Failing Unit Test Results
if: failure()
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v3
with:
name: Unit and Int Test Failure Results
path: ./Library/build/reports/tests/**
diff --git a/settings.gradle b/settings.gradle
index 2388470..c96738d 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -14,7 +14,7 @@ dependencyResolutionManagement {
library('autoservice', 'com.google.auto.service:auto-service:1.0.1')
library('javapoet', 'com.squareup:javapoet:1.13.0')
library('junit', 'junit:junit:4.13.2')
- library('kotlinstdlibjdk8', 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.+')
+ library('kotlinstdlibjdk8', 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.1')
}
}
}
From 7bdbf1108bc8373cfcb1cec5243517896f38e24c Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Tue, 1 Nov 2022 12:31:52 +0100
Subject: [PATCH 12/41] fix: Github Workflows
---
.github/workflows/develop.yml | 6 +++---
.github/workflows/master.yml | 4 ++--
.github/workflows/pr.yml | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml
index ac557fd..8032c23 100644
--- a/.github/workflows/develop.yml
+++ b/.github/workflows/develop.yml
@@ -15,7 +15,7 @@ jobs:
uses: actions/setup-java@v3
with:
distribution: temurin
- java-version: 1.8
+ java-version: 8
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: Gradle Plugin Publish Local
@@ -33,7 +33,7 @@ jobs:
uses: actions/setup-java@v3
with:
distribution: temurin
- java-version: 1.8
+ java-version: 8
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: Build with Gradle
@@ -50,7 +50,7 @@ jobs:
uses: actions/setup-java@v3
with:
distribution: temurin
- java-version: 1.8
+ java-version: 8
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: Gradle Maven Publish
diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml
index a09512a..45150ab 100644
--- a/.github/workflows/master.yml
+++ b/.github/workflows/master.yml
@@ -15,7 +15,7 @@ jobs:
uses: actions/setup-java@v3
with:
distribution: temurin
- java-version: 1.8
+ java-version: 8
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: Build with Gradle
@@ -38,7 +38,7 @@ jobs:
uses: actions/setup-java@v3
with:
distribution: temurin
- java-version: 1.8
+ java-version: 8
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: Gradle Maven Publish
diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
index f82ce60..e73eef4 100644
--- a/.github/workflows/pr.yml
+++ b/.github/workflows/pr.yml
@@ -16,7 +16,7 @@ jobs:
uses: actions/setup-java@v3
with:
distribution: temurin
- java-version: 1.8
+ java-version: 8
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: Run unit tests
From b2bb0a4740a8045977b8c7465cad0441d66cf66c Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Tue, 1 Nov 2022 12:37:48 +0100
Subject: [PATCH 13/41] fix: Github Workflows
---
settings.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/settings.gradle b/settings.gradle
index c96738d..37ba134 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -14,7 +14,7 @@ dependencyResolutionManagement {
library('autoservice', 'com.google.auto.service:auto-service:1.0.1')
library('javapoet', 'com.squareup:javapoet:1.13.0')
library('junit', 'junit:junit:4.13.2')
- library('kotlinstdlibjdk8', 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.1')
+ library('kotlinstdlibjdk8', 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.10')
}
}
}
From 336b35a6c2c3a4531148ccb702556ba4e9911f2b Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Tue, 1 Nov 2022 12:50:29 +0100
Subject: [PATCH 14/41] fix: Tests wait time
---
.../touchportal/test/LibraryTests.java | 71 ++++++++++---------
1 file changed, 36 insertions(+), 35 deletions(-)
diff --git a/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java b/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java
index 2f85477..f2f8bf2 100644
--- a/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java
+++ b/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java
@@ -50,6 +50,7 @@
import static org.junit.Assert.*;
public class LibraryTests {
+ private static final long REASONABLE_TIME = 100;
private ServerSocket serverSocket;
private Socket serverSocketClient;
private TouchPortalPluginTest touchPortalPluginTest;
@@ -113,7 +114,7 @@ private void serverSocketAccept() {
}
}).start();
try {
- Thread.sleep(100);
+ Thread.sleep(REASONABLE_TIME);
}
catch (InterruptedException ignored) {}
}
@@ -137,7 +138,7 @@ public void close() {
ioException.printStackTrace();
}
try {
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
}
catch (InterruptedException e) {
e.printStackTrace();
@@ -150,7 +151,7 @@ public void close() {
@Test
public void testConnection() {
try {
- Thread.sleep(500);
+ Thread.sleep(REASONABLE_TIME);
}
catch (InterruptedException e) {
e.printStackTrace();
@@ -208,7 +209,7 @@ public void testClose() {
public void testServerSocketCloses() throws IOException, InterruptedException {
this.serverSocketClient.close();
this.serverSocket.close();
- Thread.sleep(100);
+ Thread.sleep(REASONABLE_TIME);
assertFalse(this.touchPortalPluginTest.isConnected());
}
@@ -378,7 +379,7 @@ public void testReceiveActionNoId() throws IOException, InterruptedException {
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -392,7 +393,7 @@ public void testReceiveConnectorNoId() throws IOException, InterruptedException
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -407,7 +408,7 @@ public void testReceiveActionEmptyId() throws IOException, InterruptedException
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -422,7 +423,7 @@ public void testReceiveConnectorEmptyId() throws IOException, InterruptedExcepti
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -443,7 +444,7 @@ public void testReceiveShortConnectorIdNotification() throws IOException, Interr
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -474,7 +475,7 @@ public void testReceiveDummyWithDataTextAndNumberAction() throws IOException, In
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -500,7 +501,7 @@ public void testReceiveDummyWithDataFileAction() throws IOException, Interrupted
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -515,7 +516,7 @@ public void testReceiveDummyDummyWithJsonObject() throws IOException, Interrupte
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -530,7 +531,7 @@ public void testReceiveDummyDummyWithTPActionMessage() throws IOException, Inter
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -545,7 +546,7 @@ public void testReceiveDummyDummyWithParam() throws IOException, InterruptedExce
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -561,7 +562,7 @@ public void testReceiveActionHoldableDownAndUp() throws IOException, Interrupted
jsonMessageHoldDown.addProperty(ReceivedMessageHelper.ACTION_ID, TouchPortalPluginTestConstants.BaseCategory.Actions.ActionHoldable.ID);
out.println(jsonMessageHoldDown);
- Thread.sleep(150);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isActionBeingHeld(TouchPortalPluginTestConstants.BaseCategory.Actions.ActionHoldable.ID));
@@ -571,7 +572,7 @@ public void testReceiveActionHoldableDownAndUp() throws IOException, Interrupted
jsonMessageHoldUp.addProperty(ReceivedMessageHelper.ACTION_ID, TouchPortalPluginTestConstants.BaseCategory.Actions.ActionHoldable.ID);
out.println(jsonMessageHoldUp);
- Thread.sleep(150);
+ Thread.sleep(REASONABLE_TIME);
assertNull(this.touchPortalPluginTest.isActionBeingHeld(TouchPortalPluginTestConstants.BaseCategory.Actions.ActionHoldable.ID));
@@ -589,7 +590,7 @@ public void testReceiveActionHoldablePress() throws IOException, InterruptedExce
jsonMessageHoldDown.addProperty(ReceivedMessageHelper.ACTION_ID, TouchPortalPluginTestConstants.BaseCategory.Actions.ActionHoldable.ID);
out.println(jsonMessageHoldDown);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertNull(this.touchPortalPluginTest.isActionBeingHeld(TouchPortalPluginTestConstants.BaseCategory.Actions.ActionHoldable.ID));
@@ -609,7 +610,7 @@ public void testReceiveConnectorForSlider() throws IOException, InterruptedExcep
out.println(jsonMessageConnectorForSlider);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -632,7 +633,7 @@ public void testReceiveConnectorForSliderWithData() throws IOException, Interrup
out.println(jsonMessageConnectorForSliderWithData);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -668,7 +669,7 @@ public void testReceiveConnectorForSliderWithNonData() throws IOException, Inter
out.println(jsonMessageConnectorForSliderWithNonData);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -682,7 +683,7 @@ public void testReceiveListChange() throws IOException, InterruptedException {
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -697,7 +698,7 @@ public void testReceiveListChangeNoListener() throws IOException, InterruptedExc
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -712,7 +713,7 @@ public void testReceiveActionNoListener() throws IOException, InterruptedExcepti
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -726,7 +727,7 @@ public void testReceiveBadPlugin() throws IOException, InterruptedException {
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -739,7 +740,7 @@ public void testReceiveNoMessageType() throws IOException, InterruptedException
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -753,7 +754,7 @@ public void testReceiveUnknownMessageType() throws IOException, InterruptedExcep
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -782,7 +783,7 @@ public void testReceiveInfo() throws IOException, InterruptedException {
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -805,7 +806,7 @@ public void testReceiveInfoMissingPropsAndNoListener() throws IOException, Inter
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -828,7 +829,7 @@ public void testReceiveClose() throws IOException, InterruptedException {
out.println(jsonMessage);
// Wait for the listenerThread to catch up
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertFalse(this.touchPortalPluginTest.isConnected());
assertFalse(this.touchPortalPluginTest.isListening());
@@ -839,7 +840,7 @@ public void testReceiveJSONFail() throws IOException, InterruptedException {
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println("Not a JSON Object");
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -850,7 +851,7 @@ public void testReceiveEmpty() throws IOException, InterruptedException {
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println();
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -865,7 +866,7 @@ public void testReceivePart() throws IOException, InterruptedException {
out.print("data");
out.println();
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -911,7 +912,7 @@ public void testReceiveSettings() throws IOException, InterruptedException {
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -929,7 +930,7 @@ public void testReceiveSettingsNoListener() throws IOException, InterruptedExcep
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertTrue(this.touchPortalPluginTest.isConnected());
assertTrue(this.touchPortalPluginTest.isListening());
@@ -958,7 +959,7 @@ public void testSendSettingUpdate() throws IOException, InterruptedException {
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
- Thread.sleep(10);
+ Thread.sleep(REASONABLE_TIME);
assertFalse(this.touchPortalPluginTest.sendSettingUpdate(null, null, false));
assertFalse(this.touchPortalPluginTest.sendSettingUpdate("", null, false));
From 93b8668e38b78ca91534d7d1870ec475ffeae981 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Tue, 1 Nov 2022 13:07:42 +0100
Subject: [PATCH 15/41] fix: Packager SNAPSHOT publication
---
Packager/build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Packager/build.gradle b/Packager/build.gradle
index 42d58ab..386cb06 100644
--- a/Packager/build.gradle
+++ b/Packager/build.gradle
@@ -7,7 +7,7 @@ plugins {
group 'com.christophecvb.touchportal'
def localArchiveBaseName = 'plugin-packager'
-version versionName
+version versionName + (isRelease ? '' : '-' + System.currentTimeSeconds())
pluginBundle {
website = 'https://github.com/ChristopheCVB/TouchPortalPluginSDK'
From dbaa8cc4761943e2918d607e5e61390e6bbed6ab Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Tue, 1 Nov 2022 13:15:49 +0100
Subject: [PATCH 16/41] fix: Packager SNAPSHOT publication
---
Packager/build.gradle | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Packager/build.gradle b/Packager/build.gradle
index 386cb06..62564ee 100644
--- a/Packager/build.gradle
+++ b/Packager/build.gradle
@@ -1,13 +1,14 @@
plugins {
id 'groovy-gradle-plugin'
- id 'com.gradle.plugin-publish' version '0.15.0'
+ id 'com.gradle.plugin-publish' version '1.0.0'
id 'maven-publish'
id 'signing'
}
group 'com.christophecvb.touchportal'
def localArchiveBaseName = 'plugin-packager'
-version versionName + (isRelease ? '' : '-' + System.currentTimeSeconds())
+//version versionName + (isRelease ? '' : '-' + System.currentTimeSeconds())
+version isRelease ? versionName : versionName.replace('-SNAPSHOT', '-' + System.currentTimeSeconds())
pluginBundle {
website = 'https://github.com/ChristopheCVB/TouchPortalPluginSDK'
From 7b6f062037d72f70f302f756694fea8ce3663295 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Tue, 1 Nov 2022 13:20:27 +0100
Subject: [PATCH 17/41] fix: Packager SNAPSHOT publication
---
Packager/build.gradle | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Packager/build.gradle b/Packager/build.gradle
index 62564ee..7d32b03 100644
--- a/Packager/build.gradle
+++ b/Packager/build.gradle
@@ -1,13 +1,12 @@
plugins {
id 'groovy-gradle-plugin'
- id 'com.gradle.plugin-publish' version '1.0.0'
+ id 'com.gradle.plugin-publish' version '0.15.0'
id 'maven-publish'
id 'signing'
}
group 'com.christophecvb.touchportal'
def localArchiveBaseName = 'plugin-packager'
-//version versionName + (isRelease ? '' : '-' + System.currentTimeSeconds())
version isRelease ? versionName : versionName.replace('-SNAPSHOT', '-' + System.currentTimeSeconds())
pluginBundle {
From 925e94f6be8263f22dd757f6ba352c84dc9981fb Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Tue, 1 Nov 2022 19:53:54 +0100
Subject: [PATCH 18/41] fix: Packager SNAPSHOT publication
---
Packager/build.gradle | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/Packager/build.gradle b/Packager/build.gradle
index 7d32b03..a24250c 100644
--- a/Packager/build.gradle
+++ b/Packager/build.gradle
@@ -1,8 +1,7 @@
plugins {
- id 'groovy-gradle-plugin'
- id 'com.gradle.plugin-publish' version '0.15.0'
- id 'maven-publish'
+ id 'com.gradle.plugin-publish' version '1.0.0'
id 'signing'
+ id 'groovy-gradle-plugin'
}
group 'com.christophecvb.touchportal'
@@ -68,7 +67,7 @@ publishing {
repositories {
maven {
- url = version.endsWith('SNAPSHOT') ? 'https://s01.oss.sonatype.org/content/repositories/snapshots/' : 'https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/'
+ url = version.contains('-') ? 'https://s01.oss.sonatype.org/content/repositories/snapshots/' : 'https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/'
credentials {
username = envOrPropOrEmpty('OSSRH_USERNAME')
password = envOrPropOrEmpty('OSSRH_PASSWORD')
From 8be5356af7c203cb8e3228947299e2b35cabe4ab Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Tue, 1 Nov 2022 19:57:17 +0100
Subject: [PATCH 19/41] fix: Packager SNAPSHOT publication
---
.github/workflows/develop.yml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml
index 8032c23..2f10fa6 100644
--- a/.github/workflows/develop.yml
+++ b/.github/workflows/develop.yml
@@ -21,6 +21,9 @@ jobs:
- name: Gradle Plugin Publish Local
run: |
./gradlew :Packager:publishToMavenLocal
+ env:
+ PGP_KEY: ${{ secrets.PGP_KEY }}
+ PGP_PWD: ${{ secrets.PGP_PWD }}
build:
From c073d8357676cdfd7e5e0f4271905e4f2c7138c5 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Tue, 1 Nov 2022 20:47:22 +0100
Subject: [PATCH 20/41] feat: Plugin ParentCategory
---
.../annotations/ParentCategory.java | 25 +++++++++++++++++++
.../touchportal/annotations/Plugin.java | 10 ++++++++
.../TouchPortalPluginAnnotationProcessor.java | 1 +
.../touchportal/helpers/PluginHelper.java | 3 ++-
.../TouchPortalSampleJavaPlugin.java | 2 +-
5 files changed, 39 insertions(+), 2 deletions(-)
create mode 100644 Annotations/src/main/java/com/christophecvb/touchportal/annotations/ParentCategory.java
diff --git a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ParentCategory.java b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ParentCategory.java
new file mode 100644
index 0000000..d7611fc
--- /dev/null
+++ b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ParentCategory.java
@@ -0,0 +1,25 @@
+package com.christophecvb.touchportal.annotations;
+
+/**
+ * Parent Categories supported by Touch Portal
+ */
+public enum ParentCategory {
+ AUDIO("audio"),
+ STREAMING("streaming"),
+ CONTENT("content"),
+ HOME_AUTOMATION("homeautomation"),
+ SOCIAL("social "),
+ GAMES("games"),
+ MISC("misc");
+
+
+ private final String key;
+
+ ParentCategory(String key) {
+ this.key = key;
+ }
+
+ public String getKey() {
+ return this.key;
+ }
+}
diff --git a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Plugin.java b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Plugin.java
index 418b32a..8f583b9 100644
--- a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Plugin.java
+++ b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Plugin.java
@@ -72,4 +72,14 @@
* @return String colorLight
*/
String colorLight();
+
+ /**
+ * Plugin Parent Category
+ *
+ * Value from enum {@link ParentCategory}
+ *
+ *
+ * @return ParentCategory parentCategory
+ */
+ ParentCategory parentCategory() default ParentCategory.MISC;
}
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationProcessor.java
index d3344ed..161c768 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationProcessor.java
@@ -146,6 +146,7 @@ private Pair processPlugin(RoundEnvironment roundE
JsonObject jsonConfiguration = new JsonObject();
jsonConfiguration.addProperty(PluginHelper.CONFIGURATION_COLOR_DARK, plugin.colorDark());
jsonConfiguration.addProperty(PluginHelper.CONFIGURATION_COLOR_LIGHT, plugin.colorLight());
+ jsonConfiguration.addProperty(PluginHelper.CONFIGURATION_PARENT_CATEGORY, plugin.parentCategory().getKey());
jsonPlugin.add(PluginHelper.CONFIGURATION, jsonConfiguration);
jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND, "java -Dapple.awt.UIElement=true -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
diff --git a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
index b4706d6..94191b8 100644
--- a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
+++ b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
@@ -36,6 +36,7 @@ public class PluginHelper {
public static final String CONFIGURATION = "configuration";
public static final String CONFIGURATION_COLOR_DARK = "colorDark";
public static final String CONFIGURATION_COLOR_LIGHT = "colorLight";
+ public static final String CONFIGURATION_PARENT_CATEGORY = "parentCategory";
public static final String PLUGIN_START_COMMAND = "plugin_start_cmd";
public static final String CATEGORIES = "categories";
public static final String SETTINGS = "settings";
@@ -43,7 +44,7 @@ public class PluginHelper {
/**
* Touch Portal Plugin System version
*/
- public static final int TOUCH_PORTAL_PLUGIN_VERSION = 6;
+ public static final int TOUCH_PORTAL_PLUGIN_VERSION = 7;
/**
* Argument passed to the jar to start the plugin
*/
diff --git a/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java b/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
index ca03977..7383fbe 100644
--- a/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
+++ b/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
@@ -32,7 +32,7 @@
import java.util.logging.Logger;
@SuppressWarnings("unused")
-@Plugin(version = BuildConfig.VERSION_CODE, colorDark = "#203060", colorLight = "#4070F0", name = "Touch Portal Plugin Example")
+@Plugin(version = BuildConfig.VERSION_CODE, colorDark = "#203060", colorLight = "#4070F0", name = "Touch Portal Plugin Example", parentCategory = ParentCategory.CONTENT)
public class TouchPortalSampleJavaPlugin extends TouchPortalPlugin implements TouchPortalPlugin.TouchPortalPluginListener {
/**
* Logger
From 829133b32eaee1290b181cde95c73982d8211bd2 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Wed, 2 Nov 2022 01:25:37 +0100
Subject: [PATCH 21/41] feat: TouchPortalPlugin.getBase64ImageFromUrl closes
#38
---
.../touchportal/TouchPortalPlugin.java | 47 +++++++++++++++++--
1 file changed, 43 insertions(+), 4 deletions(-)
diff --git a/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java b/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
index 37865d0..cc829bb 100644
--- a/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
+++ b/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
@@ -27,6 +27,8 @@
import com.google.gson.*;
import okhttp3.*;
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -34,12 +36,10 @@
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
+import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
+import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.*;
@@ -135,6 +135,10 @@ public abstract class TouchPortalPlugin {
* Current Held Actions States
*/
private final HashMap heldActionsStates = new HashMap<>();
+ /**
+ * Map containing image urls and their base64 representation
+ */
+ private final HashMap base64Images = new HashMap<>();
/**
* Executor Service for callbacks
*/
@@ -1197,6 +1201,41 @@ public Boolean isActionBeingHeld(String actionId) {
return this.heldActionsStates.get(actionId);
}
+ /**
+ * Convert an image url to a base64 representation
+ *
+ * @param imageUrl String
+ * @return String base64Image
+ */
+ public String getBase64ImageFromUrl(String imageUrl) {
+ String base64Image = "";
+ if (this.base64Images.containsKey(imageUrl)) {
+ base64Image = this.base64Images.get(imageUrl);
+ }
+ else {
+ ByteArrayOutputStream byteArrayOutputStream = null;
+ try {
+ BufferedImage bufferedImage = ImageIO.read(new URL(imageUrl));
+
+ ImageIO.write(bufferedImage, "jpg", byteArrayOutputStream = new ByteArrayOutputStream());
+ base64Image = Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
+ this.base64Images.put(imageUrl, base64Image);
+ }
+ catch (Exception exception) {
+ LOGGER.warning(exception.getMessage() + " for Image URL: " + imageUrl);
+ }
+ finally {
+ if (byteArrayOutputStream != null) {
+ try {
+ byteArrayOutputStream.close();
+ }
+ catch (IOException ignored) {}
+ }
+ }
+ }
+ return base64Image;
+ }
+
/**
* Interface Definition for Callbacks
*/
From e7f9a6e719d32f0d16401c2eb19df320d4e7d23d Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Mon, 14 Nov 2022 23:06:02 +0100
Subject: [PATCH 22/41] fix: Set encoding to UTF-8
---
.../touchportal/packager/TouchPortalPluginPackager.groovy | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Packager/src/main/groovy/com/christophecvb/touchportal/packager/TouchPortalPluginPackager.groovy b/Packager/src/main/groovy/com/christophecvb/touchportal/packager/TouchPortalPluginPackager.groovy
index 4a1d305..c111e8c 100644
--- a/Packager/src/main/groovy/com/christophecvb/touchportal/packager/TouchPortalPluginPackager.groovy
+++ b/Packager/src/main/groovy/com/christophecvb/touchportal/packager/TouchPortalPluginPackager.groovy
@@ -17,8 +17,9 @@ class TouchPortalPluginPackager implements Plugin {
project.tasks.withType(JavaCompile) { task ->
task.doFirst {
- println('Adding -parameters to Compiler Args')
+ println('Adding -parameters to Compiler Args and setting encoding to UTF-8')
options.compilerArgs.add('-parameters')
+ options.encoding = "UTF-8"
}
}
From 14abfe7234a0f38583fc54ad20ee105c222712e1 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Mon, 14 Nov 2022 23:07:35 +0100
Subject: [PATCH 23/41] feat: TP Plugin API 7 Platform start command
---
.../TouchPortalPluginAnnotationProcessor.java | 3 +++
.../touchportal/helpers/PluginHelper.java | 3 +++
README.md | 20 +++++++------------
SampleJava/build.gradle | 2 +-
.../TouchPortalSampleJavaPlugin.java | 2 +-
SampleKotlin/build.gradle | 2 +-
6 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationProcessor.java
index 161c768..26489b0 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationProcessor.java
@@ -149,6 +149,9 @@ private Pair processPlugin(RoundEnvironment roundE
jsonConfiguration.addProperty(PluginHelper.CONFIGURATION_PARENT_CATEGORY, plugin.parentCategory().getKey());
jsonPlugin.add(PluginHelper.CONFIGURATION, jsonConfiguration);
jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND, "java -Dapple.awt.UIElement=true -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
+ jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND + PluginHelper.PLUGIN_START_COMMAND_SUFFIX_WIN, "java -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
+ jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND + PluginHelper.PLUGIN_START_COMMAND_SUFFIX_MACOS, "java -Dapple.awt.UIElement=true -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
+ jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND + PluginHelper.PLUGIN_START_COMMAND_SUFFIX_LINUX, "java -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
TypeSpec.Builder settingsTypeSpecBuilder = TypeSpec.classBuilder("Settings").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
JsonArray jsonSettings = new JsonArray();
diff --git a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
index 94191b8..e8819d7 100644
--- a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
+++ b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
@@ -38,6 +38,9 @@ public class PluginHelper {
public static final String CONFIGURATION_COLOR_LIGHT = "colorLight";
public static final String CONFIGURATION_PARENT_CATEGORY = "parentCategory";
public static final String PLUGIN_START_COMMAND = "plugin_start_cmd";
+ public static final String PLUGIN_START_COMMAND_SUFFIX_WIN = "_windows";
+ public static final String PLUGIN_START_COMMAND_SUFFIX_MACOS = "_mac";
+ public static final String PLUGIN_START_COMMAND_SUFFIX_LINUX = "_linux";
public static final String CATEGORIES = "categories";
public static final String SETTINGS = "settings";
diff --git a/README.md b/README.md
index 7546e47..d06b1ae 100644
--- a/README.md
+++ b/README.md
@@ -18,26 +18,24 @@ Once you have cloned this project, you can run the `gradlew javaDoc` and browse
## Releases
-Latest is 8.0.0
-
-Go to [releases](https://github.com/ChristopheCVB/TouchPortalPluginSDK/releases)
+Go to [releases](https://github.com/ChristopheCVB/TouchPortalPluginSDK/releases) to check which is the latest
### Maven Central
-Latest version is `8.0.0`
-
-Prior versions were not published to Maven Central
+Versions before `7.0.0` were not published to Maven Central
#### Gradle
```groovy
plugins {
- id 'com.christophecvb.touchportal.plugin-packager' version '8.0.0'
+ id 'com.christophecvb.touchportal.plugin-packager' version 'X.Y.Z'
}
+tpPlugin.mainClassSimpleName = 'MyTouchPortalPlugin'
+
dependencies {
- implementation 'com.christophecvb.touchportal:plugin-sdk:8.0.0'
- annotationProcessor 'com.christophecvb.touchportal:plugin-sdk-annotations-processor:8.0.0'
+ implementation 'com.christophecvb.touchportal:plugin-sdk:X.Y.Z'
+ annotationProcessor 'com.christophecvb.touchportal:plugin-sdk-annotations-processor:X.Y.Z'
}
```
@@ -262,7 +260,3 @@ public class MyTouchPortalPlugin extends TouchPortalPlugin {
- Arguments: `start`
- Working Directory: `YourModule/build/plugin/YourTouchPortalPlugin`
[![Touch Portal Plugin SDK Gradle Application Configuration](https://raw.githubusercontent.com/ChristopheCVB/TouchPortalPluginSDK/master/resources/TP%20Plugin%20SDK%20Gradle%20Application%20Configuration.png)](#debugging-tips)
-
-## ROADMAP
-
-The roadmap can be found [here](https://github.com/ChristopheCVB/TouchPortalPluginSDK/projects/1)
diff --git a/SampleJava/build.gradle b/SampleJava/build.gradle
index 8f0e6de..306d47b 100644
--- a/SampleJava/build.gradle
+++ b/SampleJava/build.gradle
@@ -1,6 +1,6 @@
plugins {
id 'java'
- id 'com.github.gmazzo.buildconfig' version '3.0.0'
+ id 'com.github.gmazzo.buildconfig' version '3.1.0'
id 'com.christophecvb.touchportal.plugin-packager' version "+"
}
diff --git a/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java b/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
index 7383fbe..bdfeca5 100644
--- a/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
+++ b/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
@@ -20,10 +20,10 @@
package com.christophecvb.touchportal.samplejava;
+import com.christophecvb.touchportal.TouchPortalPlugin;
import com.christophecvb.touchportal.annotations.*;
import com.christophecvb.touchportal.helpers.PluginHelper;
import com.christophecvb.touchportal.helpers.ReceivedMessageHelper;
-import com.christophecvb.touchportal.TouchPortalPlugin;
import com.christophecvb.touchportal.model.*;
import com.google.gson.JsonObject;
diff --git a/SampleKotlin/build.gradle b/SampleKotlin/build.gradle
index 6c2dda3..1faf69d 100644
--- a/SampleKotlin/build.gradle
+++ b/SampleKotlin/build.gradle
@@ -2,7 +2,7 @@ plugins {
id 'org.jetbrains.kotlin.jvm' version '1.5.0'
id 'org.jetbrains.kotlin.kapt' version '1.5.0'
id 'java'
- id 'com.github.gmazzo.buildconfig' version '3.0.0'
+ id 'com.github.gmazzo.buildconfig' version '3.1.0'
id 'com.christophecvb.touchportal.plugin-packager' version "+"
}
From c39594bed9e052e89d490a86bbf1f144e6405fb4 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Sun, 27 Nov 2022 02:39:31 +0100
Subject: [PATCH 24/41] core: Refactor Annotations Processor core: TP_JAVA_FILE
---
.../processor/CategoryProcessor.java | 108 ++
.../processor/PluginProcessor.java | 79 ++
.../processor/SettingProcessor.java | 70 ++
.../processor/TPAnnotationException.java | 51 +
.../TouchPortalPluginAnnotationProcessor.java | 1114 -----------------
...TouchPortalPluginAnnotationsProcessor.java | 620 +++++++++
.../processor/utils/SpecUtils.java | 303 +++++
.../javax.annotation.processing.Processor | 2 +-
.../touchportal/helpers/PluginHelper.java | 4 +
.../TouchPortalPluginTest/plugin.config | 2 +-
10 files changed, 1237 insertions(+), 1116 deletions(-)
create mode 100644 AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java
create mode 100644 AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java
create mode 100644 AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java
create mode 100644 AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TPAnnotationException.java
delete mode 100644 AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationProcessor.java
create mode 100644 AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationsProcessor.java
create mode 100644 AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/utils/SpecUtils.java
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java
new file mode 100644
index 0000000..5270f0e
--- /dev/null
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java
@@ -0,0 +1,108 @@
+package com.christophecvb.touchportal.annotations.processor;
+
+import com.christophecvb.touchportal.annotations.*;
+import com.christophecvb.touchportal.annotations.processor.utils.Pair;
+import com.christophecvb.touchportal.annotations.processor.utils.SpecUtils;
+import com.christophecvb.touchportal.helpers.CategoryHelper;
+import com.christophecvb.touchportal.helpers.GenericHelper;
+import com.christophecvb.touchportal.helpers.PluginHelper;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.squareup.javapoet.TypeSpec;
+
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.Modifier;
+import javax.tools.Diagnostic;
+import java.util.Set;
+
+public class CategoryProcessor {
+ /**
+ * Generates a JsonObject and a TypeSpec.Builder representing the {@link Category}
+ *
+ * @param roundEnv RoundEnvironment
+ * @param pluginElement Element
+ * @param plugin {@link Plugin}
+ * @param categoryElement Element
+ * @return Pair categoryPair
+ * @throws GenericHelper.TPTypeException If a used type is not Supported
+ */
+ public static Pair process(TouchPortalPluginAnnotationsProcessor processor, RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement) throws Exception {
+ processor.getMessager().printMessage(Diagnostic.Kind.NOTE, "Process Category: " + categoryElement.getSimpleName());
+ Category category = categoryElement.getAnnotation(Category.class);
+
+ TypeSpec.Builder categoryTypeSpecBuilder = SpecUtils.createCategoryTypeSpecBuilder(pluginElement, categoryElement, category);
+
+ JsonObject jsonCategory = new JsonObject();
+ jsonCategory.addProperty(CategoryHelper.ID, CategoryHelper.getCategoryId(pluginElement, categoryElement, category));
+ jsonCategory.addProperty(CategoryHelper.NAME, CategoryHelper.getCategoryName(categoryElement, category));
+ jsonCategory.addProperty(CategoryHelper.IMAGE_PATH, PluginHelper.TP_PLUGIN_FOLDER + pluginElement.getSimpleName() + "/" + category.imagePath());
+
+ TypeSpec.Builder actionsTypeSpecBuilder = TypeSpec.classBuilder("Actions").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+ JsonArray jsonActions = new JsonArray();
+ Set extends Element> actionElements = roundEnv.getElementsAnnotatedWith(Action.class);
+ for (Element actionElement : actionElements) {
+ Action action = actionElement.getAnnotation(Action.class);
+ String categoryId = category.id().isEmpty() ? categoryElement.getSimpleName().toString() : category.id();
+ if (categoryId.equals(action.categoryId())) {
+ Pair actionResult = processor.processAction(roundEnv, pluginElement, plugin, categoryElement, category, actionElement);
+ jsonActions.add(actionResult.first);
+ actionsTypeSpecBuilder.addType(actionResult.second.build());
+ }
+ }
+ categoryTypeSpecBuilder.addType(actionsTypeSpecBuilder.build());
+ jsonCategory.add(CategoryHelper.ACTIONS, jsonActions);
+
+ TypeSpec.Builder connectorsTypeSpecBuilder = TypeSpec.classBuilder("Connectors").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+ JsonArray jsonConnectors = new JsonArray();
+ Set extends Element> connectorElements = roundEnv.getElementsAnnotatedWith(Connector.class);
+ for (Element connectorElement : connectorElements) {
+ Connector connector = connectorElement.getAnnotation(Connector.class);
+ String categoryId = category.id().isEmpty() ? categoryElement.getSimpleName().toString() : category.id();
+ if (categoryId.equals(connector.categoryId())) {
+ Pair connectorResult = processor.processConnector(roundEnv, pluginElement, plugin, categoryElement, category, connectorElement);
+ jsonConnectors.add(connectorResult.first);
+ connectorsTypeSpecBuilder.addType(connectorResult.second.build());
+ }
+ }
+ categoryTypeSpecBuilder.addType(connectorsTypeSpecBuilder.build());
+ jsonCategory.add(CategoryHelper.CONNECTORS, jsonConnectors);
+
+ TypeSpec.Builder statesTypeSpecBuilder = TypeSpec.classBuilder("States").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+ JsonArray jsonStates = new JsonArray();
+ Set extends Element> stateElements = roundEnv.getElementsAnnotatedWith(State.class);
+ for (Element stateElement : stateElements) {
+ State state = stateElement.getAnnotation(State.class);
+ String categoryId = category.id().isEmpty() ? categoryElement.getSimpleName().toString() : category.id();
+ if (categoryId.equals(state.categoryId())) {
+ Pair stateResult = processor.processState(roundEnv, pluginElement, plugin, categoryElement, category, stateElement);
+ jsonStates.add(stateResult.first);
+ statesTypeSpecBuilder.addType(stateResult.second.build());
+ }
+ }
+ categoryTypeSpecBuilder.addType(statesTypeSpecBuilder.build());
+ jsonCategory.add(CategoryHelper.STATES, jsonStates);
+
+ TypeSpec.Builder eventsTypeSpecBuilder = TypeSpec.classBuilder("Events").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+ JsonArray jsonEvents = new JsonArray();
+ Set extends Element> eventElements = roundEnv.getElementsAnnotatedWith(Event.class);
+ for (Element eventElement : eventElements) {
+ State state = eventElement.getAnnotation(State.class);
+ String categoryId = category.id().isEmpty() ? categoryElement.getSimpleName().toString() : category.id();
+ if (state != null) {
+ if (categoryId.equals(state.categoryId())) {
+ Pair eventResult = processor.processEvent(roundEnv, pluginElement, plugin, categoryElement, category, eventElement);
+ jsonEvents.add(eventResult.first);
+ eventsTypeSpecBuilder.addType(eventResult.second.build());
+ }
+ }
+ else {
+ throw new TPAnnotationException.Builder(State.class).isMissing(true).forElement(eventElement).build();
+ }
+ }
+ categoryTypeSpecBuilder.addType(eventsTypeSpecBuilder.build());
+ jsonCategory.add(CategoryHelper.EVENTS, jsonEvents);
+
+ return Pair.create(jsonCategory, categoryTypeSpecBuilder);
+ }
+}
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java
new file mode 100644
index 0000000..7e4e505
--- /dev/null
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java
@@ -0,0 +1,79 @@
+package com.christophecvb.touchportal.annotations.processor;
+
+import com.christophecvb.touchportal.annotations.Category;
+import com.christophecvb.touchportal.annotations.Plugin;
+import com.christophecvb.touchportal.annotations.Setting;
+import com.christophecvb.touchportal.annotations.processor.utils.Pair;
+import com.christophecvb.touchportal.annotations.processor.utils.SpecUtils;
+import com.christophecvb.touchportal.helpers.GenericHelper;
+import com.christophecvb.touchportal.helpers.PluginHelper;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.squareup.javapoet.TypeSpec;
+
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.Modifier;
+import javax.tools.Diagnostic;
+import java.util.Set;
+
+public class PluginProcessor {
+ /**
+ * Generates a JsonObject and a TypeSpec.Builder representing the {@link Plugin}
+ *
+ * @param roundEnv RoundEnvironment
+ * @param pluginElement Element
+ * @return Pair pluginPair
+ * @throws GenericHelper.TPTypeException If a used type is not Supported
+ */
+ public static Pair process(TouchPortalPluginAnnotationsProcessor processor, RoundEnvironment roundEnv, Element pluginElement) throws Exception {
+ processor.getMessager().printMessage(Diagnostic.Kind.NOTE, "Process Plugin: " + pluginElement.getSimpleName());
+ Plugin plugin = pluginElement.getAnnotation(Plugin.class);
+
+ TypeSpec.Builder pluginTypeSpecBuilder = SpecUtils.createPluginTypeSpecBuilder(pluginElement, plugin);
+
+ JsonObject jsonPlugin = new JsonObject();
+ jsonPlugin.addProperty(PluginHelper.SDK, PluginHelper.TOUCH_PORTAL_PLUGIN_VERSION);
+ jsonPlugin.addProperty(PluginHelper.VERSION, plugin.version());
+ jsonPlugin.addProperty(PluginHelper.NAME, PluginHelper.getPluginName(pluginElement, plugin));
+ jsonPlugin.addProperty(PluginHelper.ID, PluginHelper.getPluginId(pluginElement));
+ JsonObject jsonConfiguration = new JsonObject();
+ jsonConfiguration.addProperty(PluginHelper.CONFIGURATION_COLOR_DARK, plugin.colorDark());
+ jsonConfiguration.addProperty(PluginHelper.CONFIGURATION_COLOR_LIGHT, plugin.colorLight());
+ jsonConfiguration.addProperty(PluginHelper.CONFIGURATION_PARENT_CATEGORY, plugin.parentCategory().getKey());
+ jsonPlugin.add(PluginHelper.CONFIGURATION, jsonConfiguration);
+ jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND, PluginHelper.TP_JAVA + " -Dapple.awt.UIElement=true -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
+ jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND + PluginHelper.PLUGIN_START_COMMAND_SUFFIX_WIN, PluginHelper.TP_JAVA + " -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
+ jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND + PluginHelper.PLUGIN_START_COMMAND_SUFFIX_MACOS, PluginHelper.TP_JAVA + " -Dapple.awt.UIElement=true -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
+ jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND + PluginHelper.PLUGIN_START_COMMAND_SUFFIX_LINUX, PluginHelper.TP_JAVA + " -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
+
+ TypeSpec.Builder settingsTypeSpecBuilder = TypeSpec.classBuilder("Settings").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+ JsonArray jsonSettings = new JsonArray();
+ Set extends Element> settingElements = roundEnv.getElementsAnnotatedWith(Setting.class);
+ for (Element settingElement : settingElements) {
+ Pair settingResult = SettingProcessor.process(processor, settingElement);
+ jsonSettings.add(settingResult.first);
+ settingsTypeSpecBuilder.addType(settingResult.second.build());
+ }
+ if (jsonSettings.size() > 0) {
+ jsonPlugin.add(PluginHelper.SETTINGS, jsonSettings);
+ }
+ pluginTypeSpecBuilder.addType(settingsTypeSpecBuilder.build());
+
+ JsonArray jsonCategories = new JsonArray();
+ Set extends Element> categoryElements = roundEnv.getElementsAnnotatedWith(Category.class);
+ for (Element categoryElement : categoryElements) {
+ Pair categoryResult = CategoryProcessor.process(processor, roundEnv, pluginElement, plugin, categoryElement);
+ jsonCategories.add(categoryResult.first);
+ pluginTypeSpecBuilder.addType(categoryResult.second.build());
+ }
+ if (jsonCategories.size() > 0) {
+ jsonPlugin.add(PluginHelper.CATEGORIES, jsonCategories);
+ }
+ else {
+ throw new TPAnnotationException.Builder(Category.class).isMissing(true).build();
+ }
+
+ return Pair.create(jsonPlugin, pluginTypeSpecBuilder);
+ }
+}
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java
new file mode 100644
index 0000000..d5c636f
--- /dev/null
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java
@@ -0,0 +1,70 @@
+package com.christophecvb.touchportal.annotations.processor;
+
+import com.christophecvb.touchportal.annotations.Setting;
+import com.christophecvb.touchportal.annotations.processor.utils.Pair;
+import com.christophecvb.touchportal.annotations.processor.utils.SpecUtils;
+import com.christophecvb.touchportal.helpers.GenericHelper;
+import com.christophecvb.touchportal.helpers.SettingHelper;
+import com.google.gson.JsonObject;
+import com.squareup.javapoet.TypeSpec;
+
+import javax.lang.model.element.Element;
+import javax.tools.Diagnostic;
+
+public class SettingProcessor {
+ /**
+ * Generates a JsonObject and a TypeSpec.Builder representing the {@link Setting}
+ *
+ * @param settingElement Element
+ * @return Pair statePair
+ * @throws GenericHelper.TPTypeException If a used type is not Supported
+ */
+ public static Pair process(TouchPortalPluginAnnotationsProcessor processor, Element settingElement) throws Exception {
+ processor.getMessager().printMessage(Diagnostic.Kind.NOTE, "Process Setting: " + settingElement.getSimpleName());
+ Setting setting = settingElement.getAnnotation(Setting.class);
+
+ TypeSpec.Builder settingTypeSpecBuilder = SpecUtils.createSettingTypeSpecBuilder(settingElement, setting);
+
+ String className = settingElement.getEnclosingElement().getSimpleName() + "." + settingElement.getSimpleName();
+
+ JsonObject jsonSetting = new JsonObject();
+ jsonSetting.addProperty(SettingHelper.NAME, SettingHelper.getSettingName(settingElement, setting));
+ String desiredTPType = GenericHelper.getTouchPortalType(className, settingElement);
+ jsonSetting.addProperty(SettingHelper.TYPE, desiredTPType);
+ jsonSetting.addProperty(SettingHelper.DEFAULT, setting.defaultValue());
+ jsonSetting.addProperty(SettingHelper.IS_READ_ONLY, setting.isReadOnly());
+ switch (desiredTPType) {
+ case SettingHelper.TYPE_TEXT:
+ if (setting.maxLength() > 0) {
+ jsonSetting.addProperty(SettingHelper.MAX_LENGTH, setting.maxLength());
+ }
+ if (setting.isPassword()) {
+ jsonSetting.addProperty(SettingHelper.IS_PASSWORD, true);
+ }
+ break;
+
+ case SettingHelper.TYPE_NUMBER:
+ try {
+ double defaultValue = Double.parseDouble(setting.defaultValue());
+ if (defaultValue < setting.minValue() || defaultValue > setting.maxValue()) {
+ throw new GenericHelper.TPTypeException.Builder(className).defaultNotInRange().build();
+ }
+ }
+ catch (NumberFormatException numberFormatException) {
+ throw new GenericHelper.TPTypeException.Builder(className).defaultInvalid(setting.defaultValue()).build();
+ }
+ if (setting.minValue() > Double.NEGATIVE_INFINITY) {
+ jsonSetting.addProperty(SettingHelper.MIN_VALUE, setting.minValue());
+ }
+ if (setting.maxValue() < Double.POSITIVE_INFINITY) {
+ jsonSetting.addProperty(SettingHelper.MAX_VALUE, setting.maxValue());
+ }
+ break;
+
+ default:
+ throw new GenericHelper.TPTypeException.Builder(className).typeUnsupported(desiredTPType).forAnnotation(GenericHelper.TPTypeException.ForAnnotation.SETTING).build();
+ }
+
+ return Pair.create(jsonSetting, settingTypeSpecBuilder);
+ }
+}
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TPAnnotationException.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TPAnnotationException.java
new file mode 100644
index 0000000..c680bbf
--- /dev/null
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TPAnnotationException.java
@@ -0,0 +1,51 @@
+package com.christophecvb.touchportal.annotations.processor;
+
+import javax.lang.model.element.Element;
+import java.lang.annotation.Annotation;
+
+public class TPAnnotationException extends Exception {
+ private TPAnnotationException(Class extends Annotation> annotationType, Boolean isMissing, Integer count, Element element, String typeFor) {
+ super(annotationType.getSimpleName() + " Annotation"
+ + (isMissing != null && isMissing ? " is missing" : "")
+ + (count != null ? " count cannot be " + count : "")
+ + (typeFor != null ? " " + typeFor : "")
+ + (element != null ? " for element " + element.getSimpleName() : "")
+ );
+ }
+
+ public static class Builder {
+ private final Class extends Annotation> annotationType;
+ private Boolean isMissing;
+ private Integer count;
+ private Element element;
+ private String typeFor;
+
+ public Builder(Class extends Annotation> annotationType) {
+ this.annotationType = annotationType;
+ }
+
+ public Builder isMissing(Boolean isMissing) {
+ this.isMissing = isMissing;
+ return this;
+ }
+
+ public Builder forElement(Element element) {
+ this.element = element;
+ return this;
+ }
+
+ public Builder typeFor(String type, String forElement, String because) {
+ this.typeFor = "type for " + forElement + " cannot be " + type + " because " + because;
+ return this;
+ }
+
+ public Builder count(int count) {
+ this.count = count;
+ return this;
+ }
+
+ public TPAnnotationException build() {
+ return new TPAnnotationException(this.annotationType, this.isMissing, this.count, this.element, this.typeFor);
+ }
+ }
+}
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationProcessor.java
deleted file mode 100644
index 26489b0..0000000
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationProcessor.java
+++ /dev/null
@@ -1,1114 +0,0 @@
-/*
- * Touch Portal Plugin SDK
- *
- * Copyright 2020 Christophe Carvalho Vilas-Boas
- * christophe.carvalhovilasboas@gmail.com
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.christophecvb.touchportal.annotations.processor;
-
-import com.christophecvb.touchportal.annotations.*;
-import com.christophecvb.touchportal.annotations.processor.utils.Pair;
-import com.christophecvb.touchportal.helpers.*;
-import com.google.auto.service.AutoService;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonObject;
-import com.squareup.javapoet.ArrayTypeName;
-import com.squareup.javapoet.FieldSpec;
-import com.squareup.javapoet.JavaFile;
-import com.squareup.javapoet.TypeSpec;
-
-import javax.annotation.processing.*;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.TypeElement;
-import javax.tools.Diagnostic;
-import javax.tools.FileObject;
-import javax.tools.StandardLocation;
-import java.io.Writer;
-import java.lang.annotation.AnnotationFormatError;
-import java.util.LinkedHashSet;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Touch Portal Plugin Annotation Processor
- */
-@AutoService(Processor.class)
-public class TouchPortalPluginAnnotationProcessor extends AbstractProcessor {
- private Filer filer;
- private Messager messager;
-
- public static String capitalize(String str) {
- if (str == null || str.isEmpty()) {
- return str;
- }
-
- return str.substring(0, 1).toUpperCase() + str.substring(1);
- }
-
- @Override
- public synchronized void init(ProcessingEnvironment processingEnv) {
- super.init(processingEnv);
- this.filer = processingEnv.getFiler();
- this.messager = processingEnv.getMessager();
- }
-
- @Override
- public Set getSupportedAnnotationTypes() {
- Set annotations = new LinkedHashSet<>();
- annotations.add(Plugin.class.getCanonicalName());
- annotations.add(Setting.class.getCanonicalName());
- annotations.add(Category.class.getCanonicalName());
- annotations.add(Action.class.getCanonicalName());
- annotations.add(Data.class.getCanonicalName());
- annotations.add(State.class.getCanonicalName());
- annotations.add(Event.class.getCanonicalName());
- annotations.add(Connector.class.getCanonicalName());
- return annotations;
- }
-
- @Override
- public SourceVersion getSupportedSourceVersion() {
- return SourceVersion.latestSupported();
- }
-
- @Override
- public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) {
- if (roundEnv.processingOver() || annotations.size() == 0) {
- return false;
- }
- this.messager.printMessage(Diagnostic.Kind.NOTE, this.getClass().getSimpleName() + ".process");
-
- try {
- Set extends Element> plugins = roundEnv.getElementsAnnotatedWith(Plugin.class);
- if (plugins.size() != 1) {
- throw new Exception("You need 1(one) @Plugin Annotation, you have " + plugins.size());
- }
- for (Element pluginElement : plugins) {
- Pair pluginPair = this.processPlugin(roundEnv, pluginElement);
-
- String actionFileName = "resources/" + PluginHelper.ENTRY_TP;
- FileObject actionFileObject = this.filer.createResource(StandardLocation.SOURCE_OUTPUT, "", actionFileName, pluginElement);
- Writer writer = actionFileObject.openWriter();
- writer.write(pluginPair.first.toString());
- writer.flush();
- writer.close();
-
- TypeSpec pluginTypeSpec = pluginPair.second.build();
- String packageName = ((PackageElement) pluginElement.getEnclosingElement()).getQualifiedName().toString();
- JavaFile javaConstantsFile = JavaFile.builder(packageName, pluginTypeSpec).build();
- javaConstantsFile.writeTo(this.filer);
- }
- }
- catch (Exception exception) {
- this.messager.printMessage(Diagnostic.Kind.ERROR, exception.getMessage());
- }
-
- return true;
- }
-
- /**
- * Generates a JsonObject and a TypeSpec.Builder representing the {@link Plugin}
- *
- * @param roundEnv RoundEnvironment
- * @param pluginElement Element
- * @return Pair pluginPair
- * @throws GenericHelper.TPTypeException If a used type is not Supported
- */
- private Pair processPlugin(RoundEnvironment roundEnv, Element pluginElement) throws Exception {
- this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Plugin: " + pluginElement.getSimpleName());
- Plugin plugin = pluginElement.getAnnotation(Plugin.class);
-
- TypeSpec.Builder pluginTypeSpecBuilder = this.createPluginTypeSpecBuilder(pluginElement, plugin);
-
- JsonObject jsonPlugin = new JsonObject();
- jsonPlugin.addProperty(PluginHelper.SDK, PluginHelper.TOUCH_PORTAL_PLUGIN_VERSION);
- jsonPlugin.addProperty(PluginHelper.VERSION, plugin.version());
- jsonPlugin.addProperty(PluginHelper.NAME, PluginHelper.getPluginName(pluginElement, plugin));
- jsonPlugin.addProperty(PluginHelper.ID, PluginHelper.getPluginId(pluginElement));
- JsonObject jsonConfiguration = new JsonObject();
- jsonConfiguration.addProperty(PluginHelper.CONFIGURATION_COLOR_DARK, plugin.colorDark());
- jsonConfiguration.addProperty(PluginHelper.CONFIGURATION_COLOR_LIGHT, plugin.colorLight());
- jsonConfiguration.addProperty(PluginHelper.CONFIGURATION_PARENT_CATEGORY, plugin.parentCategory().getKey());
- jsonPlugin.add(PluginHelper.CONFIGURATION, jsonConfiguration);
- jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND, "java -Dapple.awt.UIElement=true -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
- jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND + PluginHelper.PLUGIN_START_COMMAND_SUFFIX_WIN, "java -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
- jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND + PluginHelper.PLUGIN_START_COMMAND_SUFFIX_MACOS, "java -Dapple.awt.UIElement=true -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
- jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND + PluginHelper.PLUGIN_START_COMMAND_SUFFIX_LINUX, "java -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
-
- TypeSpec.Builder settingsTypeSpecBuilder = TypeSpec.classBuilder("Settings").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
- JsonArray jsonSettings = new JsonArray();
- Set extends Element> settingElements = roundEnv.getElementsAnnotatedWith(Setting.class);
- for (Element settingElement : settingElements) {
- Pair settingResult = this.processSetting(settingElement);
- jsonSettings.add(settingResult.first);
- settingsTypeSpecBuilder.addType(settingResult.second.build());
- }
- if (jsonSettings.size() > 0) {
- jsonPlugin.add(PluginHelper.SETTINGS, jsonSettings);
- }
- pluginTypeSpecBuilder.addType(settingsTypeSpecBuilder.build());
-
- JsonArray jsonCategories = new JsonArray();
- Set extends Element> categoryElements = roundEnv.getElementsAnnotatedWith(Category.class);
- for (Element categoryElement : categoryElements) {
- Pair categoryResult = this.processCategory(roundEnv, pluginElement, plugin, categoryElement);
- jsonCategories.add(categoryResult.first);
- pluginTypeSpecBuilder.addType(categoryResult.second.build());
- }
- if (jsonCategories.size() > 0) {
- jsonPlugin.add(PluginHelper.CATEGORIES, jsonCategories);
- }
- else {
- throw new Exception("Category Annotation missing");
- }
-
- return Pair.create(jsonPlugin, pluginTypeSpecBuilder);
- }
-
- /**
- * Generates a JsonObject and a TypeSpec.Builder representing the {@link Setting}
- *
- * @param settingElement Element
- * @return Pair statePair
- * @throws GenericHelper.TPTypeException If a used type is not Supported
- */
- private Pair processSetting(Element settingElement) throws Exception {
- this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Setting: " + settingElement.getSimpleName());
- Setting setting = settingElement.getAnnotation(Setting.class);
-
- TypeSpec.Builder settingTypeSpecBuilder = this.createSettingTypeSpecBuilder(settingElement, setting);
-
- String className = settingElement.getEnclosingElement().getSimpleName() + "." + settingElement.getSimpleName();
-
- JsonObject jsonSetting = new JsonObject();
- jsonSetting.addProperty(SettingHelper.NAME, SettingHelper.getSettingName(settingElement, setting));
- String desiredTPType = GenericHelper.getTouchPortalType(className, settingElement);
- jsonSetting.addProperty(SettingHelper.TYPE, desiredTPType);
- jsonSetting.addProperty(SettingHelper.DEFAULT, setting.defaultValue());
- jsonSetting.addProperty(SettingHelper.IS_READ_ONLY, setting.isReadOnly());
- switch (desiredTPType) {
- case SettingHelper.TYPE_TEXT:
- if (setting.maxLength() > 0) {
- jsonSetting.addProperty(SettingHelper.MAX_LENGTH, setting.maxLength());
- }
- if (setting.isPassword()) {
- jsonSetting.addProperty(SettingHelper.IS_PASSWORD, true);
- }
- break;
-
- case SettingHelper.TYPE_NUMBER:
- try {
- double defaultValue = Double.parseDouble(setting.defaultValue());
- if (defaultValue < setting.minValue() || defaultValue > setting.maxValue()) {
- throw new GenericHelper.TPTypeException.Builder(className).defaultNotInRange().build();
- }
- }
- catch (NumberFormatException numberFormatException) {
- throw new GenericHelper.TPTypeException.Builder(className).defaultInvalid(setting.defaultValue()).build();
- }
- if (setting.minValue() > Double.NEGATIVE_INFINITY) {
- jsonSetting.addProperty(SettingHelper.MIN_VALUE, setting.minValue());
- }
- if (setting.maxValue() < Double.POSITIVE_INFINITY) {
- jsonSetting.addProperty(SettingHelper.MAX_VALUE, setting.maxValue());
- }
- break;
-
- default:
- throw new GenericHelper.TPTypeException.Builder(className).typeUnsupported(desiredTPType).forAnnotation(GenericHelper.TPTypeException.ForAnnotation.SETTING).build();
- }
-
- return Pair.create(jsonSetting, settingTypeSpecBuilder);
- }
-
- /**
- * Generates a JsonObject and a TypeSpec.Builder representing the {@link Category}
- *
- * @param roundEnv RoundEnvironment
- * @param pluginElement Element
- * @param plugin {@link Plugin}
- * @param categoryElement Element
- * @return Pair categoryPair
- * @throws GenericHelper.TPTypeException If a used type is not Supported
- */
- private Pair processCategory(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement) throws Exception {
- this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Category: " + categoryElement.getSimpleName());
- Category category = categoryElement.getAnnotation(Category.class);
-
- TypeSpec.Builder categoryTypeSpecBuilder = this.createCategoryTypeSpecBuilder(pluginElement, categoryElement, category);
-
- JsonObject jsonCategory = new JsonObject();
- jsonCategory.addProperty(CategoryHelper.ID, CategoryHelper.getCategoryId(pluginElement, categoryElement, category));
- jsonCategory.addProperty(CategoryHelper.NAME, CategoryHelper.getCategoryName(categoryElement, category));
- jsonCategory.addProperty(CategoryHelper.IMAGE_PATH, PluginHelper.TP_PLUGIN_FOLDER + pluginElement.getSimpleName() + "/" + category.imagePath());
-
- TypeSpec.Builder actionsTypeSpecBuilder = TypeSpec.classBuilder("Actions").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
- JsonArray jsonActions = new JsonArray();
- Set extends Element> actionElements = roundEnv.getElementsAnnotatedWith(Action.class);
- for (Element actionElement : actionElements) {
- Action action = actionElement.getAnnotation(Action.class);
- String categoryId = category.id().isEmpty() ? categoryElement.getSimpleName().toString() : category.id();
- if (categoryId.equals(action.categoryId())) {
- Pair actionResult = this.processAction(roundEnv, pluginElement, plugin, categoryElement, category, actionElement);
- jsonActions.add(actionResult.first);
- actionsTypeSpecBuilder.addType(actionResult.second.build());
- }
- }
- categoryTypeSpecBuilder.addType(actionsTypeSpecBuilder.build());
- jsonCategory.add(CategoryHelper.ACTIONS, jsonActions);
-
- TypeSpec.Builder connectorsTypeSpecBuilder = TypeSpec.classBuilder("Connectors").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
- JsonArray jsonConnectors = new JsonArray();
- Set extends Element> connectorElements = roundEnv.getElementsAnnotatedWith(Connector.class);
- for (Element connectorElement : connectorElements) {
- Connector connector = connectorElement.getAnnotation(Connector.class);
- String categoryId = category.id().isEmpty() ? categoryElement.getSimpleName().toString() : category.id();
- if (categoryId.equals(connector.categoryId())) {
- Pair connectorResult = this.processConnector(roundEnv, pluginElement, plugin, categoryElement, category, connectorElement);
- jsonConnectors.add(connectorResult.first);
- connectorsTypeSpecBuilder.addType(connectorResult.second.build());
- }
- }
- categoryTypeSpecBuilder.addType(connectorsTypeSpecBuilder.build());
- jsonCategory.add(CategoryHelper.CONNECTORS, jsonConnectors);
-
- TypeSpec.Builder statesTypeSpecBuilder = TypeSpec.classBuilder("States").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
- JsonArray jsonStates = new JsonArray();
- Set extends Element> stateElements = roundEnv.getElementsAnnotatedWith(State.class);
- for (Element stateElement : stateElements) {
- State state = stateElement.getAnnotation(State.class);
- String categoryId = category.id().isEmpty() ? categoryElement.getSimpleName().toString() : category.id();
- if (categoryId.equals(state.categoryId())) {
- Pair stateResult = this.processState(roundEnv, pluginElement, plugin, categoryElement, category, stateElement);
- jsonStates.add(stateResult.first);
- statesTypeSpecBuilder.addType(stateResult.second.build());
- }
- }
- categoryTypeSpecBuilder.addType(statesTypeSpecBuilder.build());
- jsonCategory.add(CategoryHelper.STATES, jsonStates);
-
- TypeSpec.Builder eventsTypeSpecBuilder = TypeSpec.classBuilder("Events").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
- JsonArray jsonEvents = new JsonArray();
- Set extends Element> eventElements = roundEnv.getElementsAnnotatedWith(Event.class);
- for (Element eventElement : eventElements) {
- State state = eventElement.getAnnotation(State.class);
- String categoryId = category.id().isEmpty() ? categoryElement.getSimpleName().toString() : category.id();
- if (state != null) {
- if (categoryId.equals(state.categoryId())) {
- Pair eventResult = this.processEvent(roundEnv, pluginElement, plugin, categoryElement, category, eventElement);
- jsonEvents.add(eventResult.first);
- eventsTypeSpecBuilder.addType(eventResult.second.build());
- }
- }
- else {
- throw new AnnotationFormatError("The State Annotation is missing for element " + eventElement.getSimpleName());
- }
- }
- categoryTypeSpecBuilder.addType(eventsTypeSpecBuilder.build());
- jsonCategory.add(CategoryHelper.EVENTS, jsonEvents);
-
- return Pair.create(jsonCategory, categoryTypeSpecBuilder);
- }
-
- /**
- * Generates a JsonObject and a TypeSpec.Builder representing the {@link Action}
- *
- * @param roundEnv RoundEnvironment
- * @param pluginElement Element
- * @param plugin {@link Plugin}
- * @param categoryElement Element
- * @param category {@link Category}
- * @param actionElement Element
- * @return Pair actionPair
- */
- private Pair processAction(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element actionElement) throws Exception {
- this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Action: " + actionElement.getSimpleName());
- Action action = actionElement.getAnnotation(Action.class);
-
- TypeSpec.Builder actionTypeSpecBuilder = this.createActionTypeSpecBuilder(pluginElement, categoryElement, category, actionElement, action);
-
- JsonObject jsonAction = new JsonObject();
- jsonAction.addProperty(ActionHelper.ID, ActionHelper.getActionId(pluginElement, categoryElement, category, actionElement, action));
- jsonAction.addProperty(ActionHelper.NAME, ActionHelper.getActionName(actionElement, action));
- jsonAction.addProperty(ActionHelper.PREFIX, action.prefix());
- jsonAction.addProperty(ActionHelper.TYPE, action.type());
- if (!action.description().isEmpty()) {
- jsonAction.addProperty(ActionHelper.DESCRIPTION, action.description());
- }
- if (!action.format().isEmpty()) {
- jsonAction.addProperty(ActionHelper.FORMAT, action.format());
- jsonAction.addProperty(ActionHelper.TRY_INLINE, true);
- }
- jsonAction.addProperty(ActionHelper.HAS_HOLD_FUNCTIONALITY, action.hasHoldFunctionality());
-
- ActionTranslation[] actionTranslations = actionElement.getAnnotationsByType(ActionTranslation.class);
- if (actionTranslations.length > 0) {
- for (ActionTranslation actionTranslation : actionTranslations) {
- String languageCode = actionTranslation.language().getCode();
- if (!actionTranslation.name().isEmpty()) {
- jsonAction.addProperty(ActionHelper.NAME + "_" + languageCode, actionTranslation.name());
- }
- if (!actionTranslation.prefix().isEmpty()) {
- jsonAction.addProperty(ActionHelper.PREFIX + "_" + languageCode, actionTranslation.prefix());
- }
- if (!actionTranslation.description().isEmpty()) {
- jsonAction.addProperty(ActionHelper.DESCRIPTION + "_" + languageCode, actionTranslation.description());
- }
- if (!actionTranslation.format().isEmpty()) {
- jsonAction.addProperty(ActionHelper.FORMAT + "_" + languageCode, actionTranslation.format());
- }
- }
- }
-
- JsonArray jsonActionData = new JsonArray();
- Set extends Element> dataElements = roundEnv.getElementsAnnotatedWith(Data.class);
- for (Element dataElement : dataElements) {
- Element enclosingElement = dataElement.getEnclosingElement();
- if (actionElement.equals(enclosingElement)) {
- Pair actionDataResult = this.processActionData(roundEnv, pluginElement, plugin, categoryElement, category, actionElement, action, jsonAction, dataElement);
- jsonActionData.add(actionDataResult.first);
- if (actionDataResult.second != null) {
- actionTypeSpecBuilder.addType(actionDataResult.second.build());
- }
- }
- }
- if (jsonActionData.size() > 0) {
- jsonAction.add(ActionHelper.DATA, jsonActionData);
- }
-
- return Pair.create(jsonAction, actionTypeSpecBuilder);
- }
-
- /**
- * Generates a JsonObject and a TypeSpec.Builder representing the {@link Connector}
- *
- * @param roundEnv RoundEnvironment
- * @param pluginElement Element
- * @param plugin {@link Plugin}
- * @param categoryElement Element
- * @param category {@link Category}
- * @param connectorElement Element
- * @return Pair actionPair
- */
- private Pair processConnector(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element connectorElement) throws Exception {
- this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Connector: " + connectorElement.getSimpleName());
- Connector connector = connectorElement.getAnnotation(Connector.class);
-
- TypeSpec.Builder connectorTypeSpecBuilder = this.createConnectorTypeSpecBuilder(pluginElement, categoryElement, category, connectorElement, connector);
-
- JsonObject jsonConnector = new JsonObject();
- jsonConnector.addProperty(ConnectorHelper.ID, ConnectorHelper.getConnectorId(pluginElement, categoryElement, category, connectorElement, connector));
- jsonConnector.addProperty(ConnectorHelper.NAME, ConnectorHelper.getConnectorName(connectorElement, connector));
- jsonConnector.addProperty(ConnectorHelper.FORMAT, connector.format());
-
- String classMethod = pluginElement.getSimpleName() + "." + connectorElement.getSimpleName();
- boolean connectorValueFound = false;
- Set extends Element> connectorValueElements = roundEnv.getElementsAnnotatedWith(ConnectorValue.class);
- for (Element connectorValueElement : connectorValueElements) {
- Element enclosingElement = connectorValueElement.getEnclosingElement();
- if (connectorElement.equals(enclosingElement)) {
- String classMethodParameter = classMethod + "(" + connectorValueElement.getSimpleName() + ")";
- String desiredType = GenericHelper.getTouchPortalType(classMethodParameter, connectorValueElement);
- if (!desiredType.equals(GenericHelper.TP_TYPE_NUMBER)) {
- throw new GenericHelper.TPTypeException.Builder(classMethodParameter).typeUnsupported(desiredType).forAnnotation(GenericHelper.TPTypeException.ForAnnotation.CONNECTOR_VALUE).build();
- }
- connectorValueFound = true;
- break;
- }
- }
- if (!connectorValueFound) {
- throw new IllegalArgumentException("Connector " + classMethod + " has no declared ConnectorValue");
- }
-
- JsonArray jsonConnectorData = new JsonArray();
- Set extends Element> dataElements = roundEnv.getElementsAnnotatedWith(Data.class);
- for (Element dataElement : dataElements) {
- Element enclosingElement = dataElement.getEnclosingElement();
- if (connectorElement.equals(enclosingElement)) {
- Pair connectorDataResult = this.processConnectorData(roundEnv, pluginElement, plugin, categoryElement, category, connectorElement, connector, jsonConnector, dataElement);
- jsonConnectorData.add(connectorDataResult.first);
- if (connectorDataResult.second != null) {
- connectorTypeSpecBuilder.addType(connectorDataResult.second.build());
- }
- }
- }
- if (jsonConnectorData.size() > 0) {
- jsonConnector.add(ConnectorHelper.DATA, jsonConnectorData);
- }
-
- return Pair.create(jsonConnector, connectorTypeSpecBuilder);
- }
-
- /**
- * Generates a JsonObject and a TypeSpec.Builder representing the {@link State}
- *
- * @param roundEnv RoundEnvironment
- * @param pluginElement Element
- * @param plugin {@link Plugin}
- * @param categoryElement Element
- * @param category {@link Category}
- * @param stateElement Element
- * @return Pair statePair
- * @throws GenericHelper.TPTypeException If a used type is not Supported
- */
- private Pair processState(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element stateElement) throws Exception {
- this.messager.printMessage(Diagnostic.Kind.NOTE, "Process State: " + stateElement.getSimpleName());
- State state = stateElement.getAnnotation(State.class);
-
- TypeSpec.Builder stateTypeSpecBuilder = this.createStateTypeSpecBuilder(pluginElement, categoryElement, category, stateElement, state);
-
- String className = stateElement.getEnclosingElement().getSimpleName() + "." + stateElement.getSimpleName();
-
- JsonObject jsonState = new JsonObject();
- jsonState.addProperty(StateHelper.ID, StateHelper.getStateId(pluginElement, categoryElement, category, stateElement, state));
- String desiredTPType = GenericHelper.getTouchPortalType(className, stateElement);
- jsonState.addProperty(StateHelper.TYPE, desiredTPType);
- jsonState.addProperty(StateHelper.DESC, StateHelper.getStateDesc(stateElement, state));
- jsonState.addProperty(StateHelper.DEFAULT, state.defaultValue());
- if (desiredTPType.equals(StateHelper.TYPE_CHOICE)) {
- JsonArray stateValueChoices = new JsonArray();
- for (String valueChoice : state.valueChoices()) {
- stateValueChoices.add(valueChoice);
- }
- jsonState.add(StateHelper.VALUE_CHOICES, stateValueChoices);
- }
- else if (!desiredTPType.equals(StateHelper.TYPE_TEXT)) {
- throw new GenericHelper.TPTypeException.Builder(className).typeUnsupported(desiredTPType).forAnnotation(GenericHelper.TPTypeException.ForAnnotation.STATE).build();
- }
-
- Event event = stateElement.getAnnotation(Event.class);
- if (event != null && !desiredTPType.equals(StateHelper.TYPE_TEXT)) {
- throw new Exception("The type of the State Annotation for " + className + " cannot be " + desiredTPType + " because the field is also Annotated with Event. Only the type " + StateHelper.TYPE_TEXT + " is supported for a State that has an Event Annotation.");
- }
-
- return Pair.create(jsonState, stateTypeSpecBuilder);
- }
-
- /**
- * Generates a JsonObject and a TypeSpec.Builder representing the {@link Event}
- *
- * @param roundEnv RoundEnvironment
- * @param pluginElement Element
- * @param plugin {@link Plugin}
- * @param categoryElement Element
- * @param category {@link Category}
- * @param eventElement Element
- * @return Pair eventPair
- * @throws GenericHelper.TPTypeException If any used type is not Supported
- */
- private Pair processEvent(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element eventElement) throws Exception {
- this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Event: " + eventElement.getSimpleName());
- State state = eventElement.getAnnotation(State.class);
- Event event = eventElement.getAnnotation(Event.class);
-
- String reference = eventElement.getEnclosingElement().getSimpleName() + "." + eventElement.getSimpleName();
-
- if (state == null) {
- throw new Exception("The Event Annotation on " + reference + " must be used with the State Annotation");
- }
-
- TypeSpec.Builder eventTypeSpecBuilder = this.createEventTypeSpecBuilder(pluginElement, categoryElement, category, eventElement, event);
-
- JsonObject jsonEvent = new JsonObject();
- jsonEvent.addProperty(EventHelper.ID, EventHelper.getEventId(pluginElement, categoryElement, category, eventElement, event));
- jsonEvent.addProperty(EventHelper.TYPE, EventHelper.TYPE_COMMUNICATE);
- jsonEvent.addProperty(EventHelper.NAME, EventHelper.getEventName(eventElement, event));
- jsonEvent.addProperty(EventHelper.FORMAT, event.format());
- String desiredTPType = GenericHelper.getTouchPortalType(reference, eventElement);
- if (desiredTPType.equals(StateHelper.TYPE_TEXT)) {
- jsonEvent.addProperty(EventHelper.VALUE_TYPE, EventHelper.VALUE_TYPE_CHOICE);
- JsonArray eventValueChoices = new JsonArray();
- for (String valueChoice : event.valueChoices()) {
- eventValueChoices.add(valueChoice);
- }
- jsonEvent.add(EventHelper.VALUE_CHOICES, eventValueChoices);
- jsonEvent.addProperty(EventHelper.VALUE_STATE_ID, StateHelper.getStateId(pluginElement, categoryElement, category, eventElement, state));
- }
- else {
- throw new GenericHelper.TPTypeException.Builder(reference).typeUnsupported(desiredTPType).forAnnotation(GenericHelper.TPTypeException.ForAnnotation.EVENT).build();
- }
-
- return Pair.create(jsonEvent, eventTypeSpecBuilder);
- }
-
- /**
- * Generates a JsonObject and a TypeSpec.Builder representing the {@link Data} for an {@link Action}
- *
- * @param roundEnv RoundEnvironment
- * @param pluginElement Element
- * @param plugin {@link Plugin}
- * @param categoryElement Element
- * @param category {@link Category}
- * @param actionElement Element
- * @param action {@link Action}
- * @param jsonAction JsonObject
- * @param dataElement Element
- * @return Pair dataPair
- */
- private Pair processActionData(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element actionElement, Action action, JsonObject jsonAction, Element dataElement) throws Exception {
- this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Action Data: " + dataElement.getSimpleName());
- Data data = dataElement.getAnnotation(Data.class);
-
- TypeSpec.Builder actionDataTypeSpecBuilder = this.createActionDataTypeSpecBuilder(pluginElement, categoryElement, category, actionElement, action, dataElement, data);
-
- Element method = dataElement.getEnclosingElement();
- String className = method.getEnclosingElement().getSimpleName() + "." + method.getSimpleName() + "(" + dataElement.getSimpleName() + ")";
-
- JsonObject jsonData = new JsonObject();
- String desiredTPType = GenericHelper.getTouchPortalType(className, dataElement);
- jsonData.addProperty(DataHelper.TYPE, desiredTPType);
- jsonData.addProperty(DataHelper.LABEL, DataHelper.getDataLabel(dataElement, data));
- // Default Value
- switch (desiredTPType) {
- case GenericHelper.TP_TYPE_NUMBER:
- double defaultValue = 0;
- try {
- defaultValue = Double.parseDouble(data.defaultValue());
- }
- catch (NumberFormatException ignored) {}
- jsonData.addProperty(DataHelper.DEFAULT, defaultValue);
- break;
-
- case GenericHelper.TP_TYPE_SWITCH:
- jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue().equals("true"));
- break;
-
- default:
- jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue());
- break;
- }
- AtomicReference dataId = new AtomicReference<>(DataHelper.getActionDataId(pluginElement, categoryElement, category, actionElement, action, dataElement, data));
- // Specific properties
- switch (desiredTPType) {
- case GenericHelper.TP_TYPE_CHOICE:
- JsonArray dataValueChoices = new JsonArray();
- if (!data.stateId().isEmpty()) {
- Optional extends Element> optionalStateElement = roundEnv.getElementsAnnotatedWith(State.class).stream().filter(element -> {
- State state = element.getAnnotation(State.class);
- String shortStateId = !state.id().isEmpty() ? state.id() : element.getSimpleName().toString();
- return shortStateId.equals(data.stateId());
- }).findFirst();
- if (optionalStateElement.isPresent()) {
- actionDataTypeSpecBuilder = null;
-
- Element stateElement = optionalStateElement.get();
- State state = stateElement.getAnnotation(State.class);
- dataId.set(StateHelper.getStateId(pluginElement, categoryElement, category, stateElement, state));
- for (String valueChoice : state.valueChoices()) {
- dataValueChoices.add(valueChoice);
- }
- jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue().isEmpty() ? state.defaultValue() : data.defaultValue());
- }
- else {
- for (String valueChoice : data.valueChoices()) {
- dataValueChoices.add(valueChoice);
- }
- }
- }
- else {
- for (String valueChoice : data.valueChoices()) {
- dataValueChoices.add(valueChoice);
- }
- }
- jsonData.add(DataHelper.VALUE_CHOICES, dataValueChoices);
- break;
-
- case GenericHelper.TP_TYPE_FILE:
- if (data.isDirectory()) {
- jsonData.addProperty(DataHelper.TYPE, GenericHelper.TP_TYPE_DIRECTORY);
- }
- else {
- JsonArray jsonExtensions = new JsonArray();
- for (String extension : data.extensions()) {
- if (extension.matches(DataHelper.EXTENSION_FORMAT)) {
- jsonExtensions.add(extension);
- }
- else {
- this.messager.printMessage(Diagnostic.Kind.ERROR, "Action Data Extension: [" + extension + "] format is not valid");
- }
- }
- jsonData.add(DataHelper.EXTENSIONS, jsonExtensions);
- }
- break;
-
- case GenericHelper.TP_TYPE_TEXT:
- if (data.isColor()) {
- jsonData.addProperty(DataHelper.TYPE, GenericHelper.TP_TYPE_COLOR);
- if (!data.defaultValue().isEmpty()) {
- if (!data.defaultValue().matches(DataHelper.COLOR_FORMAT)) {
- this.messager.printMessage(Diagnostic.Kind.ERROR, "Action Data Color Default value: [" + data.defaultValue() + "] format is not valid");
- }
- }
- }
- break;
-
- case GenericHelper.TP_TYPE_NUMBER:
- try {
- double defaultValue = jsonData.get(DataHelper.DEFAULT).getAsDouble();
- if (defaultValue < data.minValue() || defaultValue > data.maxValue()) {
- throw new GenericHelper.TPTypeException.Builder(className).defaultNotInRange().build();
- }
- }
- catch (NumberFormatException numberFormatException) {
- throw new GenericHelper.TPTypeException.Builder(className).defaultInvalid(data.defaultValue()).build();
- }
- jsonData.addProperty(DataHelper.ALLOW_DECIMALS, GenericHelper.getTouchPortalTypeNumberAllowDecimals(dataElement.asType().toString()));
- if (data.minValue() > Double.NEGATIVE_INFINITY) {
- jsonData.addProperty(DataHelper.MIN_VALUE, data.minValue());
- }
- if (data.maxValue() < Double.POSITIVE_INFINITY) {
- jsonData.addProperty(DataHelper.MAX_VALUE, data.maxValue());
- }
- break;
- }
- jsonData.addProperty(DataHelper.ID, dataId.get());
- if (!action.format().isEmpty()) {
- // Replace wildcards
- String rawFormat = jsonAction.get(ActionHelper.FORMAT).getAsString();
- jsonAction.addProperty(ActionHelper.FORMAT, rawFormat.replace("{$" + (data.id().isEmpty() ? dataElement.getSimpleName().toString() : data.id()) + "$}", "{$" + dataId.get() + "$}"));
- }
-
- return Pair.create(jsonData, actionDataTypeSpecBuilder);
- }
-
- /**
- * Generates a JsonObject and a TypeSpec.Builder representing the {@link Data} for a {@link Connector}
- *
- * @param roundEnv RoundEnvironment
- * @param pluginElement Element
- * @param plugin {@link Plugin}
- * @param categoryElement Element
- * @param category {@link Category}
- * @param connectorElement Element
- * @param connector {@link Connector}
- * @param jsonConnector JsonObject
- * @param dataElement Element
- * @return Pair dataPair
- */
- private Pair processConnectorData(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element connectorElement, Connector connector, JsonObject jsonConnector, Element dataElement) throws Exception {
- this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Connector Data: " + dataElement.getSimpleName());
- Data data = dataElement.getAnnotation(Data.class);
-
- TypeSpec.Builder connectorDataTypeSpecBuilder = this.createConnectorDataTypeSpecBuilder(pluginElement, categoryElement, category, connectorElement, connector, dataElement, data);
-
- Element method = dataElement.getEnclosingElement();
- String className = method.getEnclosingElement().getSimpleName() + "." + method.getSimpleName() + "(" + dataElement.getSimpleName() + ")";
-
- JsonObject jsonData = new JsonObject();
- String desiredTPType = GenericHelper.getTouchPortalType(className, dataElement);
- jsonData.addProperty(DataHelper.TYPE, desiredTPType);
- jsonData.addProperty(DataHelper.LABEL, DataHelper.getDataLabel(dataElement, data));
- // Default Value
- switch (desiredTPType) {
- case GenericHelper.TP_TYPE_NUMBER:
- double defaultValue = 0;
- try {
- defaultValue = Double.parseDouble(data.defaultValue());
- }
- catch (NumberFormatException ignored) {}
- jsonData.addProperty(DataHelper.DEFAULT, defaultValue);
- break;
-
- case GenericHelper.TP_TYPE_SWITCH:
- jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue().equals("true"));
- break;
-
- default:
- jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue());
- break;
- }
- AtomicReference dataId = new AtomicReference<>(DataHelper.getConnectorDataId(pluginElement, categoryElement, category, connectorElement, connector, dataElement, data));
- // Specific properties
- switch (desiredTPType) {
- case GenericHelper.TP_TYPE_CHOICE:
- JsonArray dataValueChoices = new JsonArray();
- if (!data.stateId().isEmpty()) {
- Optional extends Element> optionalStateElement = roundEnv.getElementsAnnotatedWith(State.class).stream().filter(element -> {
- State state = element.getAnnotation(State.class);
- String shortStateId = !state.id().isEmpty() ? state.id() : element.getSimpleName().toString();
- return shortStateId.equals(data.stateId());
- }).findFirst();
- if (optionalStateElement.isPresent()) {
- connectorDataTypeSpecBuilder = null;
-
- Element stateElement = optionalStateElement.get();
- State state = stateElement.getAnnotation(State.class);
- dataId.set(StateHelper.getStateId(pluginElement, categoryElement, category, stateElement, state));
- for (String valueChoice : state.valueChoices()) {
- dataValueChoices.add(valueChoice);
- }
- jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue().isEmpty() ? state.defaultValue() : data.defaultValue());
- }
- else {
- for (String valueChoice : data.valueChoices()) {
- dataValueChoices.add(valueChoice);
- }
- }
- }
- else {
- for (String valueChoice : data.valueChoices()) {
- dataValueChoices.add(valueChoice);
- }
- }
- jsonData.add(DataHelper.VALUE_CHOICES, dataValueChoices);
- break;
-
- case GenericHelper.TP_TYPE_FILE:
- if (data.isDirectory()) {
- jsonData.addProperty(DataHelper.TYPE, GenericHelper.TP_TYPE_DIRECTORY);
- }
- else {
- JsonArray jsonExtensions = new JsonArray();
- for (String extension : data.extensions()) {
- if (extension.matches(DataHelper.EXTENSION_FORMAT)) {
- jsonExtensions.add(extension);
- }
- else {
- this.messager.printMessage(Diagnostic.Kind.ERROR, "Action Data Extension: [" + extension + "] format is not valid");
- }
- }
- jsonData.add(DataHelper.EXTENSIONS, jsonExtensions);
- }
- break;
-
- case GenericHelper.TP_TYPE_TEXT:
- if (data.isColor()) {
- jsonData.addProperty(DataHelper.TYPE, GenericHelper.TP_TYPE_COLOR);
- if (!data.defaultValue().isEmpty()) {
- if (!data.defaultValue().matches(DataHelper.COLOR_FORMAT)) {
- this.messager.printMessage(Diagnostic.Kind.ERROR, "Action Data Color Default value: [" + data.defaultValue() + "] format is not valid");
- }
- }
- }
- break;
-
- case GenericHelper.TP_TYPE_NUMBER:
- try {
- double defaultValue = jsonData.get(DataHelper.DEFAULT).getAsDouble();
- if (defaultValue < data.minValue() || defaultValue > data.maxValue()) {
- throw new GenericHelper.TPTypeException.Builder(className).defaultNotInRange().build();
- }
- }
- catch (NumberFormatException numberFormatException) {
- throw new GenericHelper.TPTypeException.Builder(className).defaultInvalid(data.defaultValue()).build();
- }
- jsonData.addProperty(DataHelper.ALLOW_DECIMALS, GenericHelper.getTouchPortalTypeNumberAllowDecimals(dataElement.asType().toString()));
- if (data.minValue() > Double.NEGATIVE_INFINITY) {
- jsonData.addProperty(DataHelper.MIN_VALUE, data.minValue());
- }
- if (data.maxValue() < Double.POSITIVE_INFINITY) {
- jsonData.addProperty(DataHelper.MAX_VALUE, data.maxValue());
- }
- break;
- }
- jsonData.addProperty(DataHelper.ID, dataId.get());
- if (!connector.format().isEmpty()) {
- // Replace wildcards
- String rawFormat = jsonConnector.get(ConnectorHelper.FORMAT).getAsString();
- jsonConnector.addProperty(ConnectorHelper.FORMAT, rawFormat.replace("{$" + (data.id().isEmpty() ? dataElement.getSimpleName().toString() : data.id()) + "$}", "{$" + dataId.get() + "$}"));
- }
-
- return Pair.create(jsonData, connectorDataTypeSpecBuilder);
- }
-
- /**
- * Generates a TypeSpec.Builder with Constants for the {@link Plugin}
- *
- * @param pluginElement Element
- * @param plugin {@link Plugin}
- * @return TypeSpec.Builder pluginTypeSpecBuilder
- */
- private TypeSpec.Builder createPluginTypeSpecBuilder(Element pluginElement, Plugin plugin) {
- String simpleClassName = pluginElement.getSimpleName().toString() + "Constants";
-
- TypeSpec.Builder pluginTypeSpecBuilder = TypeSpec.classBuilder(TouchPortalPluginAnnotationProcessor.capitalize(simpleClassName));
- pluginTypeSpecBuilder.addModifiers(Modifier.PUBLIC);
-
- pluginTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("id", PluginHelper.getPluginId(pluginElement)));
- pluginTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("name", plugin.name()));
- pluginTypeSpecBuilder.addField(this.getStaticFinalLongFieldSpec("version", plugin.version()));
-
- return pluginTypeSpecBuilder;
- }
-
- /**
- * Generates a TypeSpec.Builder with Constants for the {@link Category}
- *
- * @param pluginElement Element
- * @param categoryElement Element
- * @param category {@link Category}
- * @return TypeSpec.Builder pluginTypeSpecBuilder
- */
- private TypeSpec.Builder createCategoryTypeSpecBuilder(Element pluginElement, Element categoryElement, Category category) {
- String simpleClassName = category.id().isEmpty() ? categoryElement.getSimpleName().toString() : category.id();
-
- TypeSpec.Builder categoryTypeSpecBuilder = TypeSpec.classBuilder(TouchPortalPluginAnnotationProcessor.capitalize(simpleClassName)).addModifiers(Modifier.PUBLIC, Modifier.STATIC);
- categoryTypeSpecBuilder.addModifiers(Modifier.PUBLIC);
-
- categoryTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("id", CategoryHelper.getCategoryId(pluginElement, categoryElement, category)));
- categoryTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("name", category.name()));
- categoryTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("image_path", category.imagePath()));
-
- return categoryTypeSpecBuilder;
- }
-
- /**
- * Generates a TypeSpec.Builder with Constants for the {@link Action}
- *
- * @param pluginElement Element
- * @param categoryElement Element
- * @param category {@link Category}
- * @param actionElement Element
- * @param action {@link Action}
- * @return TypeSpec.Builder actionTypeSpecBuilder
- */
- private TypeSpec.Builder createActionTypeSpecBuilder(Element pluginElement, Element categoryElement, Category category, Element actionElement, Action action) {
- String simpleClassName = action.id().isEmpty() ? actionElement.getSimpleName().toString() : action.id();
-
- TypeSpec.Builder actionTypeSpecBuilder = TypeSpec.classBuilder(TouchPortalPluginAnnotationProcessor.capitalize(simpleClassName)).addModifiers(Modifier.PUBLIC, Modifier.STATIC);
- actionTypeSpecBuilder.addModifiers(Modifier.PUBLIC);
-
- actionTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("id", ActionHelper.getActionId(pluginElement, categoryElement, category, actionElement, action)));
- actionTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("name", ActionHelper.getActionName(actionElement, action)));
- actionTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("prefix", action.prefix()));
- actionTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("description", action.description()));
- actionTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("type", action.type()));
- actionTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("format", action.format()));
- actionTypeSpecBuilder.addField(this.getStaticFinalBooleanFieldSpec("has_hold_functionality", action.hasHoldFunctionality()));
-
- return actionTypeSpecBuilder;
- }
-
- /**
- * Generates a TypeSpec.Builder with Constants for the {@link Action}
- *
- * @param pluginElement Element
- * @param categoryElement Element
- * @param category {@link Category}
- * @param connectorElement Element
- * @param connector {@link Action}
- * @return TypeSpec.Builder actionTypeSpecBuilder
- */
- private TypeSpec.Builder createConnectorTypeSpecBuilder(Element pluginElement, Element categoryElement, Category category, Element connectorElement, Connector connector) {
- String simpleClassName = connector.id().isEmpty() ? connectorElement.getSimpleName().toString() : connector.id();
-
- TypeSpec.Builder actionTypeSpecBuilder = TypeSpec.classBuilder(TouchPortalPluginAnnotationProcessor.capitalize(simpleClassName)).addModifiers(Modifier.PUBLIC, Modifier.STATIC);
- actionTypeSpecBuilder.addModifiers(Modifier.PUBLIC);
-
- actionTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("id", ConnectorHelper.getConnectorId(pluginElement, categoryElement, category, connectorElement, connector)));
- actionTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("name", ConnectorHelper.getConnectorName(connectorElement, connector)));
- actionTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("format", connector.format()));
-
- return actionTypeSpecBuilder;
- }
-
- /**
- * Generates a TypeSpec.Builder with Constants for the {@link Data} for an {@link Action}
- *
- * @param pluginElement Element
- * @param categoryElement Element
- * @param category {@link Category}
- * @param actionElement Element
- * @param action {@link Action}
- * @param dataElement Element
- * @param data {@link Data}
- * @return TypeSpec.Builder dataTypeSpecBuilder
- */
- private TypeSpec.Builder createActionDataTypeSpecBuilder(Element pluginElement, Element categoryElement, Category category, Element actionElement, Action action, Element dataElement, Data data) {
- String simpleClassName = data.id().isEmpty() ? dataElement.getSimpleName().toString() : data.id();
-
- TypeSpec.Builder actionDataTypeSpecBuilder = TypeSpec.classBuilder(TouchPortalPluginAnnotationProcessor.capitalize(simpleClassName)).addModifiers(Modifier.PUBLIC, Modifier.STATIC);
- actionDataTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("id", DataHelper.getActionDataId(pluginElement, categoryElement, category, actionElement, action, dataElement, data)));
- actionDataTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("label", DataHelper.getDataLabel(dataElement, data)));
- actionDataTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("default_value", data.defaultValue()));
- actionDataTypeSpecBuilder.addField(this.getStaticFinalStringArrayFieldSpec("value_choices", data.valueChoices()));
- actionDataTypeSpecBuilder.addField(this.getStaticFinalStringArrayFieldSpec("extensions", data.extensions()));
- actionDataTypeSpecBuilder.addField(this.getStaticFinalBooleanFieldSpec("is_directory", data.isDirectory()));
- actionDataTypeSpecBuilder.addField(this.getStaticFinalBooleanFieldSpec("is_color", data.isColor()));
- if (data.minValue() > Double.NEGATIVE_INFINITY) {
- actionDataTypeSpecBuilder.addField(this.getStaticFinalDoubleFieldSpec("min_value", data.minValue()));
- }
- if (data.maxValue() < Double.POSITIVE_INFINITY) {
- actionDataTypeSpecBuilder.addField(this.getStaticFinalDoubleFieldSpec("max_value", data.maxValue()));
- }
-
- return actionDataTypeSpecBuilder;
- }
-
- /**
- * Generates a TypeSpec.Builder with Constants for the {@link Data} for a {@link Connector}
- *
- * @param pluginElement Element
- * @param categoryElement Element
- * @param category {@link Category}
- * @param connectorElement Element
- * @param connector {@link Connector}
- * @param dataElement Element
- * @param data {@link Data}
- * @return TypeSpec.Builder dataTypeSpecBuilder
- */
- private TypeSpec.Builder createConnectorDataTypeSpecBuilder(Element pluginElement, Element categoryElement, Category category, Element connectorElement, Connector connector, Element dataElement, Data data) {
- String simpleClassName = data.id().isEmpty() ? dataElement.getSimpleName().toString() : data.id();
-
- TypeSpec.Builder connectorDataTypeSpecBuilder = TypeSpec.classBuilder(TouchPortalPluginAnnotationProcessor.capitalize(simpleClassName)).addModifiers(Modifier.PUBLIC, Modifier.STATIC);
- connectorDataTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("id", DataHelper.getConnectorDataId(pluginElement, categoryElement, category, connectorElement, connector, dataElement, data)));
- connectorDataTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("label", DataHelper.getDataLabel(dataElement, data)));
- connectorDataTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("default_value", data.defaultValue()));
- connectorDataTypeSpecBuilder.addField(this.getStaticFinalStringArrayFieldSpec("value_choices", data.valueChoices()));
- connectorDataTypeSpecBuilder.addField(this.getStaticFinalStringArrayFieldSpec("extensions", data.extensions()));
- connectorDataTypeSpecBuilder.addField(this.getStaticFinalBooleanFieldSpec("is_directory", data.isDirectory()));
- connectorDataTypeSpecBuilder.addField(this.getStaticFinalBooleanFieldSpec("is_color", data.isColor()));
- if (data.minValue() > Double.NEGATIVE_INFINITY) {
- connectorDataTypeSpecBuilder.addField(this.getStaticFinalDoubleFieldSpec("min_value", data.minValue()));
- }
- if (data.maxValue() < Double.POSITIVE_INFINITY) {
- connectorDataTypeSpecBuilder.addField(this.getStaticFinalDoubleFieldSpec("max_value", data.maxValue()));
- }
-
- return connectorDataTypeSpecBuilder;
- }
-
- /**
- * Generates a TypeSpec.Builder with Constants for the {@link Setting}
- *
- * @param settingElement Element
- * @param setting {@link Setting}
- * @return TypeSpec.Builder stateTypeSpecBuilder
- */
- private TypeSpec.Builder createSettingTypeSpecBuilder(Element settingElement, Setting setting) {
- String simpleClassName = settingElement.getSimpleName().toString();
-
- TypeSpec.Builder stateTypeSpecBuilder = TypeSpec.classBuilder(TouchPortalPluginAnnotationProcessor.capitalize(simpleClassName)).addModifiers(Modifier.PUBLIC, Modifier.STATIC);
- stateTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("name", SettingHelper.getSettingName(settingElement, setting)));
- stateTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("default", setting.defaultValue()));
- stateTypeSpecBuilder.addField(this.getStaticFinalDoubleFieldSpec("max_length", setting.maxLength()));
- stateTypeSpecBuilder.addField(this.getStaticFinalBooleanFieldSpec("is_password", setting.isPassword()));
- if (setting.minValue() > Double.NEGATIVE_INFINITY) {
- stateTypeSpecBuilder.addField(this.getStaticFinalDoubleFieldSpec("min_value", setting.minValue()));
- }
- if (setting.maxValue() < Double.POSITIVE_INFINITY) {
- stateTypeSpecBuilder.addField(this.getStaticFinalDoubleFieldSpec("max_value", setting.maxValue()));
- }
-
- return stateTypeSpecBuilder;
- }
-
- /**
- * Generates a TypeSpec.Builder with Constants for the {@link State}
- *
- * @param pluginElement Element
- * @param categoryElement Element
- * @param category {@link Category}
- * @param stateElement Element
- * @param state {@link State}
- * @return TypeSpec.Builder stateTypeSpecBuilder
- */
- private TypeSpec.Builder createStateTypeSpecBuilder(Element pluginElement, Element categoryElement, Category category, Element stateElement, State state) {
- String simpleClassName = state.id().isEmpty() ? stateElement.getSimpleName().toString() : state.id();
-
- TypeSpec.Builder stateTypeSpecBuilder = TypeSpec.classBuilder(TouchPortalPluginAnnotationProcessor.capitalize(simpleClassName)).addModifiers(Modifier.PUBLIC, Modifier.STATIC);
- stateTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("id", StateHelper.getStateId(pluginElement, categoryElement, category, stateElement, state)));
- stateTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("desc", StateHelper.getStateDesc(stateElement, state)));
- stateTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("default_value", state.defaultValue()));
- stateTypeSpecBuilder.addField(this.getStaticFinalStringArrayFieldSpec("value_choices", state.valueChoices()));
-
- return stateTypeSpecBuilder;
- }
-
- /**
- * Generates a TypeSpec.Builder with Constants for the {@link Event}
- *
- * @param pluginElement Element
- * @param categoryElement Element
- * @param category {@link Category}
- * @param eventElement Element
- * @param event {@link Event}
- * @return TypeSpec.Builder eventTypeSpecBuilder
- */
- private TypeSpec.Builder createEventTypeSpecBuilder(Element pluginElement, Element categoryElement, Category category, Element eventElement, Event event) {
- String simpleClassName = event.id().isEmpty() ? eventElement.getSimpleName().toString() : event.id();
-
- TypeSpec.Builder eventTypeSpecBuilder = TypeSpec.classBuilder(TouchPortalPluginAnnotationProcessor.capitalize(simpleClassName)).addModifiers(Modifier.PUBLIC, Modifier.STATIC);
- eventTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("id", EventHelper.getEventId(pluginElement, categoryElement, category, eventElement, event)));
- eventTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("name", EventHelper.getEventName(eventElement, event)));
- eventTypeSpecBuilder.addField(this.getStaticFinalStringFieldSpec("format", event.format()));
- eventTypeSpecBuilder.addField(this.getStaticFinalStringArrayFieldSpec("value_choices", event.valueChoices()));
-
- return eventTypeSpecBuilder;
- }
-
- /**
- * Internal Get a Static Final String Field initialised with value
- *
- * @param fieldName String
- * @param value String
- * @return FieldSpec fieldSpec
- */
- private FieldSpec getStaticFinalStringFieldSpec(String fieldName, String value) {
- return FieldSpec.builder(String.class, fieldName.toUpperCase()).addModifiers(Modifier.PUBLIC, Modifier.FINAL, Modifier.STATIC).initializer("$S", value).build();
- }
-
- /**
- * Internal Get a Static Final long Field initialised with value
- *
- * @param fieldName String
- * @param value long
- * @return FieldSpec fieldSpec
- */
- private FieldSpec getStaticFinalDoubleFieldSpec(String fieldName, double value) {
- return FieldSpec.builder(double.class, fieldName.toUpperCase()).addModifiers(Modifier.PUBLIC, Modifier.FINAL, Modifier.STATIC).initializer("$L", value).build();
- }
-
- /**
- * Internal Get a Static Final long Field initialised with value
- *
- * @param fieldName String
- * @param value long
- * @return FieldSpec fieldSpec
- */
- private FieldSpec getStaticFinalLongFieldSpec(String fieldName, long value) {
- return FieldSpec.builder(long.class, fieldName.toUpperCase()).addModifiers(Modifier.PUBLIC, Modifier.FINAL, Modifier.STATIC).initializer("$L", value).build();
- }
-
- /**
- * Internal Get a Static Final boolean Field initialised with value
- *
- * @param fieldName String
- * @param value boolean
- * @return FieldSpec fieldSpec
- */
- private FieldSpec getStaticFinalBooleanFieldSpec(String fieldName, boolean value) {
- return FieldSpec.builder(boolean.class, fieldName.toUpperCase()).addModifiers(Modifier.PUBLIC, Modifier.FINAL, Modifier.STATIC).initializer("$L", value).build();
- }
-
- /**
- * Internal Get a Static Final boolean Field initialised with value
- *
- * @param fieldName String
- * @param values String[]
- * @return FieldSpec fieldSpec
- */
- private FieldSpec getStaticFinalStringArrayFieldSpec(String fieldName, String[] values) {
- ArrayTypeName stringArray = ArrayTypeName.of(String.class);
- String literal = "{\"" + String.join("\",\"", values) + "\"}";
- return FieldSpec.builder(String[].class, fieldName.toUpperCase()).addModifiers(Modifier.PUBLIC, Modifier.FINAL, Modifier.STATIC).initializer("new $1T $2L", stringArray, literal).build();
- }
-}
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationsProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationsProcessor.java
new file mode 100644
index 0000000..d0a71f0
--- /dev/null
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationsProcessor.java
@@ -0,0 +1,620 @@
+/*
+ * Touch Portal Plugin SDK
+ *
+ * Copyright 2020 Christophe Carvalho Vilas-Boas
+ * christophe.carvalhovilasboas@gmail.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.christophecvb.touchportal.annotations.processor;
+
+import com.christophecvb.touchportal.annotations.*;
+import com.christophecvb.touchportal.annotations.processor.utils.Pair;
+import com.christophecvb.touchportal.annotations.processor.utils.SpecUtils;
+import com.christophecvb.touchportal.helpers.*;
+import com.google.auto.service.AutoService;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.TypeSpec;
+
+import javax.annotation.processing.*;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+import javax.tools.FileObject;
+import javax.tools.StandardLocation;
+import java.io.Writer;
+import java.util.LinkedHashSet;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Touch Portal Plugin Annotations Processor
+ */
+@AutoService(Processor.class)
+public class TouchPortalPluginAnnotationsProcessor extends AbstractProcessor {
+ private Filer filer;
+ private Messager messager;
+
+ public Messager getMessager() {
+ return this.messager;
+ }
+
+ @Override
+ public synchronized void init(ProcessingEnvironment processingEnv) {
+ super.init(processingEnv);
+ this.filer = processingEnv.getFiler();
+ this.messager = processingEnv.getMessager();
+ }
+
+ @Override
+ public Set getSupportedAnnotationTypes() {
+ Set annotations = new LinkedHashSet<>();
+ annotations.add(Plugin.class.getCanonicalName());
+ annotations.add(Setting.class.getCanonicalName());
+ annotations.add(Category.class.getCanonicalName());
+ annotations.add(Action.class.getCanonicalName());
+ annotations.add(Data.class.getCanonicalName());
+ annotations.add(State.class.getCanonicalName());
+ annotations.add(Event.class.getCanonicalName());
+ annotations.add(Connector.class.getCanonicalName());
+ return annotations;
+ }
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latestSupported();
+ }
+
+ @Override
+ public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ if (roundEnv.processingOver() || annotations.size() == 0) {
+ return false;
+ }
+ this.messager.printMessage(Diagnostic.Kind.NOTE, this.getClass().getSimpleName() + ".process");
+
+ try {
+ Set extends Element> plugins = roundEnv.getElementsAnnotatedWith(Plugin.class);
+ if (plugins.size() != 1) {
+ throw new TPAnnotationException.Builder(Plugin.class).count(plugins.size()).build();
+ }
+ for (Element pluginElement : plugins) {
+ Pair pluginPair = PluginProcessor.process(this, roundEnv, pluginElement);
+
+ String entryFileName = "resources/" + PluginHelper.ENTRY_TP;
+ FileObject actionFileObject = this.filer.createResource(StandardLocation.SOURCE_OUTPUT, "", entryFileName, pluginElement);
+ Writer writer = actionFileObject.openWriter();
+ writer.write(pluginPair.first.toString());
+ writer.flush();
+ writer.close();
+
+ TypeSpec pluginTypeSpec = pluginPair.second.build();
+ String packageName = ((PackageElement) pluginElement.getEnclosingElement()).getQualifiedName().toString();
+ JavaFile javaConstantsFile = JavaFile.builder(packageName, pluginTypeSpec).build();
+ javaConstantsFile.writeTo(this.filer);
+ }
+ }
+ catch (Exception exception) {
+ this.messager.printMessage(Diagnostic.Kind.ERROR, exception.getMessage());
+ }
+
+ return true;
+ }
+
+ /**
+ * Generates a JsonObject and a TypeSpec.Builder representing the {@link Action}
+ *
+ * @param roundEnv RoundEnvironment
+ * @param pluginElement Element
+ * @param plugin {@link Plugin}
+ * @param categoryElement Element
+ * @param category {@link Category}
+ * @param actionElement Element
+ * @return Pair actionPair
+ */
+ public Pair processAction(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element actionElement) throws Exception {
+ this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Action: " + actionElement.getSimpleName());
+ Action action = actionElement.getAnnotation(Action.class);
+
+ TypeSpec.Builder actionTypeSpecBuilder = SpecUtils.createActionTypeSpecBuilder(pluginElement, categoryElement, category, actionElement, action);
+
+ JsonObject jsonAction = new JsonObject();
+ jsonAction.addProperty(ActionHelper.ID, ActionHelper.getActionId(pluginElement, categoryElement, category, actionElement, action));
+ jsonAction.addProperty(ActionHelper.NAME, ActionHelper.getActionName(actionElement, action));
+ jsonAction.addProperty(ActionHelper.PREFIX, action.prefix());
+ jsonAction.addProperty(ActionHelper.TYPE, action.type());
+ if (!action.description().isEmpty()) {
+ jsonAction.addProperty(ActionHelper.DESCRIPTION, action.description());
+ }
+ if (!action.format().isEmpty()) {
+ jsonAction.addProperty(ActionHelper.FORMAT, action.format());
+ jsonAction.addProperty(ActionHelper.TRY_INLINE, true);
+ }
+ jsonAction.addProperty(ActionHelper.HAS_HOLD_FUNCTIONALITY, action.hasHoldFunctionality());
+
+ ActionTranslation[] actionTranslations = actionElement.getAnnotationsByType(ActionTranslation.class);
+ if (actionTranslations.length > 0) {
+ for (ActionTranslation actionTranslation : actionTranslations) {
+ String languageCode = actionTranslation.language().getCode();
+ if (!actionTranslation.name().isEmpty()) {
+ jsonAction.addProperty(ActionHelper.NAME + "_" + languageCode, actionTranslation.name());
+ }
+ if (!actionTranslation.prefix().isEmpty()) {
+ jsonAction.addProperty(ActionHelper.PREFIX + "_" + languageCode, actionTranslation.prefix());
+ }
+ if (!actionTranslation.description().isEmpty()) {
+ jsonAction.addProperty(ActionHelper.DESCRIPTION + "_" + languageCode, actionTranslation.description());
+ }
+ if (!actionTranslation.format().isEmpty()) {
+ jsonAction.addProperty(ActionHelper.FORMAT + "_" + languageCode, actionTranslation.format());
+ }
+ }
+ }
+
+ JsonArray jsonActionData = new JsonArray();
+ Set extends Element> dataElements = roundEnv.getElementsAnnotatedWith(Data.class);
+ for (Element dataElement : dataElements) {
+ Element enclosingElement = dataElement.getEnclosingElement();
+ if (actionElement.equals(enclosingElement)) {
+ Pair actionDataResult = this.processActionData(roundEnv, pluginElement, plugin, categoryElement, category, actionElement, action, jsonAction, dataElement);
+ jsonActionData.add(actionDataResult.first);
+ if (actionDataResult.second != null) {
+ actionTypeSpecBuilder.addType(actionDataResult.second.build());
+ }
+ }
+ }
+ if (jsonActionData.size() > 0) {
+ jsonAction.add(ActionHelper.DATA, jsonActionData);
+ }
+
+ return Pair.create(jsonAction, actionTypeSpecBuilder);
+ }
+
+ /**
+ * Generates a JsonObject and a TypeSpec.Builder representing the {@link Connector}
+ *
+ * @param roundEnv RoundEnvironment
+ * @param pluginElement Element
+ * @param plugin {@link Plugin}
+ * @param categoryElement Element
+ * @param category {@link Category}
+ * @param connectorElement Element
+ * @return Pair actionPair
+ */
+ public Pair processConnector(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element connectorElement) throws Exception {
+ this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Connector: " + connectorElement.getSimpleName());
+ Connector connector = connectorElement.getAnnotation(Connector.class);
+
+ TypeSpec.Builder connectorTypeSpecBuilder = SpecUtils.createConnectorTypeSpecBuilder(pluginElement, categoryElement, category, connectorElement, connector);
+
+ JsonObject jsonConnector = new JsonObject();
+ jsonConnector.addProperty(ConnectorHelper.ID, ConnectorHelper.getConnectorId(pluginElement, categoryElement, category, connectorElement, connector));
+ jsonConnector.addProperty(ConnectorHelper.NAME, ConnectorHelper.getConnectorName(connectorElement, connector));
+ jsonConnector.addProperty(ConnectorHelper.FORMAT, connector.format());
+
+ String classMethod = pluginElement.getSimpleName() + "." + connectorElement.getSimpleName();
+ boolean connectorValueFound = false;
+ Set extends Element> connectorValueElements = roundEnv.getElementsAnnotatedWith(ConnectorValue.class);
+ for (Element connectorValueElement : connectorValueElements) {
+ Element enclosingElement = connectorValueElement.getEnclosingElement();
+ if (connectorElement.equals(enclosingElement)) {
+ String classMethodParameter = classMethod + "(" + connectorValueElement.getSimpleName() + ")";
+ String desiredType = GenericHelper.getTouchPortalType(classMethodParameter, connectorValueElement);
+ if (!desiredType.equals(GenericHelper.TP_TYPE_NUMBER)) {
+ throw new GenericHelper.TPTypeException.Builder(classMethodParameter).typeUnsupported(desiredType).forAnnotation(GenericHelper.TPTypeException.ForAnnotation.CONNECTOR_VALUE).build();
+ }
+ connectorValueFound = true;
+ break;
+ }
+ }
+ if (!connectorValueFound) {
+ throw new TPAnnotationException.Builder(ConnectorValue.class).isMissing(true).forElement(connectorElement).build();
+ }
+
+ JsonArray jsonConnectorData = new JsonArray();
+ Set extends Element> dataElements = roundEnv.getElementsAnnotatedWith(Data.class);
+ for (Element dataElement : dataElements) {
+ Element enclosingElement = dataElement.getEnclosingElement();
+ if (connectorElement.equals(enclosingElement)) {
+ Pair connectorDataResult = this.processConnectorData(roundEnv, pluginElement, plugin, categoryElement, category, connectorElement, connector, jsonConnector, dataElement);
+ jsonConnectorData.add(connectorDataResult.first);
+ if (connectorDataResult.second != null) {
+ connectorTypeSpecBuilder.addType(connectorDataResult.second.build());
+ }
+ }
+ }
+ if (jsonConnectorData.size() > 0) {
+ jsonConnector.add(ConnectorHelper.DATA, jsonConnectorData);
+ }
+
+ return Pair.create(jsonConnector, connectorTypeSpecBuilder);
+ }
+
+ /**
+ * Generates a JsonObject and a TypeSpec.Builder representing the {@link State}
+ *
+ * @param roundEnv RoundEnvironment
+ * @param pluginElement Element
+ * @param plugin {@link Plugin}
+ * @param categoryElement Element
+ * @param category {@link Category}
+ * @param stateElement Element
+ * @return Pair statePair
+ * @throws GenericHelper.TPTypeException If a used type is not Supported
+ */
+ public Pair processState(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element stateElement) throws Exception {
+ this.messager.printMessage(Diagnostic.Kind.NOTE, "Process State: " + stateElement.getSimpleName());
+ State state = stateElement.getAnnotation(State.class);
+
+ TypeSpec.Builder stateTypeSpecBuilder = SpecUtils.createStateTypeSpecBuilder(pluginElement, categoryElement, category, stateElement, state);
+
+ String className = stateElement.getEnclosingElement().getSimpleName() + "." + stateElement.getSimpleName();
+
+ JsonObject jsonState = new JsonObject();
+ jsonState.addProperty(StateHelper.ID, StateHelper.getStateId(pluginElement, categoryElement, category, stateElement, state));
+ String desiredTPType = GenericHelper.getTouchPortalType(className, stateElement);
+ jsonState.addProperty(StateHelper.TYPE, desiredTPType);
+ jsonState.addProperty(StateHelper.DESC, StateHelper.getStateDesc(stateElement, state));
+ jsonState.addProperty(StateHelper.DEFAULT, state.defaultValue());
+ if (desiredTPType.equals(StateHelper.TYPE_CHOICE)) {
+ JsonArray stateValueChoices = new JsonArray();
+ for (String valueChoice : state.valueChoices()) {
+ stateValueChoices.add(valueChoice);
+ }
+ jsonState.add(StateHelper.VALUE_CHOICES, stateValueChoices);
+ }
+ else if (!desiredTPType.equals(StateHelper.TYPE_TEXT)) {
+ throw new GenericHelper.TPTypeException.Builder(className).typeUnsupported(desiredTPType).forAnnotation(GenericHelper.TPTypeException.ForAnnotation.STATE).build();
+ }
+
+ Event event = stateElement.getAnnotation(Event.class);
+ if (event != null && !desiredTPType.equals(StateHelper.TYPE_TEXT)) {
+ throw new TPAnnotationException.Builder(State.class).typeFor(desiredTPType, className, "the field is also Annotated with Event. Only the type " + StateHelper.TYPE_TEXT + " is supported for a State that has an Event Annotation.").build();
+ }
+
+ return Pair.create(jsonState, stateTypeSpecBuilder);
+ }
+
+ /**
+ * Generates a JsonObject and a TypeSpec.Builder representing the {@link Event}
+ *
+ * @param roundEnv RoundEnvironment
+ * @param pluginElement Element
+ * @param plugin {@link Plugin}
+ * @param categoryElement Element
+ * @param category {@link Category}
+ * @param eventElement Element
+ * @return Pair eventPair
+ * @throws GenericHelper.TPTypeException If any used type is not Supported
+ */
+ public Pair processEvent(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element eventElement) throws Exception {
+ this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Event: " + eventElement.getSimpleName());
+ State state = eventElement.getAnnotation(State.class);
+ Event event = eventElement.getAnnotation(Event.class);
+
+ String reference = eventElement.getEnclosingElement().getSimpleName() + "." + eventElement.getSimpleName();
+
+ if (state == null) {
+ throw new TPAnnotationException.Builder(State.class).isMissing(true).forElement(eventElement).build();
+ }
+
+ TypeSpec.Builder eventTypeSpecBuilder = SpecUtils.createEventTypeSpecBuilder(pluginElement, categoryElement, category, eventElement, event);
+
+ JsonObject jsonEvent = new JsonObject();
+ jsonEvent.addProperty(EventHelper.ID, EventHelper.getEventId(pluginElement, categoryElement, category, eventElement, event));
+ jsonEvent.addProperty(EventHelper.TYPE, EventHelper.TYPE_COMMUNICATE);
+ jsonEvent.addProperty(EventHelper.NAME, EventHelper.getEventName(eventElement, event));
+ jsonEvent.addProperty(EventHelper.FORMAT, event.format());
+ String desiredTPType = GenericHelper.getTouchPortalType(reference, eventElement);
+ if (desiredTPType.equals(StateHelper.TYPE_TEXT)) {
+ jsonEvent.addProperty(EventHelper.VALUE_TYPE, EventHelper.VALUE_TYPE_CHOICE);
+ JsonArray eventValueChoices = new JsonArray();
+ for (String valueChoice : event.valueChoices()) {
+ eventValueChoices.add(valueChoice);
+ }
+ jsonEvent.add(EventHelper.VALUE_CHOICES, eventValueChoices);
+ jsonEvent.addProperty(EventHelper.VALUE_STATE_ID, StateHelper.getStateId(pluginElement, categoryElement, category, eventElement, state));
+ }
+ else {
+ throw new GenericHelper.TPTypeException.Builder(reference).typeUnsupported(desiredTPType).forAnnotation(GenericHelper.TPTypeException.ForAnnotation.EVENT).build();
+ }
+
+ return Pair.create(jsonEvent, eventTypeSpecBuilder);
+ }
+
+ /**
+ * Generates a JsonObject and a TypeSpec.Builder representing the {@link Data} for an {@link Action}
+ *
+ * @param roundEnv RoundEnvironment
+ * @param pluginElement Element
+ * @param plugin {@link Plugin}
+ * @param categoryElement Element
+ * @param category {@link Category}
+ * @param actionElement Element
+ * @param action {@link Action}
+ * @param jsonAction JsonObject
+ * @param dataElement Element
+ * @return Pair dataPair
+ */
+ private Pair processActionData(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element actionElement, Action action, JsonObject jsonAction, Element dataElement) throws Exception {
+ this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Action Data: " + dataElement.getSimpleName());
+ Data data = dataElement.getAnnotation(Data.class);
+
+ TypeSpec.Builder actionDataTypeSpecBuilder = SpecUtils.createActionDataTypeSpecBuilder(pluginElement, categoryElement, category, actionElement, action, dataElement, data);
+
+ Element method = dataElement.getEnclosingElement();
+ String className = method.getEnclosingElement().getSimpleName() + "." + method.getSimpleName() + "(" + dataElement.getSimpleName() + ")";
+
+ JsonObject jsonData = new JsonObject();
+ String desiredTPType = GenericHelper.getTouchPortalType(className, dataElement);
+ jsonData.addProperty(DataHelper.TYPE, desiredTPType);
+ jsonData.addProperty(DataHelper.LABEL, DataHelper.getDataLabel(dataElement, data));
+ // Default Value
+ switch (desiredTPType) {
+ case GenericHelper.TP_TYPE_NUMBER:
+ double defaultValue = 0;
+ try {
+ defaultValue = Double.parseDouble(data.defaultValue());
+ }
+ catch (NumberFormatException ignored) {}
+ jsonData.addProperty(DataHelper.DEFAULT, defaultValue);
+ break;
+
+ case GenericHelper.TP_TYPE_SWITCH:
+ jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue().equals("true"));
+ break;
+
+ default:
+ jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue());
+ break;
+ }
+ AtomicReference dataId = new AtomicReference<>(DataHelper.getActionDataId(pluginElement, categoryElement, category, actionElement, action, dataElement, data));
+ // Specific properties
+ switch (desiredTPType) {
+ case GenericHelper.TP_TYPE_CHOICE:
+ JsonArray dataValueChoices = new JsonArray();
+ if (!data.stateId().isEmpty()) {
+ Optional extends Element> optionalStateElement = roundEnv.getElementsAnnotatedWith(State.class).stream().filter(element -> {
+ State state = element.getAnnotation(State.class);
+ String shortStateId = !state.id().isEmpty() ? state.id() : element.getSimpleName().toString();
+ return shortStateId.equals(data.stateId());
+ }).findFirst();
+ if (optionalStateElement.isPresent()) {
+ actionDataTypeSpecBuilder = null;
+
+ Element stateElement = optionalStateElement.get();
+ State state = stateElement.getAnnotation(State.class);
+ dataId.set(StateHelper.getStateId(pluginElement, categoryElement, category, stateElement, state));
+ for (String valueChoice : state.valueChoices()) {
+ dataValueChoices.add(valueChoice);
+ }
+ jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue().isEmpty() ? state.defaultValue() : data.defaultValue());
+ }
+ else {
+ for (String valueChoice : data.valueChoices()) {
+ dataValueChoices.add(valueChoice);
+ }
+ }
+ }
+ else {
+ for (String valueChoice : data.valueChoices()) {
+ dataValueChoices.add(valueChoice);
+ }
+ }
+ jsonData.add(DataHelper.VALUE_CHOICES, dataValueChoices);
+ break;
+
+ case GenericHelper.TP_TYPE_FILE:
+ if (data.isDirectory()) {
+ jsonData.addProperty(DataHelper.TYPE, GenericHelper.TP_TYPE_DIRECTORY);
+ }
+ else {
+ JsonArray jsonExtensions = new JsonArray();
+ for (String extension : data.extensions()) {
+ if (extension.matches(DataHelper.EXTENSION_FORMAT)) {
+ jsonExtensions.add(extension);
+ }
+ else {
+ this.messager.printMessage(Diagnostic.Kind.ERROR, "Action Data Extension: [" + extension + "] format is not valid");
+ }
+ }
+ jsonData.add(DataHelper.EXTENSIONS, jsonExtensions);
+ }
+ break;
+
+ case GenericHelper.TP_TYPE_TEXT:
+ if (data.isColor()) {
+ jsonData.addProperty(DataHelper.TYPE, GenericHelper.TP_TYPE_COLOR);
+ if (!data.defaultValue().isEmpty()) {
+ if (!data.defaultValue().matches(DataHelper.COLOR_FORMAT)) {
+ this.messager.printMessage(Diagnostic.Kind.ERROR, "Action Data Color Default value: [" + data.defaultValue() + "] format is not valid");
+ }
+ }
+ }
+ break;
+
+ case GenericHelper.TP_TYPE_NUMBER:
+ try {
+ double defaultValue = jsonData.get(DataHelper.DEFAULT).getAsDouble();
+ if (defaultValue < data.minValue() || defaultValue > data.maxValue()) {
+ throw new GenericHelper.TPTypeException.Builder(className).defaultNotInRange().build();
+ }
+ }
+ catch (NumberFormatException numberFormatException) {
+ throw new GenericHelper.TPTypeException.Builder(className).defaultInvalid(data.defaultValue()).build();
+ }
+ jsonData.addProperty(DataHelper.ALLOW_DECIMALS, GenericHelper.getTouchPortalTypeNumberAllowDecimals(dataElement.asType().toString()));
+ if (data.minValue() > Double.NEGATIVE_INFINITY) {
+ jsonData.addProperty(DataHelper.MIN_VALUE, data.minValue());
+ }
+ if (data.maxValue() < Double.POSITIVE_INFINITY) {
+ jsonData.addProperty(DataHelper.MAX_VALUE, data.maxValue());
+ }
+ break;
+ }
+ jsonData.addProperty(DataHelper.ID, dataId.get());
+ if (!action.format().isEmpty()) {
+ // Replace wildcards
+ String rawFormat = jsonAction.get(ActionHelper.FORMAT).getAsString();
+ jsonAction.addProperty(ActionHelper.FORMAT, rawFormat.replace("{$" + (data.id().isEmpty() ? dataElement.getSimpleName().toString() : data.id()) + "$}", "{$" + dataId.get() + "$}"));
+ }
+
+ return Pair.create(jsonData, actionDataTypeSpecBuilder);
+ }
+
+ /**
+ * Generates a JsonObject and a TypeSpec.Builder representing the {@link Data} for a {@link Connector}
+ *
+ * @param roundEnv RoundEnvironment
+ * @param pluginElement Element
+ * @param plugin {@link Plugin}
+ * @param categoryElement Element
+ * @param category {@link Category}
+ * @param connectorElement Element
+ * @param connector {@link Connector}
+ * @param jsonConnector JsonObject
+ * @param dataElement Element
+ * @return Pair dataPair
+ */
+ private Pair processConnectorData(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element connectorElement, Connector connector, JsonObject jsonConnector, Element dataElement) throws Exception {
+ this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Connector Data: " + dataElement.getSimpleName());
+ Data data = dataElement.getAnnotation(Data.class);
+
+ TypeSpec.Builder connectorDataTypeSpecBuilder = SpecUtils.createConnectorDataTypeSpecBuilder(pluginElement, categoryElement, category, connectorElement, connector, dataElement, data);
+
+ Element method = dataElement.getEnclosingElement();
+ String className = method.getEnclosingElement().getSimpleName() + "." + method.getSimpleName() + "(" + dataElement.getSimpleName() + ")";
+
+ JsonObject jsonData = new JsonObject();
+ String desiredTPType = GenericHelper.getTouchPortalType(className, dataElement);
+ jsonData.addProperty(DataHelper.TYPE, desiredTPType);
+ jsonData.addProperty(DataHelper.LABEL, DataHelper.getDataLabel(dataElement, data));
+ // Default Value
+ switch (desiredTPType) {
+ case GenericHelper.TP_TYPE_NUMBER:
+ double defaultValue = 0;
+ try {
+ defaultValue = Double.parseDouble(data.defaultValue());
+ }
+ catch (NumberFormatException ignored) {}
+ jsonData.addProperty(DataHelper.DEFAULT, defaultValue);
+ break;
+
+ case GenericHelper.TP_TYPE_SWITCH:
+ jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue().equals("true"));
+ break;
+
+ default:
+ jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue());
+ break;
+ }
+ AtomicReference dataId = new AtomicReference<>(DataHelper.getConnectorDataId(pluginElement, categoryElement, category, connectorElement, connector, dataElement, data));
+ // Specific properties
+ switch (desiredTPType) {
+ case GenericHelper.TP_TYPE_CHOICE:
+ JsonArray dataValueChoices = new JsonArray();
+ if (!data.stateId().isEmpty()) {
+ Optional extends Element> optionalStateElement = roundEnv.getElementsAnnotatedWith(State.class).stream().filter(element -> {
+ State state = element.getAnnotation(State.class);
+ String shortStateId = !state.id().isEmpty() ? state.id() : element.getSimpleName().toString();
+ return shortStateId.equals(data.stateId());
+ }).findFirst();
+ if (optionalStateElement.isPresent()) {
+ connectorDataTypeSpecBuilder = null;
+
+ Element stateElement = optionalStateElement.get();
+ State state = stateElement.getAnnotation(State.class);
+ dataId.set(StateHelper.getStateId(pluginElement, categoryElement, category, stateElement, state));
+ for (String valueChoice : state.valueChoices()) {
+ dataValueChoices.add(valueChoice);
+ }
+ jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue().isEmpty() ? state.defaultValue() : data.defaultValue());
+ }
+ else {
+ for (String valueChoice : data.valueChoices()) {
+ dataValueChoices.add(valueChoice);
+ }
+ }
+ }
+ else {
+ for (String valueChoice : data.valueChoices()) {
+ dataValueChoices.add(valueChoice);
+ }
+ }
+ jsonData.add(DataHelper.VALUE_CHOICES, dataValueChoices);
+ break;
+
+ case GenericHelper.TP_TYPE_FILE:
+ if (data.isDirectory()) {
+ jsonData.addProperty(DataHelper.TYPE, GenericHelper.TP_TYPE_DIRECTORY);
+ }
+ else {
+ JsonArray jsonExtensions = new JsonArray();
+ for (String extension : data.extensions()) {
+ if (extension.matches(DataHelper.EXTENSION_FORMAT)) {
+ jsonExtensions.add(extension);
+ }
+ else {
+ this.messager.printMessage(Diagnostic.Kind.ERROR, "Action Data Extension: [" + extension + "] format is not valid");
+ }
+ }
+ jsonData.add(DataHelper.EXTENSIONS, jsonExtensions);
+ }
+ break;
+
+ case GenericHelper.TP_TYPE_TEXT:
+ if (data.isColor()) {
+ jsonData.addProperty(DataHelper.TYPE, GenericHelper.TP_TYPE_COLOR);
+ if (!data.defaultValue().isEmpty()) {
+ if (!data.defaultValue().matches(DataHelper.COLOR_FORMAT)) {
+ this.messager.printMessage(Diagnostic.Kind.ERROR, "Action Data Color Default value: [" + data.defaultValue() + "] format is not valid");
+ }
+ }
+ }
+ break;
+
+ case GenericHelper.TP_TYPE_NUMBER:
+ try {
+ double defaultValue = jsonData.get(DataHelper.DEFAULT).getAsDouble();
+ if (defaultValue < data.minValue() || defaultValue > data.maxValue()) {
+ throw new GenericHelper.TPTypeException.Builder(className).defaultNotInRange().build();
+ }
+ }
+ catch (NumberFormatException numberFormatException) {
+ throw new GenericHelper.TPTypeException.Builder(className).defaultInvalid(data.defaultValue()).build();
+ }
+ jsonData.addProperty(DataHelper.ALLOW_DECIMALS, GenericHelper.getTouchPortalTypeNumberAllowDecimals(dataElement.asType().toString()));
+ if (data.minValue() > Double.NEGATIVE_INFINITY) {
+ jsonData.addProperty(DataHelper.MIN_VALUE, data.minValue());
+ }
+ if (data.maxValue() < Double.POSITIVE_INFINITY) {
+ jsonData.addProperty(DataHelper.MAX_VALUE, data.maxValue());
+ }
+ break;
+ }
+ jsonData.addProperty(DataHelper.ID, dataId.get());
+ if (!connector.format().isEmpty()) {
+ // Replace wildcards
+ String rawFormat = jsonConnector.get(ConnectorHelper.FORMAT).getAsString();
+ jsonConnector.addProperty(ConnectorHelper.FORMAT, rawFormat.replace("{$" + (data.id().isEmpty() ? dataElement.getSimpleName().toString() : data.id()) + "$}", "{$" + dataId.get() + "$}"));
+ }
+
+ return Pair.create(jsonData, connectorDataTypeSpecBuilder);
+ }
+}
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/utils/SpecUtils.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/utils/SpecUtils.java
new file mode 100644
index 0000000..c681c16
--- /dev/null
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/utils/SpecUtils.java
@@ -0,0 +1,303 @@
+package com.christophecvb.touchportal.annotations.processor.utils;
+
+import com.christophecvb.touchportal.annotations.*;
+import com.christophecvb.touchportal.helpers.*;
+import com.squareup.javapoet.ArrayTypeName;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.TypeSpec;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.Modifier;
+
+public class SpecUtils {
+ private static String capitalize(String str) {
+ if (str == null || str.isEmpty()) {
+ return str;
+ }
+
+ return str.substring(0, 1).toUpperCase() + str.substring(1);
+ }
+
+ /**
+ * Generates a TypeSpec.Builder with Constants for the {@link Plugin}
+ *
+ * @param pluginElement Element
+ * @param plugin {@link Plugin}
+ * @return TypeSpec.Builder pluginTypeSpecBuilder
+ */
+ public static TypeSpec.Builder createPluginTypeSpecBuilder(Element pluginElement, Plugin plugin) {
+ String simpleClassName = pluginElement.getSimpleName().toString() + "Constants";
+
+ TypeSpec.Builder pluginTypeSpecBuilder = TypeSpec.classBuilder(SpecUtils.capitalize(simpleClassName));
+ pluginTypeSpecBuilder.addModifiers(Modifier.PUBLIC);
+
+ pluginTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("id", PluginHelper.getPluginId(pluginElement)));
+ pluginTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("name", plugin.name()));
+ pluginTypeSpecBuilder.addField(SpecUtils.getStaticFinalLongFieldSpec("version", plugin.version()));
+
+ return pluginTypeSpecBuilder;
+ }
+
+ /**
+ * Generates a TypeSpec.Builder with Constants for the {@link Category}
+ *
+ * @param pluginElement Element
+ * @param categoryElement Element
+ * @param category {@link Category}
+ * @return TypeSpec.Builder pluginTypeSpecBuilder
+ */
+ public static TypeSpec.Builder createCategoryTypeSpecBuilder(Element pluginElement, Element categoryElement, Category category) {
+ String simpleClassName = category.id().isEmpty() ? categoryElement.getSimpleName().toString() : category.id();
+
+ TypeSpec.Builder categoryTypeSpecBuilder = TypeSpec.classBuilder(SpecUtils.capitalize(simpleClassName)).addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+ categoryTypeSpecBuilder.addModifiers(Modifier.PUBLIC);
+
+ categoryTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("id", CategoryHelper.getCategoryId(pluginElement, categoryElement, category)));
+ categoryTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("name", category.name()));
+ categoryTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("image_path", category.imagePath()));
+
+ return categoryTypeSpecBuilder;
+ }
+
+ /**
+ * Generates a TypeSpec.Builder with Constants for the {@link Action}
+ *
+ * @param pluginElement Element
+ * @param categoryElement Element
+ * @param category {@link Category}
+ * @param actionElement Element
+ * @param action {@link Action}
+ * @return TypeSpec.Builder actionTypeSpecBuilder
+ */
+ public static TypeSpec.Builder createActionTypeSpecBuilder(Element pluginElement, Element categoryElement, Category category, Element actionElement, Action action) {
+ String simpleClassName = action.id().isEmpty() ? actionElement.getSimpleName().toString() : action.id();
+
+ TypeSpec.Builder actionTypeSpecBuilder = TypeSpec.classBuilder(SpecUtils.capitalize(simpleClassName)).addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+ actionTypeSpecBuilder.addModifiers(Modifier.PUBLIC);
+
+ actionTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("id", ActionHelper.getActionId(pluginElement, categoryElement, category, actionElement, action)));
+ actionTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("name", ActionHelper.getActionName(actionElement, action)));
+ actionTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("prefix", action.prefix()));
+ actionTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("description", action.description()));
+ actionTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("type", action.type()));
+ actionTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("format", action.format()));
+ actionTypeSpecBuilder.addField(SpecUtils.getStaticFinalBooleanFieldSpec("has_hold_functionality", action.hasHoldFunctionality()));
+
+ return actionTypeSpecBuilder;
+ }
+
+ /**
+ * Generates a TypeSpec.Builder with Constants for the {@link Action}
+ *
+ * @param pluginElement Element
+ * @param categoryElement Element
+ * @param category {@link Category}
+ * @param connectorElement Element
+ * @param connector {@link Action}
+ * @return TypeSpec.Builder actionTypeSpecBuilder
+ */
+ public static TypeSpec.Builder createConnectorTypeSpecBuilder(Element pluginElement, Element categoryElement, Category category, Element connectorElement, Connector connector) {
+ String simpleClassName = connector.id().isEmpty() ? connectorElement.getSimpleName().toString() : connector.id();
+
+ TypeSpec.Builder actionTypeSpecBuilder = TypeSpec.classBuilder(SpecUtils.capitalize(simpleClassName)).addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+ actionTypeSpecBuilder.addModifiers(Modifier.PUBLIC);
+
+ actionTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("id", ConnectorHelper.getConnectorId(pluginElement, categoryElement, category, connectorElement, connector)));
+ actionTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("name", ConnectorHelper.getConnectorName(connectorElement, connector)));
+ actionTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("format", connector.format()));
+
+ return actionTypeSpecBuilder;
+ }
+
+ /**
+ * Generates a TypeSpec.Builder with Constants for the {@link Data} for an {@link Action}
+ *
+ * @param pluginElement Element
+ * @param categoryElement Element
+ * @param category {@link Category}
+ * @param actionElement Element
+ * @param action {@link Action}
+ * @param dataElement Element
+ * @param data {@link Data}
+ * @return TypeSpec.Builder dataTypeSpecBuilder
+ */
+ public static TypeSpec.Builder createActionDataTypeSpecBuilder(Element pluginElement, Element categoryElement, Category category, Element actionElement, Action action, Element dataElement, Data data) {
+ String simpleClassName = data.id().isEmpty() ? dataElement.getSimpleName().toString() : data.id();
+
+ TypeSpec.Builder actionDataTypeSpecBuilder = TypeSpec.classBuilder(SpecUtils.capitalize(simpleClassName)).addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+ actionDataTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("id", DataHelper.getActionDataId(pluginElement, categoryElement, category, actionElement, action, dataElement, data)));
+ actionDataTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("label", DataHelper.getDataLabel(dataElement, data)));
+ actionDataTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("default_value", data.defaultValue()));
+ actionDataTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringArrayFieldSpec("value_choices", data.valueChoices()));
+ actionDataTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringArrayFieldSpec("extensions", data.extensions()));
+ actionDataTypeSpecBuilder.addField(SpecUtils.getStaticFinalBooleanFieldSpec("is_directory", data.isDirectory()));
+ actionDataTypeSpecBuilder.addField(SpecUtils.getStaticFinalBooleanFieldSpec("is_color", data.isColor()));
+ if (data.minValue() > Double.NEGATIVE_INFINITY) {
+ actionDataTypeSpecBuilder.addField(SpecUtils.getStaticFinalDoubleFieldSpec("min_value", data.minValue()));
+ }
+ if (data.maxValue() < Double.POSITIVE_INFINITY) {
+ actionDataTypeSpecBuilder.addField(SpecUtils.getStaticFinalDoubleFieldSpec("max_value", data.maxValue()));
+ }
+
+ return actionDataTypeSpecBuilder;
+ }
+
+ /**
+ * Generates a TypeSpec.Builder with Constants for the {@link Data} for a {@link Connector}
+ *
+ * @param pluginElement Element
+ * @param categoryElement Element
+ * @param category {@link Category}
+ * @param connectorElement Element
+ * @param connector {@link Connector}
+ * @param dataElement Element
+ * @param data {@link Data}
+ * @return TypeSpec.Builder dataTypeSpecBuilder
+ */
+ public static TypeSpec.Builder createConnectorDataTypeSpecBuilder(Element pluginElement, Element categoryElement, Category category, Element connectorElement, Connector connector, Element dataElement, Data data) {
+ String simpleClassName = data.id().isEmpty() ? dataElement.getSimpleName().toString() : data.id();
+
+ TypeSpec.Builder connectorDataTypeSpecBuilder = TypeSpec.classBuilder(SpecUtils.capitalize(simpleClassName)).addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+ connectorDataTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("id", DataHelper.getConnectorDataId(pluginElement, categoryElement, category, connectorElement, connector, dataElement, data)));
+ connectorDataTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("label", DataHelper.getDataLabel(dataElement, data)));
+ connectorDataTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("default_value", data.defaultValue()));
+ connectorDataTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringArrayFieldSpec("value_choices", data.valueChoices()));
+ connectorDataTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringArrayFieldSpec("extensions", data.extensions()));
+ connectorDataTypeSpecBuilder.addField(SpecUtils.getStaticFinalBooleanFieldSpec("is_directory", data.isDirectory()));
+ connectorDataTypeSpecBuilder.addField(SpecUtils.getStaticFinalBooleanFieldSpec("is_color", data.isColor()));
+ if (data.minValue() > Double.NEGATIVE_INFINITY) {
+ connectorDataTypeSpecBuilder.addField(SpecUtils.getStaticFinalDoubleFieldSpec("min_value", data.minValue()));
+ }
+ if (data.maxValue() < Double.POSITIVE_INFINITY) {
+ connectorDataTypeSpecBuilder.addField(SpecUtils.getStaticFinalDoubleFieldSpec("max_value", data.maxValue()));
+ }
+
+ return connectorDataTypeSpecBuilder;
+ }
+
+ /**
+ * Generates a TypeSpec.Builder with Constants for the {@link Setting}
+ *
+ * @param settingElement Element
+ * @param setting {@link Setting}
+ * @return TypeSpec.Builder stateTypeSpecBuilder
+ */
+ public static TypeSpec.Builder createSettingTypeSpecBuilder(Element settingElement, Setting setting) {
+ String simpleClassName = settingElement.getSimpleName().toString();
+
+ TypeSpec.Builder stateTypeSpecBuilder = TypeSpec.classBuilder(SpecUtils.capitalize(simpleClassName)).addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+ stateTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("name", SettingHelper.getSettingName(settingElement, setting)));
+ stateTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("default", setting.defaultValue()));
+ stateTypeSpecBuilder.addField(SpecUtils.getStaticFinalDoubleFieldSpec("max_length", setting.maxLength()));
+ stateTypeSpecBuilder.addField(SpecUtils.getStaticFinalBooleanFieldSpec("is_password", setting.isPassword()));
+ if (setting.minValue() > Double.NEGATIVE_INFINITY) {
+ stateTypeSpecBuilder.addField(SpecUtils.getStaticFinalDoubleFieldSpec("min_value", setting.minValue()));
+ }
+ if (setting.maxValue() < Double.POSITIVE_INFINITY) {
+ stateTypeSpecBuilder.addField(SpecUtils.getStaticFinalDoubleFieldSpec("max_value", setting.maxValue()));
+ }
+
+ return stateTypeSpecBuilder;
+ }
+
+ /**
+ * Generates a TypeSpec.Builder with Constants for the {@link State}
+ *
+ * @param pluginElement Element
+ * @param categoryElement Element
+ * @param category {@link Category}
+ * @param stateElement Element
+ * @param state {@link State}
+ * @return TypeSpec.Builder stateTypeSpecBuilder
+ */
+ public static TypeSpec.Builder createStateTypeSpecBuilder(Element pluginElement, Element categoryElement, Category category, Element stateElement, State state) {
+ String simpleClassName = state.id().isEmpty() ? stateElement.getSimpleName().toString() : state.id();
+
+ TypeSpec.Builder stateTypeSpecBuilder = TypeSpec.classBuilder(SpecUtils.capitalize(simpleClassName)).addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+ stateTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("id", StateHelper.getStateId(pluginElement, categoryElement, category, stateElement, state)));
+ stateTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("desc", StateHelper.getStateDesc(stateElement, state)));
+ stateTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("default_value", state.defaultValue()));
+ stateTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringArrayFieldSpec("value_choices", state.valueChoices()));
+
+ return stateTypeSpecBuilder;
+ }
+
+ /**
+ * Generates a TypeSpec.Builder with Constants for the {@link Event}
+ *
+ * @param pluginElement Element
+ * @param categoryElement Element
+ * @param category {@link Category}
+ * @param eventElement Element
+ * @param event {@link Event}
+ * @return TypeSpec.Builder eventTypeSpecBuilder
+ */
+ public static TypeSpec.Builder createEventTypeSpecBuilder(Element pluginElement, Element categoryElement, Category category, Element eventElement, Event event) {
+ String simpleClassName = event.id().isEmpty() ? eventElement.getSimpleName().toString() : event.id();
+
+ TypeSpec.Builder eventTypeSpecBuilder = TypeSpec.classBuilder(SpecUtils.capitalize(simpleClassName)).addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+ eventTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("id", EventHelper.getEventId(pluginElement, categoryElement, category, eventElement, event)));
+ eventTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("name", EventHelper.getEventName(eventElement, event)));
+ eventTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("format", event.format()));
+ eventTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringArrayFieldSpec("value_choices", event.valueChoices()));
+
+ return eventTypeSpecBuilder;
+ }
+
+ /**
+ * Internal Get a Static Final String Field initialised with value
+ *
+ * @param fieldName String
+ * @param value String
+ * @return FieldSpec fieldSpec
+ */
+ public static FieldSpec getStaticFinalStringFieldSpec(String fieldName, String value) {
+ return FieldSpec.builder(String.class, fieldName.toUpperCase()).addModifiers(Modifier.PUBLIC, Modifier.FINAL, Modifier.STATIC).initializer("$S", value).build();
+ }
+
+ /**
+ * Internal Get a Static Final long Field initialised with value
+ *
+ * @param fieldName String
+ * @param value long
+ * @return FieldSpec fieldSpec
+ */
+ public static FieldSpec getStaticFinalDoubleFieldSpec(String fieldName, double value) {
+ return FieldSpec.builder(double.class, fieldName.toUpperCase()).addModifiers(Modifier.PUBLIC, Modifier.FINAL, Modifier.STATIC).initializer("$L", value).build();
+ }
+
+ /**
+ * Internal Get a Static Final long Field initialised with value
+ *
+ * @param fieldName String
+ * @param value long
+ * @return FieldSpec fieldSpec
+ */
+ public static FieldSpec getStaticFinalLongFieldSpec(String fieldName, long value) {
+ return FieldSpec.builder(long.class, fieldName.toUpperCase()).addModifiers(Modifier.PUBLIC, Modifier.FINAL, Modifier.STATIC).initializer("$L", value).build();
+ }
+
+ /**
+ * Internal Get a Static Final boolean Field initialised with value
+ *
+ * @param fieldName String
+ * @param value boolean
+ * @return FieldSpec fieldSpec
+ */
+ public static FieldSpec getStaticFinalBooleanFieldSpec(String fieldName, boolean value) {
+ return FieldSpec.builder(boolean.class, fieldName.toUpperCase()).addModifiers(Modifier.PUBLIC, Modifier.FINAL, Modifier.STATIC).initializer("$L", value).build();
+ }
+
+ /**
+ * Internal Get a Static Final boolean Field initialised with value
+ *
+ * @param fieldName String
+ * @param values String[]
+ * @return FieldSpec fieldSpec
+ */
+ public static FieldSpec getStaticFinalStringArrayFieldSpec(String fieldName, String[] values) {
+ ArrayTypeName stringArray = ArrayTypeName.of(String.class);
+ String literal = "{\"" + String.join("\",\"", values) + "\"}";
+ return FieldSpec.builder(String[].class, fieldName.toUpperCase()).addModifiers(Modifier.PUBLIC, Modifier.FINAL, Modifier.STATIC).initializer("new $1T $2L", stringArray, literal).build();
+ }
+}
diff --git a/AnnotationsProcessor/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/AnnotationsProcessor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
index 85ca834..ebd05a3 100644
--- a/AnnotationsProcessor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
+++ b/AnnotationsProcessor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
@@ -1 +1 @@
-com.christophecvb.touchportal.annotations.processor.TouchPortalPluginAnnotationProcessor
+com.christophecvb.touchportal.annotations.processor.TouchPortalPluginAnnotationsProcessor
diff --git a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
index e8819d7..66febb3 100644
--- a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
+++ b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
@@ -56,6 +56,10 @@ public class PluginHelper {
* Touch Portal Plugin System TP_PLUGIN_FOLDER
*/
public static final String TP_PLUGIN_FOLDER = "%TP_PLUGIN_FOLDER%";
+ /**
+ * Touch Portal Plugin System TP_JAVA_FILE
+ */
+ public static final String TP_JAVA = "%TP_JAVA_FILE%";
/**
* Touch Portal entry file
*/
diff --git a/Library/src/test/resources/TouchPortalPluginTest/plugin.config b/Library/src/test/resources/TouchPortalPluginTest/plugin.config
index 09a2603..10fc40b 100644
--- a/Library/src/test/resources/TouchPortalPluginTest/plugin.config
+++ b/Library/src/test/resources/TouchPortalPluginTest/plugin.config
@@ -1,4 +1,4 @@
#TouchPortalPluginTest
-#Mon May 23 10:54:55 CEST 2022
+#Sat Nov 26 23:11:43 CET 2022
samplekey=Sample Value
plugin.version=1
From ed082fa159f38fd64cbb8f6d823828feb7b3020d Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Sun, 27 Nov 2022 02:48:08 +0100
Subject: [PATCH 25/41] fix: JavaDoc
---
.../annotations/processor/CategoryProcessor.java | 2 +-
.../annotations/processor/PluginProcessor.java | 2 +-
.../annotations/processor/SettingProcessor.java | 2 +-
.../TouchPortalPluginAnnotationsProcessor.java | 12 ++++++------
4 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java
index 5270f0e..ec55530 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java
@@ -24,7 +24,7 @@ public class CategoryProcessor {
* @param pluginElement Element
* @param plugin {@link Plugin}
* @param categoryElement Element
- * @return Pair categoryPair
+ * @return Pair<JsonObject, TypeSpec.Builder> categoryPair
* @throws GenericHelper.TPTypeException If a used type is not Supported
*/
public static Pair process(TouchPortalPluginAnnotationsProcessor processor, RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement) throws Exception {
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java
index 7e4e505..b837ebf 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java
@@ -23,7 +23,7 @@ public class PluginProcessor {
*
* @param roundEnv RoundEnvironment
* @param pluginElement Element
- * @return Pair pluginPair
+ * @return Pair<JsonObject, TypeSpec.Builder> pluginPair
* @throws GenericHelper.TPTypeException If a used type is not Supported
*/
public static Pair process(TouchPortalPluginAnnotationsProcessor processor, RoundEnvironment roundEnv, Element pluginElement) throws Exception {
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java
index d5c636f..939fd69 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java
@@ -16,7 +16,7 @@ public class SettingProcessor {
* Generates a JsonObject and a TypeSpec.Builder representing the {@link Setting}
*
* @param settingElement Element
- * @return Pair statePair
+ * @return Pair<JsonObject, TypeSpec.Builder> statePair
* @throws GenericHelper.TPTypeException If a used type is not Supported
*/
public static Pair process(TouchPortalPluginAnnotationsProcessor processor, Element settingElement) throws Exception {
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationsProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationsProcessor.java
index d0a71f0..8b7a633 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationsProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationsProcessor.java
@@ -126,7 +126,7 @@ public boolean process(Set extends TypeElement> annotations, RoundEnvironment
* @param categoryElement Element
* @param category {@link Category}
* @param actionElement Element
- * @return Pair actionPair
+ * @return Pair<JsonObject, TypeSpec.Builder> actionPair
*/
public Pair processAction(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element actionElement) throws Exception {
this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Action: " + actionElement.getSimpleName());
@@ -195,7 +195,7 @@ public Pair processAction(RoundEnvironment roundEn
* @param categoryElement Element
* @param category {@link Category}
* @param connectorElement Element
- * @return Pair actionPair
+ * @return Pair<JsonObject, TypeSpec.Builder> actionPair
*/
public Pair processConnector(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element connectorElement) throws Exception {
this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Connector: " + connectorElement.getSimpleName());
@@ -255,7 +255,7 @@ public Pair processConnector(RoundEnvironment roun
* @param categoryElement Element
* @param category {@link Category}
* @param stateElement Element
- * @return Pair statePair
+ * @return Pair<JsonObject, TypeSpec.Builder> statePair
* @throws GenericHelper.TPTypeException If a used type is not Supported
*/
public Pair processState(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element stateElement) throws Exception {
@@ -300,7 +300,7 @@ else if (!desiredTPType.equals(StateHelper.TYPE_TEXT)) {
* @param categoryElement Element
* @param category {@link Category}
* @param eventElement Element
- * @return Pair eventPair
+ * @return Pair<JsonObject, TypeSpec.Builder> eventPair
* @throws GenericHelper.TPTypeException If any used type is not Supported
*/
public Pair processEvent(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element eventElement) throws Exception {
@@ -350,7 +350,7 @@ public Pair processEvent(RoundEnvironment roundEnv
* @param action {@link Action}
* @param jsonAction JsonObject
* @param dataElement Element
- * @return Pair dataPair
+ * @return Pair<JsonObject, TypeSpec.Builder> dataPair
*/
private Pair processActionData(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element actionElement, Action action, JsonObject jsonAction, Element dataElement) throws Exception {
this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Action Data: " + dataElement.getSimpleName());
@@ -490,7 +490,7 @@ private Pair processActionData(RoundEnvironment ro
* @param connector {@link Connector}
* @param jsonConnector JsonObject
* @param dataElement Element
- * @return Pair dataPair
+ * @return Pair<JsonObject, TypeSpec.Builder> dataPair
*/
private Pair processConnectorData(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element connectorElement, Connector connector, JsonObject jsonConnector, Element dataElement) throws Exception {
this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Connector Data: " + dataElement.getSimpleName());
From a7f8bcc8c3381c4e8a0672d8cecb8de53079ec17 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Sun, 27 Nov 2022 03:00:31 +0100
Subject: [PATCH 26/41] fix: JavaDoc
---
.../processor/CategoryProcessor.java | 3 ++-
.../processor/PluginProcessor.java | 3 ++-
.../processor/SettingProcessor.java | 2 +-
...TouchPortalPluginAnnotationsProcessor.java | 21 ++++++++++++-------
4 files changed, 19 insertions(+), 10 deletions(-)
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java
index ec55530..b0ee179 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java
@@ -26,8 +26,9 @@ public class CategoryProcessor {
* @param categoryElement Element
* @return Pair<JsonObject, TypeSpec.Builder> categoryPair
* @throws GenericHelper.TPTypeException If a used type is not Supported
+ * @throws TPAnnotationException If an Annotation is misused
*/
- public static Pair process(TouchPortalPluginAnnotationsProcessor processor, RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement) throws Exception {
+ public static Pair process(TouchPortalPluginAnnotationsProcessor processor, RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement) throws GenericHelper.TPTypeException, TPAnnotationException {
processor.getMessager().printMessage(Diagnostic.Kind.NOTE, "Process Category: " + categoryElement.getSimpleName());
Category category = categoryElement.getAnnotation(Category.class);
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java
index b837ebf..1e2705a 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java
@@ -25,8 +25,9 @@ public class PluginProcessor {
* @param pluginElement Element
* @return Pair<JsonObject, TypeSpec.Builder> pluginPair
* @throws GenericHelper.TPTypeException If a used type is not Supported
+ * @throws TPAnnotationException If an Annotation is misused
*/
- public static Pair process(TouchPortalPluginAnnotationsProcessor processor, RoundEnvironment roundEnv, Element pluginElement) throws Exception {
+ public static Pair process(TouchPortalPluginAnnotationsProcessor processor, RoundEnvironment roundEnv, Element pluginElement) throws GenericHelper.TPTypeException, TPAnnotationException {
processor.getMessager().printMessage(Diagnostic.Kind.NOTE, "Process Plugin: " + pluginElement.getSimpleName());
Plugin plugin = pluginElement.getAnnotation(Plugin.class);
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java
index 939fd69..408fec3 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java
@@ -19,7 +19,7 @@ public class SettingProcessor {
* @return Pair<JsonObject, TypeSpec.Builder> statePair
* @throws GenericHelper.TPTypeException If a used type is not Supported
*/
- public static Pair process(TouchPortalPluginAnnotationsProcessor processor, Element settingElement) throws Exception {
+ public static Pair process(TouchPortalPluginAnnotationsProcessor processor, Element settingElement) throws GenericHelper.TPTypeException {
processor.getMessager().printMessage(Diagnostic.Kind.NOTE, "Process Setting: " + settingElement.getSimpleName());
Setting setting = settingElement.getAnnotation(Setting.class);
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationsProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationsProcessor.java
index 8b7a633..15ef8ab 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationsProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationsProcessor.java
@@ -127,8 +127,9 @@ public boolean process(Set extends TypeElement> annotations, RoundEnvironment
* @param category {@link Category}
* @param actionElement Element
* @return Pair<JsonObject, TypeSpec.Builder> actionPair
+ * @throws GenericHelper.TPTypeException If a used type is not Supported
*/
- public Pair processAction(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element actionElement) throws Exception {
+ public Pair processAction(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element actionElement) throws GenericHelper.TPTypeException {
this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Action: " + actionElement.getSimpleName());
Action action = actionElement.getAnnotation(Action.class);
@@ -196,8 +197,10 @@ public Pair processAction(RoundEnvironment roundEn
* @param category {@link Category}
* @param connectorElement Element
* @return Pair<JsonObject, TypeSpec.Builder> actionPair
+ * @throws GenericHelper.TPTypeException If a used type is not Supported
+ * @throws TPAnnotationException If an Annotation is misused
*/
- public Pair processConnector(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element connectorElement) throws Exception {
+ public Pair processConnector(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element connectorElement) throws GenericHelper.TPTypeException, TPAnnotationException {
this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Connector: " + connectorElement.getSimpleName());
Connector connector = connectorElement.getAnnotation(Connector.class);
@@ -257,8 +260,9 @@ public Pair processConnector(RoundEnvironment roun
* @param stateElement Element
* @return Pair<JsonObject, TypeSpec.Builder> statePair
* @throws GenericHelper.TPTypeException If a used type is not Supported
+ * @throws TPAnnotationException If an Annotation is misused
*/
- public Pair processState(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element stateElement) throws Exception {
+ public Pair processState(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element stateElement) throws GenericHelper.TPTypeException, TPAnnotationException {
this.messager.printMessage(Diagnostic.Kind.NOTE, "Process State: " + stateElement.getSimpleName());
State state = stateElement.getAnnotation(State.class);
@@ -301,9 +305,10 @@ else if (!desiredTPType.equals(StateHelper.TYPE_TEXT)) {
* @param category {@link Category}
* @param eventElement Element
* @return Pair<JsonObject, TypeSpec.Builder> eventPair
- * @throws GenericHelper.TPTypeException If any used type is not Supported
+ * @throws GenericHelper.TPTypeException If a used type is not Supported
+ * @throws TPAnnotationException If an Annotation is misused
*/
- public Pair processEvent(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element eventElement) throws Exception {
+ public Pair processEvent(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element eventElement) throws GenericHelper.TPTypeException, TPAnnotationException {
this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Event: " + eventElement.getSimpleName());
State state = eventElement.getAnnotation(State.class);
Event event = eventElement.getAnnotation(Event.class);
@@ -351,8 +356,9 @@ public Pair processEvent(RoundEnvironment roundEnv
* @param jsonAction JsonObject
* @param dataElement Element
* @return Pair<JsonObject, TypeSpec.Builder> dataPair
+ * @throws GenericHelper.TPTypeException If a used type is not Supported
*/
- private Pair processActionData(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element actionElement, Action action, JsonObject jsonAction, Element dataElement) throws Exception {
+ private Pair processActionData(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element actionElement, Action action, JsonObject jsonAction, Element dataElement) throws GenericHelper.TPTypeException {
this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Action Data: " + dataElement.getSimpleName());
Data data = dataElement.getAnnotation(Data.class);
@@ -491,8 +497,9 @@ private Pair processActionData(RoundEnvironment ro
* @param jsonConnector JsonObject
* @param dataElement Element
* @return Pair<JsonObject, TypeSpec.Builder> dataPair
+ * @throws GenericHelper.TPTypeException If a used type is not Supported
*/
- private Pair processConnectorData(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element connectorElement, Connector connector, JsonObject jsonConnector, Element dataElement) throws Exception {
+ private Pair processConnectorData(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element connectorElement, Connector connector, JsonObject jsonConnector, Element dataElement) throws GenericHelper.TPTypeException {
this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Connector Data: " + dataElement.getSimpleName());
Data data = dataElement.getAnnotation(Data.class);
From 2f4cec16f765e253f12e550f570d16965fd27b7f Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Sun, 27 Nov 2022 03:04:16 +0100
Subject: [PATCH 27/41] fix: JavaDoc
---
.../touchportal/annotations/processor/CategoryProcessor.java | 1 +
.../touchportal/annotations/processor/PluginProcessor.java | 1 +
.../touchportal/annotations/processor/SettingProcessor.java | 1 +
3 files changed, 3 insertions(+)
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java
index b0ee179..ef32fdc 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java
@@ -20,6 +20,7 @@ public class CategoryProcessor {
/**
* Generates a JsonObject and a TypeSpec.Builder representing the {@link Category}
*
+ * @param processor {@link TouchPortalPluginAnnotationsProcessor}
* @param roundEnv RoundEnvironment
* @param pluginElement Element
* @param plugin {@link Plugin}
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java
index 1e2705a..eb5182b 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java
@@ -21,6 +21,7 @@ public class PluginProcessor {
/**
* Generates a JsonObject and a TypeSpec.Builder representing the {@link Plugin}
*
+ * @param processor {@link TouchPortalPluginAnnotationsProcessor}
* @param roundEnv RoundEnvironment
* @param pluginElement Element
* @return Pair<JsonObject, TypeSpec.Builder> pluginPair
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java
index 408fec3..589f1c3 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java
@@ -15,6 +15,7 @@ public class SettingProcessor {
/**
* Generates a JsonObject and a TypeSpec.Builder representing the {@link Setting}
*
+ * @param processor {@link TouchPortalPluginAnnotationsProcessor}
* @param settingElement Element
* @return Pair<JsonObject, TypeSpec.Builder> statePair
* @throws GenericHelper.TPTypeException If a used type is not Supported
From f47e49fe72a8e20a699f5a5f5449c83ef7ade9c6 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Sun, 27 Nov 2022 18:13:44 +0100
Subject: [PATCH 28/41] core: Refactor Annotations Processor
---
.../processor/ActionProcessor.java | 88 +++
.../processor/CategoryProcessor.java | 8 +-
.../processor/ConnectorProcessor.java | 81 +++
.../annotations/processor/DataProcessor.java | 168 ++++++
.../annotations/processor/EventProcessor.java | 69 +++
.../annotations/processor/StateProcessor.java | 66 +++
...TouchPortalPluginAnnotationsProcessor.java | 510 +-----------------
7 files changed, 478 insertions(+), 512 deletions(-)
create mode 100644 AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/ActionProcessor.java
create mode 100644 AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/ConnectorProcessor.java
create mode 100644 AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/DataProcessor.java
create mode 100644 AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/EventProcessor.java
create mode 100644 AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/StateProcessor.java
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/ActionProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/ActionProcessor.java
new file mode 100644
index 0000000..5eb5970
--- /dev/null
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/ActionProcessor.java
@@ -0,0 +1,88 @@
+package com.christophecvb.touchportal.annotations.processor;
+
+import com.christophecvb.touchportal.annotations.*;
+import com.christophecvb.touchportal.annotations.processor.utils.Pair;
+import com.christophecvb.touchportal.annotations.processor.utils.SpecUtils;
+import com.christophecvb.touchportal.helpers.ActionHelper;
+import com.christophecvb.touchportal.helpers.GenericHelper;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.squareup.javapoet.TypeSpec;
+
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.Element;
+import javax.tools.Diagnostic;
+import java.util.Set;
+
+public class ActionProcessor {
+ /**
+ * Generates a JsonObject and a TypeSpec.Builder representing the {@link Action}
+ *
+ * @param processor {@link TouchPortalPluginAnnotationsProcessor}
+ * @param roundEnv RoundEnvironment
+ * @param pluginElement Element
+ * @param plugin {@link Plugin}
+ * @param categoryElement Element
+ * @param category {@link Category}
+ * @param actionElement Element
+ * @return Pair<JsonObject, TypeSpec.Builder> actionPair
+ * @throws GenericHelper.TPTypeException If a used type is not Supported
+ */
+ public static Pair process(TouchPortalPluginAnnotationsProcessor processor, RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element actionElement) throws GenericHelper.TPTypeException {
+ processor.getMessager().printMessage(Diagnostic.Kind.NOTE, "Process Action: " + actionElement.getSimpleName());
+ Action action = actionElement.getAnnotation(Action.class);
+
+ TypeSpec.Builder actionTypeSpecBuilder = SpecUtils.createActionTypeSpecBuilder(pluginElement, categoryElement, category, actionElement, action);
+
+ JsonObject jsonAction = new JsonObject();
+ jsonAction.addProperty(ActionHelper.ID, ActionHelper.getActionId(pluginElement, categoryElement, category, actionElement, action));
+ jsonAction.addProperty(ActionHelper.NAME, ActionHelper.getActionName(actionElement, action));
+ jsonAction.addProperty(ActionHelper.PREFIX, action.prefix());
+ jsonAction.addProperty(ActionHelper.TYPE, action.type());
+ if (!action.description().isEmpty()) {
+ jsonAction.addProperty(ActionHelper.DESCRIPTION, action.description());
+ }
+ if (!action.format().isEmpty()) {
+ jsonAction.addProperty(ActionHelper.FORMAT, action.format());
+ jsonAction.addProperty(ActionHelper.TRY_INLINE, true);
+ }
+ jsonAction.addProperty(ActionHelper.HAS_HOLD_FUNCTIONALITY, action.hasHoldFunctionality());
+
+ ActionTranslation[] actionTranslations = actionElement.getAnnotationsByType(ActionTranslation.class);
+ if (actionTranslations.length > 0) {
+ for (ActionTranslation actionTranslation : actionTranslations) {
+ String languageCode = actionTranslation.language().getCode();
+ if (!actionTranslation.name().isEmpty()) {
+ jsonAction.addProperty(ActionHelper.NAME + "_" + languageCode, actionTranslation.name());
+ }
+ if (!actionTranslation.prefix().isEmpty()) {
+ jsonAction.addProperty(ActionHelper.PREFIX + "_" + languageCode, actionTranslation.prefix());
+ }
+ if (!actionTranslation.description().isEmpty()) {
+ jsonAction.addProperty(ActionHelper.DESCRIPTION + "_" + languageCode, actionTranslation.description());
+ }
+ if (!actionTranslation.format().isEmpty()) {
+ jsonAction.addProperty(ActionHelper.FORMAT + "_" + languageCode, actionTranslation.format());
+ }
+ }
+ }
+
+ JsonArray jsonActionData = new JsonArray();
+ Set extends Element> dataElements = roundEnv.getElementsAnnotatedWith(Data.class);
+ for (Element dataElement : dataElements) {
+ Element enclosingElement = dataElement.getEnclosingElement();
+ if (actionElement.equals(enclosingElement)) {
+ Pair actionDataResult = DataProcessor.process(processor, roundEnv, pluginElement, plugin, categoryElement, category, actionElement, action, jsonAction, dataElement);
+ jsonActionData.add(actionDataResult.first);
+ if (actionDataResult.second != null) {
+ actionTypeSpecBuilder.addType(actionDataResult.second.build());
+ }
+ }
+ }
+ if (jsonActionData.size() > 0) {
+ jsonAction.add(ActionHelper.DATA, jsonActionData);
+ }
+
+ return Pair.create(jsonAction, actionTypeSpecBuilder);
+ }
+}
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java
index ef32fdc..acd990f 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/CategoryProcessor.java
@@ -47,7 +47,7 @@ public static Pair process(TouchPortalPluginAnnota
Action action = actionElement.getAnnotation(Action.class);
String categoryId = category.id().isEmpty() ? categoryElement.getSimpleName().toString() : category.id();
if (categoryId.equals(action.categoryId())) {
- Pair actionResult = processor.processAction(roundEnv, pluginElement, plugin, categoryElement, category, actionElement);
+ Pair actionResult = ActionProcessor.process(processor, roundEnv, pluginElement, plugin, categoryElement, category, actionElement);
jsonActions.add(actionResult.first);
actionsTypeSpecBuilder.addType(actionResult.second.build());
}
@@ -62,7 +62,7 @@ public static Pair process(TouchPortalPluginAnnota
Connector connector = connectorElement.getAnnotation(Connector.class);
String categoryId = category.id().isEmpty() ? categoryElement.getSimpleName().toString() : category.id();
if (categoryId.equals(connector.categoryId())) {
- Pair connectorResult = processor.processConnector(roundEnv, pluginElement, plugin, categoryElement, category, connectorElement);
+ Pair connectorResult = ConnectorProcessor.process(processor, roundEnv, pluginElement, plugin, categoryElement, category, connectorElement);
jsonConnectors.add(connectorResult.first);
connectorsTypeSpecBuilder.addType(connectorResult.second.build());
}
@@ -77,7 +77,7 @@ public static Pair process(TouchPortalPluginAnnota
State state = stateElement.getAnnotation(State.class);
String categoryId = category.id().isEmpty() ? categoryElement.getSimpleName().toString() : category.id();
if (categoryId.equals(state.categoryId())) {
- Pair stateResult = processor.processState(roundEnv, pluginElement, plugin, categoryElement, category, stateElement);
+ Pair stateResult = StateProcessor.process(processor, roundEnv, pluginElement, plugin, categoryElement, category, stateElement);
jsonStates.add(stateResult.first);
statesTypeSpecBuilder.addType(stateResult.second.build());
}
@@ -93,7 +93,7 @@ public static Pair process(TouchPortalPluginAnnota
String categoryId = category.id().isEmpty() ? categoryElement.getSimpleName().toString() : category.id();
if (state != null) {
if (categoryId.equals(state.categoryId())) {
- Pair eventResult = processor.processEvent(roundEnv, pluginElement, plugin, categoryElement, category, eventElement);
+ Pair eventResult = EventProcessor.process(processor, roundEnv, pluginElement, plugin, categoryElement, category, eventElement);
jsonEvents.add(eventResult.first);
eventsTypeSpecBuilder.addType(eventResult.second.build());
}
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/ConnectorProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/ConnectorProcessor.java
new file mode 100644
index 0000000..45388fb
--- /dev/null
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/ConnectorProcessor.java
@@ -0,0 +1,81 @@
+package com.christophecvb.touchportal.annotations.processor;
+
+import com.christophecvb.touchportal.annotations.*;
+import com.christophecvb.touchportal.annotations.processor.utils.Pair;
+import com.christophecvb.touchportal.annotations.processor.utils.SpecUtils;
+import com.christophecvb.touchportal.helpers.ConnectorHelper;
+import com.christophecvb.touchportal.helpers.GenericHelper;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.squareup.javapoet.TypeSpec;
+
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.Element;
+import javax.tools.Diagnostic;
+import java.util.Set;
+
+public class ConnectorProcessor {
+
+ /**
+ * Generates a JsonObject and a TypeSpec.Builder representing the {@link Connector}
+ *
+ * @param processor {@link TouchPortalPluginAnnotationsProcessor}
+ * @param roundEnv RoundEnvironment
+ * @param pluginElement Element
+ * @param plugin {@link Plugin}
+ * @param categoryElement Element
+ * @param category {@link Category}
+ * @param connectorElement Element
+ * @return Pair<JsonObject, TypeSpec.Builder> actionPair
+ * @throws GenericHelper.TPTypeException If a used type is not Supported
+ * @throws TPAnnotationException If an Annotation is misused
+ */
+ public static Pair process(TouchPortalPluginAnnotationsProcessor processor, RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element connectorElement) throws GenericHelper.TPTypeException, TPAnnotationException {
+ processor.getMessager().printMessage(Diagnostic.Kind.NOTE, "Process Connector: " + connectorElement.getSimpleName());
+ Connector connector = connectorElement.getAnnotation(Connector.class);
+
+ TypeSpec.Builder connectorTypeSpecBuilder = SpecUtils.createConnectorTypeSpecBuilder(pluginElement, categoryElement, category, connectorElement, connector);
+
+ JsonObject jsonConnector = new JsonObject();
+ jsonConnector.addProperty(ConnectorHelper.ID, ConnectorHelper.getConnectorId(pluginElement, categoryElement, category, connectorElement, connector));
+ jsonConnector.addProperty(ConnectorHelper.NAME, ConnectorHelper.getConnectorName(connectorElement, connector));
+ jsonConnector.addProperty(ConnectorHelper.FORMAT, connector.format());
+
+ String classMethod = pluginElement.getSimpleName() + "." + connectorElement.getSimpleName();
+ boolean connectorValueFound = false;
+ Set extends Element> connectorValueElements = roundEnv.getElementsAnnotatedWith(ConnectorValue.class);
+ for (Element connectorValueElement : connectorValueElements) {
+ Element enclosingElement = connectorValueElement.getEnclosingElement();
+ if (connectorElement.equals(enclosingElement)) {
+ String classMethodParameter = classMethod + "(" + connectorValueElement.getSimpleName() + ")";
+ String desiredType = GenericHelper.getTouchPortalType(classMethodParameter, connectorValueElement);
+ if (!desiredType.equals(GenericHelper.TP_TYPE_NUMBER)) {
+ throw new GenericHelper.TPTypeException.Builder(classMethodParameter).typeUnsupported(desiredType).forAnnotation(GenericHelper.TPTypeException.ForAnnotation.CONNECTOR_VALUE).build();
+ }
+ connectorValueFound = true;
+ break;
+ }
+ }
+ if (!connectorValueFound) {
+ throw new TPAnnotationException.Builder(ConnectorValue.class).isMissing(true).forElement(connectorElement).build();
+ }
+
+ JsonArray jsonConnectorData = new JsonArray();
+ Set extends Element> dataElements = roundEnv.getElementsAnnotatedWith(Data.class);
+ for (Element dataElement : dataElements) {
+ Element enclosingElement = dataElement.getEnclosingElement();
+ if (connectorElement.equals(enclosingElement)) {
+ Pair connectorDataResult = DataProcessor.process(processor, roundEnv, pluginElement, plugin, categoryElement, category, connectorElement, connector, jsonConnector, dataElement);
+ jsonConnectorData.add(connectorDataResult.first);
+ if (connectorDataResult.second != null) {
+ connectorTypeSpecBuilder.addType(connectorDataResult.second.build());
+ }
+ }
+ }
+ if (jsonConnectorData.size() > 0) {
+ jsonConnector.add(ConnectorHelper.DATA, jsonConnectorData);
+ }
+
+ return Pair.create(jsonConnector, connectorTypeSpecBuilder);
+ }
+}
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/DataProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/DataProcessor.java
new file mode 100644
index 0000000..e1ebb7f
--- /dev/null
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/DataProcessor.java
@@ -0,0 +1,168 @@
+package com.christophecvb.touchportal.annotations.processor;
+
+import com.christophecvb.touchportal.annotations.*;
+import com.christophecvb.touchportal.annotations.processor.utils.Pair;
+import com.christophecvb.touchportal.annotations.processor.utils.SpecUtils;
+import com.christophecvb.touchportal.helpers.*;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.squareup.javapoet.TypeSpec;
+
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.Element;
+import javax.tools.Diagnostic;
+import java.lang.annotation.Annotation;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class DataProcessor {
+ /**
+ * Generates a JsonObject and a TypeSpec.Builder representing the {@link Data} for an {@link Action} or a {@link Connector}
+ *
+ * @param processor {@link TouchPortalPluginAnnotationsProcessor}
+ * @param roundEnv RoundEnvironment
+ * @param pluginElement Element
+ * @param plugin {@link Plugin}
+ * @param categoryElement Element
+ * @param category {@link Category}
+ * @param targetElement Element
+ * @param annotation {@link Action} or {@link Connector}
+ * @param jsonElement JsonObject
+ * @param dataElement Element
+ * @return Pair<JsonObject, TypeSpec.Builder> dataPair
+ * @throws GenericHelper.TPTypeException If a used type is not Supported
+ */
+ public static Pair process(TouchPortalPluginAnnotationsProcessor processor, RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element targetElement, T annotation, JsonObject jsonElement, Element dataElement) throws GenericHelper.TPTypeException {
+ String annotationName = annotation.annotationType().getSimpleName();
+ boolean isAction = annotation instanceof Action;
+
+ processor.getMessager().printMessage(Diagnostic.Kind.NOTE, "Process " + annotationName + " Data: " + dataElement.getSimpleName());
+ Data data = dataElement.getAnnotation(Data.class);
+
+ TypeSpec.Builder dataTypeSpecBuilder = isAction ?
+ SpecUtils.createActionDataTypeSpecBuilder(pluginElement, categoryElement, category, targetElement, (Action) annotation, dataElement, data) :
+ SpecUtils.createConnectorDataTypeSpecBuilder(pluginElement, categoryElement, category, targetElement, (Connector) annotation, dataElement, data);
+
+ Element method = dataElement.getEnclosingElement();
+ String className = method.getEnclosingElement().getSimpleName() + "." + annotationName + "(" + dataElement.getSimpleName() + ")";
+
+ JsonObject jsonData = new JsonObject();
+ String desiredTPType = GenericHelper.getTouchPortalType(className, dataElement);
+ jsonData.addProperty(DataHelper.TYPE, desiredTPType);
+ jsonData.addProperty(DataHelper.LABEL, DataHelper.getDataLabel(dataElement, data));
+ // Default Value
+ switch (desiredTPType) {
+ case GenericHelper.TP_TYPE_NUMBER:
+ double defaultValue = 0;
+ try {
+ defaultValue = Double.parseDouble(data.defaultValue());
+ }
+ catch (NumberFormatException ignored) {}
+ jsonData.addProperty(DataHelper.DEFAULT, defaultValue);
+ break;
+
+ case GenericHelper.TP_TYPE_SWITCH:
+ jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue().equals("true"));
+ break;
+
+ default:
+ jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue());
+ break;
+ }
+ AtomicReference dataId = new AtomicReference<>( isAction ?
+ DataHelper.getActionDataId(pluginElement, categoryElement, category, targetElement, (Action) annotation, dataElement, data) :
+ DataHelper.getConnectorDataId(pluginElement, categoryElement, category, targetElement, (Connector) annotation, dataElement, data));
+ // Specific properties
+ switch (desiredTPType) {
+ case GenericHelper.TP_TYPE_CHOICE:
+ JsonArray dataValueChoices = new JsonArray();
+ if (!data.stateId().isEmpty()) {
+ Optional extends Element> optionalStateElement = roundEnv.getElementsAnnotatedWith(State.class).stream().filter(element -> {
+ State state = element.getAnnotation(State.class);
+ String shortStateId = !state.id().isEmpty() ? state.id() : element.getSimpleName().toString();
+ return shortStateId.equals(data.stateId());
+ }).findFirst();
+ if (optionalStateElement.isPresent()) {
+ dataTypeSpecBuilder = null;
+
+ Element stateElement = optionalStateElement.get();
+ State state = stateElement.getAnnotation(State.class);
+ dataId.set(StateHelper.getStateId(pluginElement, categoryElement, category, stateElement, state));
+ for (String valueChoice : state.valueChoices()) {
+ dataValueChoices.add(valueChoice);
+ }
+ jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue().isEmpty() ? state.defaultValue() : data.defaultValue());
+ }
+ else {
+ for (String valueChoice : data.valueChoices()) {
+ dataValueChoices.add(valueChoice);
+ }
+ }
+ }
+ else {
+ for (String valueChoice : data.valueChoices()) {
+ dataValueChoices.add(valueChoice);
+ }
+ }
+ jsonData.add(DataHelper.VALUE_CHOICES, dataValueChoices);
+ break;
+
+ case GenericHelper.TP_TYPE_FILE:
+ if (data.isDirectory()) {
+ jsonData.addProperty(DataHelper.TYPE, GenericHelper.TP_TYPE_DIRECTORY);
+ }
+ else {
+ JsonArray jsonExtensions = new JsonArray();
+ for (String extension : data.extensions()) {
+ if (extension.matches(DataHelper.EXTENSION_FORMAT)) {
+ jsonExtensions.add(extension);
+ }
+ else {
+ processor.getMessager().printMessage(Diagnostic.Kind.ERROR, annotationName + " Data Extension: [" + extension + "] format is not valid");
+ }
+ }
+ jsonData.add(DataHelper.EXTENSIONS, jsonExtensions);
+ }
+ break;
+
+ case GenericHelper.TP_TYPE_TEXT:
+ if (data.isColor()) {
+ jsonData.addProperty(DataHelper.TYPE, GenericHelper.TP_TYPE_COLOR);
+ if (!data.defaultValue().isEmpty()) {
+ if (!data.defaultValue().matches(DataHelper.COLOR_FORMAT)) {
+ processor.getMessager().printMessage(Diagnostic.Kind.ERROR, annotationName + " Data Color Default value: [" + data.defaultValue() + "] format is not valid");
+ }
+ }
+ }
+ break;
+
+ case GenericHelper.TP_TYPE_NUMBER:
+ try {
+ double defaultValue = jsonData.get(DataHelper.DEFAULT).getAsDouble();
+ if (defaultValue < data.minValue() || defaultValue > data.maxValue()) {
+ throw new GenericHelper.TPTypeException.Builder(className).defaultNotInRange().build();
+ }
+ }
+ catch (NumberFormatException numberFormatException) {
+ throw new GenericHelper.TPTypeException.Builder(className).defaultInvalid(data.defaultValue()).build();
+ }
+ jsonData.addProperty(DataHelper.ALLOW_DECIMALS, GenericHelper.getTouchPortalTypeNumberAllowDecimals(dataElement.asType().toString()));
+ if (data.minValue() > Double.NEGATIVE_INFINITY) {
+ jsonData.addProperty(DataHelper.MIN_VALUE, data.minValue());
+ }
+ if (data.maxValue() < Double.POSITIVE_INFINITY) {
+ jsonData.addProperty(DataHelper.MAX_VALUE, data.maxValue());
+ }
+ break;
+ }
+ jsonData.addProperty(DataHelper.ID, dataId.get());
+ String format = isAction ? ((Action) annotation).format() : ((Connector) annotation).format();
+ if (!format.isEmpty()) {
+ // Replace wildcards
+ String rawFormat = jsonElement.get(isAction ? ActionHelper.FORMAT : ConnectorHelper.FORMAT).getAsString();
+ jsonElement.addProperty(isAction ? ActionHelper.FORMAT : ConnectorHelper.FORMAT, rawFormat.replace("{$" + (data.id().isEmpty() ? dataElement.getSimpleName().toString() : data.id()) + "$}", "{$" + dataId.get() + "$}"));
+ }
+
+ return Pair.create(jsonData, dataTypeSpecBuilder);
+ }
+}
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/EventProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/EventProcessor.java
new file mode 100644
index 0000000..f5d7a44
--- /dev/null
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/EventProcessor.java
@@ -0,0 +1,69 @@
+package com.christophecvb.touchportal.annotations.processor;
+
+import com.christophecvb.touchportal.annotations.Category;
+import com.christophecvb.touchportal.annotations.Event;
+import com.christophecvb.touchportal.annotations.Plugin;
+import com.christophecvb.touchportal.annotations.State;
+import com.christophecvb.touchportal.annotations.processor.utils.Pair;
+import com.christophecvb.touchportal.annotations.processor.utils.SpecUtils;
+import com.christophecvb.touchportal.helpers.EventHelper;
+import com.christophecvb.touchportal.helpers.GenericHelper;
+import com.christophecvb.touchportal.helpers.StateHelper;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.squareup.javapoet.TypeSpec;
+
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.Element;
+import javax.tools.Diagnostic;
+
+public class EventProcessor {
+ /**
+ * Generates a JsonObject and a TypeSpec.Builder representing the {@link Event}
+ *
+ * @param processor {@link TouchPortalPluginAnnotationsProcessor}
+ * @param roundEnv RoundEnvironment
+ * @param pluginElement Element
+ * @param plugin {@link Plugin}
+ * @param categoryElement Element
+ * @param category {@link Category}
+ * @param eventElement Element
+ * @return Pair<JsonObject, TypeSpec.Builder> eventPair
+ * @throws GenericHelper.TPTypeException If a used type is not Supported
+ * @throws TPAnnotationException If an Annotation is misused
+ */
+ public static Pair process(TouchPortalPluginAnnotationsProcessor processor, RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element eventElement) throws GenericHelper.TPTypeException, TPAnnotationException {
+ processor.getMessager().printMessage(Diagnostic.Kind.NOTE, "Process Event: " + eventElement.getSimpleName());
+ State state = eventElement.getAnnotation(State.class);
+ Event event = eventElement.getAnnotation(Event.class);
+
+ String reference = eventElement.getEnclosingElement().getSimpleName() + "." + eventElement.getSimpleName();
+
+ if (state == null) {
+ throw new TPAnnotationException.Builder(State.class).isMissing(true).forElement(eventElement).build();
+ }
+
+ TypeSpec.Builder eventTypeSpecBuilder = SpecUtils.createEventTypeSpecBuilder(pluginElement, categoryElement, category, eventElement, event);
+
+ JsonObject jsonEvent = new JsonObject();
+ jsonEvent.addProperty(EventHelper.ID, EventHelper.getEventId(pluginElement, categoryElement, category, eventElement, event));
+ jsonEvent.addProperty(EventHelper.TYPE, EventHelper.TYPE_COMMUNICATE);
+ jsonEvent.addProperty(EventHelper.NAME, EventHelper.getEventName(eventElement, event));
+ jsonEvent.addProperty(EventHelper.FORMAT, event.format());
+ String desiredTPType = GenericHelper.getTouchPortalType(reference, eventElement);
+ if (desiredTPType.equals(StateHelper.TYPE_TEXT)) {
+ jsonEvent.addProperty(EventHelper.VALUE_TYPE, EventHelper.VALUE_TYPE_CHOICE);
+ JsonArray eventValueChoices = new JsonArray();
+ for (String valueChoice : event.valueChoices()) {
+ eventValueChoices.add(valueChoice);
+ }
+ jsonEvent.add(EventHelper.VALUE_CHOICES, eventValueChoices);
+ jsonEvent.addProperty(EventHelper.VALUE_STATE_ID, StateHelper.getStateId(pluginElement, categoryElement, category, eventElement, state));
+ }
+ else {
+ throw new GenericHelper.TPTypeException.Builder(reference).typeUnsupported(desiredTPType).forAnnotation(GenericHelper.TPTypeException.ForAnnotation.EVENT).build();
+ }
+
+ return Pair.create(jsonEvent, eventTypeSpecBuilder);
+ }
+}
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/StateProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/StateProcessor.java
new file mode 100644
index 0000000..2e39802
--- /dev/null
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/StateProcessor.java
@@ -0,0 +1,66 @@
+package com.christophecvb.touchportal.annotations.processor;
+
+import com.christophecvb.touchportal.annotations.Category;
+import com.christophecvb.touchportal.annotations.Event;
+import com.christophecvb.touchportal.annotations.Plugin;
+import com.christophecvb.touchportal.annotations.State;
+import com.christophecvb.touchportal.annotations.processor.utils.Pair;
+import com.christophecvb.touchportal.annotations.processor.utils.SpecUtils;
+import com.christophecvb.touchportal.helpers.GenericHelper;
+import com.christophecvb.touchportal.helpers.StateHelper;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.squareup.javapoet.TypeSpec;
+
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.Element;
+import javax.tools.Diagnostic;
+
+public class StateProcessor {
+ /**
+ * Generates a JsonObject and a TypeSpec.Builder representing the {@link State}
+ *
+ * @param processor {@link TouchPortalPluginAnnotationsProcessor}
+ * @param roundEnv RoundEnvironment
+ * @param pluginElement Element
+ * @param plugin {@link Plugin}
+ * @param categoryElement Element
+ * @param category {@link Category}
+ * @param stateElement Element
+ * @return Pair<JsonObject, TypeSpec.Builder> statePair
+ * @throws GenericHelper.TPTypeException If a used type is not Supported
+ * @throws TPAnnotationException If an Annotation is misused
+ */
+ public static Pair process(TouchPortalPluginAnnotationsProcessor processor, RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element stateElement) throws GenericHelper.TPTypeException, TPAnnotationException {
+ processor.getMessager().printMessage(Diagnostic.Kind.NOTE, "Process State: " + stateElement.getSimpleName());
+ State state = stateElement.getAnnotation(State.class);
+
+ TypeSpec.Builder stateTypeSpecBuilder = SpecUtils.createStateTypeSpecBuilder(pluginElement, categoryElement, category, stateElement, state);
+
+ String className = stateElement.getEnclosingElement().getSimpleName() + "." + stateElement.getSimpleName();
+
+ JsonObject jsonState = new JsonObject();
+ jsonState.addProperty(StateHelper.ID, StateHelper.getStateId(pluginElement, categoryElement, category, stateElement, state));
+ String desiredTPType = GenericHelper.getTouchPortalType(className, stateElement);
+ jsonState.addProperty(StateHelper.TYPE, desiredTPType);
+ jsonState.addProperty(StateHelper.DESC, StateHelper.getStateDesc(stateElement, state));
+ jsonState.addProperty(StateHelper.DEFAULT, state.defaultValue());
+ if (desiredTPType.equals(StateHelper.TYPE_CHOICE)) {
+ JsonArray stateValueChoices = new JsonArray();
+ for (String valueChoice : state.valueChoices()) {
+ stateValueChoices.add(valueChoice);
+ }
+ jsonState.add(StateHelper.VALUE_CHOICES, stateValueChoices);
+ }
+ else if (!desiredTPType.equals(StateHelper.TYPE_TEXT)) {
+ throw new GenericHelper.TPTypeException.Builder(className).typeUnsupported(desiredTPType).forAnnotation(GenericHelper.TPTypeException.ForAnnotation.STATE).build();
+ }
+
+ Event event = stateElement.getAnnotation(Event.class);
+ if (event != null && !desiredTPType.equals(StateHelper.TYPE_TEXT)) {
+ throw new TPAnnotationException.Builder(State.class).typeFor(desiredTPType, className, "the field is also Annotated with Event. Only the type " + StateHelper.TYPE_TEXT + " is supported for a State that has an Event Annotation.").build();
+ }
+
+ return Pair.create(jsonState, stateTypeSpecBuilder);
+ }
+}
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationsProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationsProcessor.java
index 15ef8ab..79bcd45 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationsProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/TouchPortalPluginAnnotationsProcessor.java
@@ -70,6 +70,8 @@ public Set getSupportedAnnotationTypes() {
annotations.add(Setting.class.getCanonicalName());
annotations.add(Category.class.getCanonicalName());
annotations.add(Action.class.getCanonicalName());
+ annotations.add(ActionTranslation.class.getCanonicalName());
+ annotations.add(ActionTranslations.class.getCanonicalName());
annotations.add(Data.class.getCanonicalName());
annotations.add(State.class.getCanonicalName());
annotations.add(Event.class.getCanonicalName());
@@ -116,512 +118,4 @@ public boolean process(Set extends TypeElement> annotations, RoundEnvironment
return true;
}
-
- /**
- * Generates a JsonObject and a TypeSpec.Builder representing the {@link Action}
- *
- * @param roundEnv RoundEnvironment
- * @param pluginElement Element
- * @param plugin {@link Plugin}
- * @param categoryElement Element
- * @param category {@link Category}
- * @param actionElement Element
- * @return Pair<JsonObject, TypeSpec.Builder> actionPair
- * @throws GenericHelper.TPTypeException If a used type is not Supported
- */
- public Pair processAction(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element actionElement) throws GenericHelper.TPTypeException {
- this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Action: " + actionElement.getSimpleName());
- Action action = actionElement.getAnnotation(Action.class);
-
- TypeSpec.Builder actionTypeSpecBuilder = SpecUtils.createActionTypeSpecBuilder(pluginElement, categoryElement, category, actionElement, action);
-
- JsonObject jsonAction = new JsonObject();
- jsonAction.addProperty(ActionHelper.ID, ActionHelper.getActionId(pluginElement, categoryElement, category, actionElement, action));
- jsonAction.addProperty(ActionHelper.NAME, ActionHelper.getActionName(actionElement, action));
- jsonAction.addProperty(ActionHelper.PREFIX, action.prefix());
- jsonAction.addProperty(ActionHelper.TYPE, action.type());
- if (!action.description().isEmpty()) {
- jsonAction.addProperty(ActionHelper.DESCRIPTION, action.description());
- }
- if (!action.format().isEmpty()) {
- jsonAction.addProperty(ActionHelper.FORMAT, action.format());
- jsonAction.addProperty(ActionHelper.TRY_INLINE, true);
- }
- jsonAction.addProperty(ActionHelper.HAS_HOLD_FUNCTIONALITY, action.hasHoldFunctionality());
-
- ActionTranslation[] actionTranslations = actionElement.getAnnotationsByType(ActionTranslation.class);
- if (actionTranslations.length > 0) {
- for (ActionTranslation actionTranslation : actionTranslations) {
- String languageCode = actionTranslation.language().getCode();
- if (!actionTranslation.name().isEmpty()) {
- jsonAction.addProperty(ActionHelper.NAME + "_" + languageCode, actionTranslation.name());
- }
- if (!actionTranslation.prefix().isEmpty()) {
- jsonAction.addProperty(ActionHelper.PREFIX + "_" + languageCode, actionTranslation.prefix());
- }
- if (!actionTranslation.description().isEmpty()) {
- jsonAction.addProperty(ActionHelper.DESCRIPTION + "_" + languageCode, actionTranslation.description());
- }
- if (!actionTranslation.format().isEmpty()) {
- jsonAction.addProperty(ActionHelper.FORMAT + "_" + languageCode, actionTranslation.format());
- }
- }
- }
-
- JsonArray jsonActionData = new JsonArray();
- Set extends Element> dataElements = roundEnv.getElementsAnnotatedWith(Data.class);
- for (Element dataElement : dataElements) {
- Element enclosingElement = dataElement.getEnclosingElement();
- if (actionElement.equals(enclosingElement)) {
- Pair actionDataResult = this.processActionData(roundEnv, pluginElement, plugin, categoryElement, category, actionElement, action, jsonAction, dataElement);
- jsonActionData.add(actionDataResult.first);
- if (actionDataResult.second != null) {
- actionTypeSpecBuilder.addType(actionDataResult.second.build());
- }
- }
- }
- if (jsonActionData.size() > 0) {
- jsonAction.add(ActionHelper.DATA, jsonActionData);
- }
-
- return Pair.create(jsonAction, actionTypeSpecBuilder);
- }
-
- /**
- * Generates a JsonObject and a TypeSpec.Builder representing the {@link Connector}
- *
- * @param roundEnv RoundEnvironment
- * @param pluginElement Element
- * @param plugin {@link Plugin}
- * @param categoryElement Element
- * @param category {@link Category}
- * @param connectorElement Element
- * @return Pair<JsonObject, TypeSpec.Builder> actionPair
- * @throws GenericHelper.TPTypeException If a used type is not Supported
- * @throws TPAnnotationException If an Annotation is misused
- */
- public Pair processConnector(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element connectorElement) throws GenericHelper.TPTypeException, TPAnnotationException {
- this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Connector: " + connectorElement.getSimpleName());
- Connector connector = connectorElement.getAnnotation(Connector.class);
-
- TypeSpec.Builder connectorTypeSpecBuilder = SpecUtils.createConnectorTypeSpecBuilder(pluginElement, categoryElement, category, connectorElement, connector);
-
- JsonObject jsonConnector = new JsonObject();
- jsonConnector.addProperty(ConnectorHelper.ID, ConnectorHelper.getConnectorId(pluginElement, categoryElement, category, connectorElement, connector));
- jsonConnector.addProperty(ConnectorHelper.NAME, ConnectorHelper.getConnectorName(connectorElement, connector));
- jsonConnector.addProperty(ConnectorHelper.FORMAT, connector.format());
-
- String classMethod = pluginElement.getSimpleName() + "." + connectorElement.getSimpleName();
- boolean connectorValueFound = false;
- Set extends Element> connectorValueElements = roundEnv.getElementsAnnotatedWith(ConnectorValue.class);
- for (Element connectorValueElement : connectorValueElements) {
- Element enclosingElement = connectorValueElement.getEnclosingElement();
- if (connectorElement.equals(enclosingElement)) {
- String classMethodParameter = classMethod + "(" + connectorValueElement.getSimpleName() + ")";
- String desiredType = GenericHelper.getTouchPortalType(classMethodParameter, connectorValueElement);
- if (!desiredType.equals(GenericHelper.TP_TYPE_NUMBER)) {
- throw new GenericHelper.TPTypeException.Builder(classMethodParameter).typeUnsupported(desiredType).forAnnotation(GenericHelper.TPTypeException.ForAnnotation.CONNECTOR_VALUE).build();
- }
- connectorValueFound = true;
- break;
- }
- }
- if (!connectorValueFound) {
- throw new TPAnnotationException.Builder(ConnectorValue.class).isMissing(true).forElement(connectorElement).build();
- }
-
- JsonArray jsonConnectorData = new JsonArray();
- Set extends Element> dataElements = roundEnv.getElementsAnnotatedWith(Data.class);
- for (Element dataElement : dataElements) {
- Element enclosingElement = dataElement.getEnclosingElement();
- if (connectorElement.equals(enclosingElement)) {
- Pair connectorDataResult = this.processConnectorData(roundEnv, pluginElement, plugin, categoryElement, category, connectorElement, connector, jsonConnector, dataElement);
- jsonConnectorData.add(connectorDataResult.first);
- if (connectorDataResult.second != null) {
- connectorTypeSpecBuilder.addType(connectorDataResult.second.build());
- }
- }
- }
- if (jsonConnectorData.size() > 0) {
- jsonConnector.add(ConnectorHelper.DATA, jsonConnectorData);
- }
-
- return Pair.create(jsonConnector, connectorTypeSpecBuilder);
- }
-
- /**
- * Generates a JsonObject and a TypeSpec.Builder representing the {@link State}
- *
- * @param roundEnv RoundEnvironment
- * @param pluginElement Element
- * @param plugin {@link Plugin}
- * @param categoryElement Element
- * @param category {@link Category}
- * @param stateElement Element
- * @return Pair<JsonObject, TypeSpec.Builder> statePair
- * @throws GenericHelper.TPTypeException If a used type is not Supported
- * @throws TPAnnotationException If an Annotation is misused
- */
- public Pair processState(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element stateElement) throws GenericHelper.TPTypeException, TPAnnotationException {
- this.messager.printMessage(Diagnostic.Kind.NOTE, "Process State: " + stateElement.getSimpleName());
- State state = stateElement.getAnnotation(State.class);
-
- TypeSpec.Builder stateTypeSpecBuilder = SpecUtils.createStateTypeSpecBuilder(pluginElement, categoryElement, category, stateElement, state);
-
- String className = stateElement.getEnclosingElement().getSimpleName() + "." + stateElement.getSimpleName();
-
- JsonObject jsonState = new JsonObject();
- jsonState.addProperty(StateHelper.ID, StateHelper.getStateId(pluginElement, categoryElement, category, stateElement, state));
- String desiredTPType = GenericHelper.getTouchPortalType(className, stateElement);
- jsonState.addProperty(StateHelper.TYPE, desiredTPType);
- jsonState.addProperty(StateHelper.DESC, StateHelper.getStateDesc(stateElement, state));
- jsonState.addProperty(StateHelper.DEFAULT, state.defaultValue());
- if (desiredTPType.equals(StateHelper.TYPE_CHOICE)) {
- JsonArray stateValueChoices = new JsonArray();
- for (String valueChoice : state.valueChoices()) {
- stateValueChoices.add(valueChoice);
- }
- jsonState.add(StateHelper.VALUE_CHOICES, stateValueChoices);
- }
- else if (!desiredTPType.equals(StateHelper.TYPE_TEXT)) {
- throw new GenericHelper.TPTypeException.Builder(className).typeUnsupported(desiredTPType).forAnnotation(GenericHelper.TPTypeException.ForAnnotation.STATE).build();
- }
-
- Event event = stateElement.getAnnotation(Event.class);
- if (event != null && !desiredTPType.equals(StateHelper.TYPE_TEXT)) {
- throw new TPAnnotationException.Builder(State.class).typeFor(desiredTPType, className, "the field is also Annotated with Event. Only the type " + StateHelper.TYPE_TEXT + " is supported for a State that has an Event Annotation.").build();
- }
-
- return Pair.create(jsonState, stateTypeSpecBuilder);
- }
-
- /**
- * Generates a JsonObject and a TypeSpec.Builder representing the {@link Event}
- *
- * @param roundEnv RoundEnvironment
- * @param pluginElement Element
- * @param plugin {@link Plugin}
- * @param categoryElement Element
- * @param category {@link Category}
- * @param eventElement Element
- * @return Pair<JsonObject, TypeSpec.Builder> eventPair
- * @throws GenericHelper.TPTypeException If a used type is not Supported
- * @throws TPAnnotationException If an Annotation is misused
- */
- public Pair processEvent(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element eventElement) throws GenericHelper.TPTypeException, TPAnnotationException {
- this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Event: " + eventElement.getSimpleName());
- State state = eventElement.getAnnotation(State.class);
- Event event = eventElement.getAnnotation(Event.class);
-
- String reference = eventElement.getEnclosingElement().getSimpleName() + "." + eventElement.getSimpleName();
-
- if (state == null) {
- throw new TPAnnotationException.Builder(State.class).isMissing(true).forElement(eventElement).build();
- }
-
- TypeSpec.Builder eventTypeSpecBuilder = SpecUtils.createEventTypeSpecBuilder(pluginElement, categoryElement, category, eventElement, event);
-
- JsonObject jsonEvent = new JsonObject();
- jsonEvent.addProperty(EventHelper.ID, EventHelper.getEventId(pluginElement, categoryElement, category, eventElement, event));
- jsonEvent.addProperty(EventHelper.TYPE, EventHelper.TYPE_COMMUNICATE);
- jsonEvent.addProperty(EventHelper.NAME, EventHelper.getEventName(eventElement, event));
- jsonEvent.addProperty(EventHelper.FORMAT, event.format());
- String desiredTPType = GenericHelper.getTouchPortalType(reference, eventElement);
- if (desiredTPType.equals(StateHelper.TYPE_TEXT)) {
- jsonEvent.addProperty(EventHelper.VALUE_TYPE, EventHelper.VALUE_TYPE_CHOICE);
- JsonArray eventValueChoices = new JsonArray();
- for (String valueChoice : event.valueChoices()) {
- eventValueChoices.add(valueChoice);
- }
- jsonEvent.add(EventHelper.VALUE_CHOICES, eventValueChoices);
- jsonEvent.addProperty(EventHelper.VALUE_STATE_ID, StateHelper.getStateId(pluginElement, categoryElement, category, eventElement, state));
- }
- else {
- throw new GenericHelper.TPTypeException.Builder(reference).typeUnsupported(desiredTPType).forAnnotation(GenericHelper.TPTypeException.ForAnnotation.EVENT).build();
- }
-
- return Pair.create(jsonEvent, eventTypeSpecBuilder);
- }
-
- /**
- * Generates a JsonObject and a TypeSpec.Builder representing the {@link Data} for an {@link Action}
- *
- * @param roundEnv RoundEnvironment
- * @param pluginElement Element
- * @param plugin {@link Plugin}
- * @param categoryElement Element
- * @param category {@link Category}
- * @param actionElement Element
- * @param action {@link Action}
- * @param jsonAction JsonObject
- * @param dataElement Element
- * @return Pair<JsonObject, TypeSpec.Builder> dataPair
- * @throws GenericHelper.TPTypeException If a used type is not Supported
- */
- private Pair processActionData(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element actionElement, Action action, JsonObject jsonAction, Element dataElement) throws GenericHelper.TPTypeException {
- this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Action Data: " + dataElement.getSimpleName());
- Data data = dataElement.getAnnotation(Data.class);
-
- TypeSpec.Builder actionDataTypeSpecBuilder = SpecUtils.createActionDataTypeSpecBuilder(pluginElement, categoryElement, category, actionElement, action, dataElement, data);
-
- Element method = dataElement.getEnclosingElement();
- String className = method.getEnclosingElement().getSimpleName() + "." + method.getSimpleName() + "(" + dataElement.getSimpleName() + ")";
-
- JsonObject jsonData = new JsonObject();
- String desiredTPType = GenericHelper.getTouchPortalType(className, dataElement);
- jsonData.addProperty(DataHelper.TYPE, desiredTPType);
- jsonData.addProperty(DataHelper.LABEL, DataHelper.getDataLabel(dataElement, data));
- // Default Value
- switch (desiredTPType) {
- case GenericHelper.TP_TYPE_NUMBER:
- double defaultValue = 0;
- try {
- defaultValue = Double.parseDouble(data.defaultValue());
- }
- catch (NumberFormatException ignored) {}
- jsonData.addProperty(DataHelper.DEFAULT, defaultValue);
- break;
-
- case GenericHelper.TP_TYPE_SWITCH:
- jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue().equals("true"));
- break;
-
- default:
- jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue());
- break;
- }
- AtomicReference dataId = new AtomicReference<>(DataHelper.getActionDataId(pluginElement, categoryElement, category, actionElement, action, dataElement, data));
- // Specific properties
- switch (desiredTPType) {
- case GenericHelper.TP_TYPE_CHOICE:
- JsonArray dataValueChoices = new JsonArray();
- if (!data.stateId().isEmpty()) {
- Optional extends Element> optionalStateElement = roundEnv.getElementsAnnotatedWith(State.class).stream().filter(element -> {
- State state = element.getAnnotation(State.class);
- String shortStateId = !state.id().isEmpty() ? state.id() : element.getSimpleName().toString();
- return shortStateId.equals(data.stateId());
- }).findFirst();
- if (optionalStateElement.isPresent()) {
- actionDataTypeSpecBuilder = null;
-
- Element stateElement = optionalStateElement.get();
- State state = stateElement.getAnnotation(State.class);
- dataId.set(StateHelper.getStateId(pluginElement, categoryElement, category, stateElement, state));
- for (String valueChoice : state.valueChoices()) {
- dataValueChoices.add(valueChoice);
- }
- jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue().isEmpty() ? state.defaultValue() : data.defaultValue());
- }
- else {
- for (String valueChoice : data.valueChoices()) {
- dataValueChoices.add(valueChoice);
- }
- }
- }
- else {
- for (String valueChoice : data.valueChoices()) {
- dataValueChoices.add(valueChoice);
- }
- }
- jsonData.add(DataHelper.VALUE_CHOICES, dataValueChoices);
- break;
-
- case GenericHelper.TP_TYPE_FILE:
- if (data.isDirectory()) {
- jsonData.addProperty(DataHelper.TYPE, GenericHelper.TP_TYPE_DIRECTORY);
- }
- else {
- JsonArray jsonExtensions = new JsonArray();
- for (String extension : data.extensions()) {
- if (extension.matches(DataHelper.EXTENSION_FORMAT)) {
- jsonExtensions.add(extension);
- }
- else {
- this.messager.printMessage(Diagnostic.Kind.ERROR, "Action Data Extension: [" + extension + "] format is not valid");
- }
- }
- jsonData.add(DataHelper.EXTENSIONS, jsonExtensions);
- }
- break;
-
- case GenericHelper.TP_TYPE_TEXT:
- if (data.isColor()) {
- jsonData.addProperty(DataHelper.TYPE, GenericHelper.TP_TYPE_COLOR);
- if (!data.defaultValue().isEmpty()) {
- if (!data.defaultValue().matches(DataHelper.COLOR_FORMAT)) {
- this.messager.printMessage(Diagnostic.Kind.ERROR, "Action Data Color Default value: [" + data.defaultValue() + "] format is not valid");
- }
- }
- }
- break;
-
- case GenericHelper.TP_TYPE_NUMBER:
- try {
- double defaultValue = jsonData.get(DataHelper.DEFAULT).getAsDouble();
- if (defaultValue < data.minValue() || defaultValue > data.maxValue()) {
- throw new GenericHelper.TPTypeException.Builder(className).defaultNotInRange().build();
- }
- }
- catch (NumberFormatException numberFormatException) {
- throw new GenericHelper.TPTypeException.Builder(className).defaultInvalid(data.defaultValue()).build();
- }
- jsonData.addProperty(DataHelper.ALLOW_DECIMALS, GenericHelper.getTouchPortalTypeNumberAllowDecimals(dataElement.asType().toString()));
- if (data.minValue() > Double.NEGATIVE_INFINITY) {
- jsonData.addProperty(DataHelper.MIN_VALUE, data.minValue());
- }
- if (data.maxValue() < Double.POSITIVE_INFINITY) {
- jsonData.addProperty(DataHelper.MAX_VALUE, data.maxValue());
- }
- break;
- }
- jsonData.addProperty(DataHelper.ID, dataId.get());
- if (!action.format().isEmpty()) {
- // Replace wildcards
- String rawFormat = jsonAction.get(ActionHelper.FORMAT).getAsString();
- jsonAction.addProperty(ActionHelper.FORMAT, rawFormat.replace("{$" + (data.id().isEmpty() ? dataElement.getSimpleName().toString() : data.id()) + "$}", "{$" + dataId.get() + "$}"));
- }
-
- return Pair.create(jsonData, actionDataTypeSpecBuilder);
- }
-
- /**
- * Generates a JsonObject and a TypeSpec.Builder representing the {@link Data} for a {@link Connector}
- *
- * @param roundEnv RoundEnvironment
- * @param pluginElement Element
- * @param plugin {@link Plugin}
- * @param categoryElement Element
- * @param category {@link Category}
- * @param connectorElement Element
- * @param connector {@link Connector}
- * @param jsonConnector JsonObject
- * @param dataElement Element
- * @return Pair<JsonObject, TypeSpec.Builder> dataPair
- * @throws GenericHelper.TPTypeException If a used type is not Supported
- */
- private Pair processConnectorData(RoundEnvironment roundEnv, Element pluginElement, Plugin plugin, Element categoryElement, Category category, Element connectorElement, Connector connector, JsonObject jsonConnector, Element dataElement) throws GenericHelper.TPTypeException {
- this.messager.printMessage(Diagnostic.Kind.NOTE, "Process Connector Data: " + dataElement.getSimpleName());
- Data data = dataElement.getAnnotation(Data.class);
-
- TypeSpec.Builder connectorDataTypeSpecBuilder = SpecUtils.createConnectorDataTypeSpecBuilder(pluginElement, categoryElement, category, connectorElement, connector, dataElement, data);
-
- Element method = dataElement.getEnclosingElement();
- String className = method.getEnclosingElement().getSimpleName() + "." + method.getSimpleName() + "(" + dataElement.getSimpleName() + ")";
-
- JsonObject jsonData = new JsonObject();
- String desiredTPType = GenericHelper.getTouchPortalType(className, dataElement);
- jsonData.addProperty(DataHelper.TYPE, desiredTPType);
- jsonData.addProperty(DataHelper.LABEL, DataHelper.getDataLabel(dataElement, data));
- // Default Value
- switch (desiredTPType) {
- case GenericHelper.TP_TYPE_NUMBER:
- double defaultValue = 0;
- try {
- defaultValue = Double.parseDouble(data.defaultValue());
- }
- catch (NumberFormatException ignored) {}
- jsonData.addProperty(DataHelper.DEFAULT, defaultValue);
- break;
-
- case GenericHelper.TP_TYPE_SWITCH:
- jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue().equals("true"));
- break;
-
- default:
- jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue());
- break;
- }
- AtomicReference dataId = new AtomicReference<>(DataHelper.getConnectorDataId(pluginElement, categoryElement, category, connectorElement, connector, dataElement, data));
- // Specific properties
- switch (desiredTPType) {
- case GenericHelper.TP_TYPE_CHOICE:
- JsonArray dataValueChoices = new JsonArray();
- if (!data.stateId().isEmpty()) {
- Optional extends Element> optionalStateElement = roundEnv.getElementsAnnotatedWith(State.class).stream().filter(element -> {
- State state = element.getAnnotation(State.class);
- String shortStateId = !state.id().isEmpty() ? state.id() : element.getSimpleName().toString();
- return shortStateId.equals(data.stateId());
- }).findFirst();
- if (optionalStateElement.isPresent()) {
- connectorDataTypeSpecBuilder = null;
-
- Element stateElement = optionalStateElement.get();
- State state = stateElement.getAnnotation(State.class);
- dataId.set(StateHelper.getStateId(pluginElement, categoryElement, category, stateElement, state));
- for (String valueChoice : state.valueChoices()) {
- dataValueChoices.add(valueChoice);
- }
- jsonData.addProperty(DataHelper.DEFAULT, data.defaultValue().isEmpty() ? state.defaultValue() : data.defaultValue());
- }
- else {
- for (String valueChoice : data.valueChoices()) {
- dataValueChoices.add(valueChoice);
- }
- }
- }
- else {
- for (String valueChoice : data.valueChoices()) {
- dataValueChoices.add(valueChoice);
- }
- }
- jsonData.add(DataHelper.VALUE_CHOICES, dataValueChoices);
- break;
-
- case GenericHelper.TP_TYPE_FILE:
- if (data.isDirectory()) {
- jsonData.addProperty(DataHelper.TYPE, GenericHelper.TP_TYPE_DIRECTORY);
- }
- else {
- JsonArray jsonExtensions = new JsonArray();
- for (String extension : data.extensions()) {
- if (extension.matches(DataHelper.EXTENSION_FORMAT)) {
- jsonExtensions.add(extension);
- }
- else {
- this.messager.printMessage(Diagnostic.Kind.ERROR, "Action Data Extension: [" + extension + "] format is not valid");
- }
- }
- jsonData.add(DataHelper.EXTENSIONS, jsonExtensions);
- }
- break;
-
- case GenericHelper.TP_TYPE_TEXT:
- if (data.isColor()) {
- jsonData.addProperty(DataHelper.TYPE, GenericHelper.TP_TYPE_COLOR);
- if (!data.defaultValue().isEmpty()) {
- if (!data.defaultValue().matches(DataHelper.COLOR_FORMAT)) {
- this.messager.printMessage(Diagnostic.Kind.ERROR, "Action Data Color Default value: [" + data.defaultValue() + "] format is not valid");
- }
- }
- }
- break;
-
- case GenericHelper.TP_TYPE_NUMBER:
- try {
- double defaultValue = jsonData.get(DataHelper.DEFAULT).getAsDouble();
- if (defaultValue < data.minValue() || defaultValue > data.maxValue()) {
- throw new GenericHelper.TPTypeException.Builder(className).defaultNotInRange().build();
- }
- }
- catch (NumberFormatException numberFormatException) {
- throw new GenericHelper.TPTypeException.Builder(className).defaultInvalid(data.defaultValue()).build();
- }
- jsonData.addProperty(DataHelper.ALLOW_DECIMALS, GenericHelper.getTouchPortalTypeNumberAllowDecimals(dataElement.asType().toString()));
- if (data.minValue() > Double.NEGATIVE_INFINITY) {
- jsonData.addProperty(DataHelper.MIN_VALUE, data.minValue());
- }
- if (data.maxValue() < Double.POSITIVE_INFINITY) {
- jsonData.addProperty(DataHelper.MAX_VALUE, data.maxValue());
- }
- break;
- }
- jsonData.addProperty(DataHelper.ID, dataId.get());
- if (!connector.format().isEmpty()) {
- // Replace wildcards
- String rawFormat = jsonConnector.get(ConnectorHelper.FORMAT).getAsString();
- jsonConnector.addProperty(ConnectorHelper.FORMAT, rawFormat.replace("{$" + (data.id().isEmpty() ? dataElement.getSimpleName().toString() : data.id()) + "$}", "{$" + dataId.get() + "$}"));
- }
-
- return Pair.create(jsonData, connectorDataTypeSpecBuilder);
- }
}
From 89f49fdfd6e12cc759a6ea01bf88a5edf16e1ec4 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Sun, 27 Nov 2022 20:25:10 +0100
Subject: [PATCH 29/41] core: Add logs in tests
---
.../touchportal/TouchPortalPlugin.java | 4 +-
.../touchportal/test/LibraryTests.java | 95 ++++++++++++++++++-
2 files changed, 94 insertions(+), 5 deletions(-)
diff --git a/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java b/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
index cc829bb..deb2940 100644
--- a/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
+++ b/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
@@ -1307,7 +1307,7 @@ public MethodDataParameterException(Method method, Parameter parameter) {
/**
* Custom ConsoleHandler
*/
- private static class CustomConsoleHandler extends ConsoleHandler {
+ public static class CustomConsoleHandler extends ConsoleHandler {
public CustomConsoleHandler() {
super();
setFormatter(new SimpleFormatter() {
@@ -1317,7 +1317,7 @@ public CustomConsoleHandler() {
public synchronized String format(LogRecord lr) {
String[] path = lr.getSourceClassName().split("\\.");
return String.format(format,
- lr.getLevel().getLocalizedName(),
+ lr.getLevel().getName(),
path[path.length - 1] + "." + lr.getSourceMethodName(),
lr.getMessage()
);
diff --git a/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java b/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java
index f2f8bf2..b271368 100644
--- a/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java
+++ b/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java
@@ -46,10 +46,13 @@
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import static org.junit.Assert.*;
public class LibraryTests {
+ private static final Logger LOGGER = Logger.getLogger(LibraryTests.class.getSimpleName());
private static final long REASONABLE_TIME = 100;
private ServerSocket serverSocket;
private Socket serverSocketClient;
@@ -84,6 +87,11 @@ public void onNotificationOptionClicked(TPNotificationOptionClickedMessage tpNot
}
};
+ static {
+ LOGGER.setUseParentHandlers(false);
+ LOGGER.addHandler(new TouchPortalPlugin.CustomConsoleHandler());
+ }
+
@Before
public void initialize() throws IOException {
// Mock Server
@@ -150,6 +158,7 @@ public void close() {
@Test
public void testConnection() {
+ LOGGER.log(Level.FINE, "Now");
try {
Thread.sleep(REASONABLE_TIME);
}
@@ -162,6 +171,7 @@ public void testConnection() {
@Test
public void testConnectionFail() {
+ LOGGER.log(Level.FINE, "Now");
this.close();
boolean connectedPairedAndListening = this.touchPortalPluginTest.connectThenPairAndListen(null);
@@ -177,6 +187,7 @@ public void testConnectionFail() {
@Test
public void testMultipleConnect() {
+ LOGGER.log(Level.FINE, "Now");
// A connectThenPairAndListen is already done in the @Before
assertTrue(this.touchPortalPluginTest.connectThenPairAndListen(null));
assertTrue(this.touchPortalPluginTest.connectThenPairAndListen(this.touchPortalPluginListener));
@@ -184,6 +195,7 @@ public void testMultipleConnect() {
@Test
public void testCloseAndReConnect() {
+ LOGGER.log(Level.FINE, "Now");
this.touchPortalPluginTest.close(null);
boolean connectedPairedAndListening = this.touchPortalPluginTest.connectThenPairAndListen(null);
@@ -193,6 +205,7 @@ public void testCloseAndReConnect() {
@Test
public void testConnectionNoListener() {
+ LOGGER.log(Level.FINE, "Now");
this.touchPortalPluginTest.close(null);
boolean connectedPairedAndListening = this.touchPortalPluginTest.connectThenPairAndListen(null);
@@ -202,11 +215,13 @@ public void testConnectionNoListener() {
@Test
public void testClose() {
+ LOGGER.log(Level.FINE, "Now");
this.touchPortalPluginTest.close(null);
}
@Test
public void testServerSocketCloses() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
this.serverSocketClient.close();
this.serverSocket.close();
Thread.sleep(REASONABLE_TIME);
@@ -215,6 +230,7 @@ public void testServerSocketCloses() throws IOException, InterruptedException {
@Test
public void testSend() {
+ LOGGER.log(Level.FINE, "Now");
// Send State Update by ID from Constants
assertTrue(this.touchPortalPluginTest.sendStateUpdate(TouchPortalPluginTestConstants.BaseCategory.States.CustomState.ID, "New Value 01"));
@@ -227,6 +243,7 @@ public void testSend() {
@Test
public void testSendStates() {
+ LOGGER.log(Level.FINE, "Now");
assertFalse(this.touchPortalPluginTest.sendStateUpdate(null, null));
assertFalse(this.touchPortalPluginTest.sendStateUpdate("", null));
assertFalse(this.touchPortalPluginTest.sendStateUpdate("", ""));
@@ -240,6 +257,7 @@ public void testSendStates() {
@Test
public void testSendChoices() {
+ LOGGER.log(Level.FINE, "Now");
assertFalse(this.touchPortalPluginTest.sendChoiceUpdate(null, null));
assertFalse(this.touchPortalPluginTest.sendChoiceUpdate("", new String[0]));
assertFalse(this.touchPortalPluginTest.sendChoiceUpdate(null, new String[0]));
@@ -254,6 +272,7 @@ public void testSendChoices() {
@Test
public void testSendSpecificChoices() {
+ LOGGER.log(Level.FINE, "Now");
assertFalse(this.touchPortalPluginTest.sendSpecificChoiceUpdate(null, null, null));
assertFalse(this.touchPortalPluginTest.sendSpecificChoiceUpdate("", null, null));
assertFalse(this.touchPortalPluginTest.sendSpecificChoiceUpdate("", "", null));
@@ -273,6 +292,7 @@ public void testSendSpecificChoices() {
@Test
public void testSendActionDataUpdate() {
+ LOGGER.log(Level.FINE, "Now");
HashMap props = new HashMap<>();
assertFalse(this.touchPortalPluginTest.sendActionDataUpdate(null, null, null));
assertFalse(this.touchPortalPluginTest.sendActionDataUpdate("", null, null));
@@ -291,6 +311,7 @@ public void testSendActionDataUpdate() {
@Test
public void testLastStateValue() {
+ LOGGER.log(Level.FINE, "Now");
String stateValue = System.currentTimeMillis() + "";
assertTrue(this.touchPortalPluginTest.sendStateUpdate(TouchPortalPluginTestConstants.BaseCategory.States.CustomState.ID, stateValue));
assertFalse(this.touchPortalPluginTest.sendStateUpdate(TouchPortalPluginTestConstants.BaseCategory.States.CustomState.ID, stateValue));
@@ -299,6 +320,7 @@ public void testLastStateValue() {
@Test
public void testShowNotification() {
+ LOGGER.log(Level.FINE, "Now");
assertFalse (this.touchPortalPluginTest.sendShowNotification(null, null, null, null));
assertFalse(this.touchPortalPluginTest.sendShowNotification("", null, null, null));
assertFalse(this.touchPortalPluginTest.sendShowNotification("", "", null, null));
@@ -314,6 +336,7 @@ public void testShowNotification() {
@Test
public void testDynamicStates() {
+ LOGGER.log(Level.FINE, "Now");
assertFalse(this.touchPortalPluginTest.sendCreateState(null, null, null, null));
assertFalse(this.touchPortalPluginTest.sendCreateState("", null, null, null));
@@ -363,6 +386,7 @@ public void testDynamicStates() {
@Test
public void testSendFail() {
+ LOGGER.log(Level.FINE, "Now");
this.touchPortalPluginTest.close(null);
assertFalse(this.touchPortalPluginTest.sendStateUpdate(TouchPortalPluginTestConstants.BaseCategory.States.CustomState.ID, "New Value"));
assertFalse(this.touchPortalPluginTest.sendChoiceUpdate("listId", null, true));
@@ -373,9 +397,11 @@ public void testSendFail() {
@Test
public void testReceiveActionNoId() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_ACTION);
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -387,9 +413,11 @@ public void testReceiveActionNoId() throws IOException, InterruptedException {
@Test
public void testReceiveConnectorNoId() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_CONNECTOR_CHANGE);
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -401,10 +429,12 @@ public void testReceiveConnectorNoId() throws IOException, InterruptedException
@Test
public void testReceiveActionEmptyId() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_ACTION);
jsonMessage.addProperty(ReceivedMessageHelper.ACTION_ID, "");
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -416,10 +446,12 @@ public void testReceiveActionEmptyId() throws IOException, InterruptedException
@Test
public void testReceiveConnectorEmptyId() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_CONNECTOR_CHANGE);
jsonMessage.addProperty(ReceivedMessageHelper.CONNECTOR_ID, "");
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -431,6 +463,7 @@ public void testReceiveConnectorEmptyId() throws IOException, InterruptedExcepti
@Test
public void testReceiveShortConnectorIdNotification() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
Map dataReceived = new HashMap<>();
dataReceived.put(TouchPortalPluginTestConstants.BaseCategory.Connectors.ConnectorForSliderWithData.Text.ID + "0", "Text0!");
dataReceived.put(TouchPortalPluginTestConstants.BaseCategory.Connectors.ConnectorForSliderWithData.Text.ID, "Text!");
@@ -441,6 +474,7 @@ public void testReceiveShortConnectorIdNotification() throws IOException, Interr
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_SHORT_CONNECTOR_ID_NOTIFICATION);
jsonMessage.addProperty(ReceivedMessageHelper.CONNECTOR_ID, ConnectorHelper.getConstructedId(TouchPortalPluginTestConstants.ID, TouchPortalPluginTestConstants.BaseCategory.Connectors.ConnectorForSliderWithData.ID, 0, dataReceived));
jsonMessage.addProperty(ReceivedMessageHelper.SHORT_ID, "SHORT_ID");
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -458,6 +492,7 @@ public void testReceiveShortConnectorIdNotification() throws IOException, Interr
@Test
public void testReceiveDummyWithDataTextAndNumberAction() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_ACTION);
@@ -472,6 +507,7 @@ public void testReceiveDummyWithDataTextAndNumberAction() throws IOException, In
numberDataItem.addProperty(ReceivedMessageHelper.ACTION_DATA_VALUE, 42);
data.add(numberDataItem);
jsonMessage.add(ActionHelper.DATA, data);
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -483,6 +519,7 @@ public void testReceiveDummyWithDataTextAndNumberAction() throws IOException, In
@Test
public void testReceiveDummyWithDataFileAction() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_ACTION);
@@ -498,6 +535,7 @@ public void testReceiveDummyWithDataFileAction() throws IOException, Interrupted
directoryDataItem.addProperty(ReceivedMessageHelper.ACTION_DATA_VALUE, "/");
data.add(directoryDataItem);
jsonMessage.add(ActionHelper.DATA, data);
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -508,11 +546,13 @@ public void testReceiveDummyWithDataFileAction() throws IOException, Interrupted
}
@Test
- public void testReceiveDummyDummyWithJsonObject() throws IOException, InterruptedException {
+ public void testReceiveDummyWithJsonObject() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_ACTION);
jsonMessage.addProperty(ReceivedMessageHelper.ACTION_ID, TouchPortalPluginTestConstants.BaseCategory.Actions.DummyWithJsonObject.ID);
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -523,11 +563,13 @@ public void testReceiveDummyDummyWithJsonObject() throws IOException, Interrupte
}
@Test
- public void testReceiveDummyDummyWithTPActionMessage() throws IOException, InterruptedException {
+ public void testReceiveDummyWithTPActionMessage() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_ACTION);
jsonMessage.addProperty(ReceivedMessageHelper.ACTION_ID, TouchPortalPluginTestConstants.BaseCategory.Actions.DummyWithTPActionMessage.ID);
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -538,11 +580,13 @@ public void testReceiveDummyDummyWithTPActionMessage() throws IOException, Inter
}
@Test
- public void testReceiveDummyDummyWithParam() throws IOException, InterruptedException {
+ public void testReceiveDummyWithParamNotData() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_ACTION);
jsonMessage.addProperty(ReceivedMessageHelper.ACTION_ID, TouchPortalPluginTestConstants.BaseCategory.Actions.DummyWithParam.ID);
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -554,12 +598,14 @@ public void testReceiveDummyDummyWithParam() throws IOException, InterruptedExce
@Test
public void testReceiveActionHoldableDownAndUp() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
JsonObject jsonMessageHoldDown = new JsonObject();
jsonMessageHoldDown.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
jsonMessageHoldDown.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_HOLD_DOWN);
jsonMessageHoldDown.addProperty(ReceivedMessageHelper.ACTION_ID, TouchPortalPluginTestConstants.BaseCategory.Actions.ActionHoldable.ID);
+
out.println(jsonMessageHoldDown);
Thread.sleep(REASONABLE_TIME);
@@ -570,6 +616,7 @@ public void testReceiveActionHoldableDownAndUp() throws IOException, Interrupted
jsonMessageHoldUp.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
jsonMessageHoldUp.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_HOLD_UP);
jsonMessageHoldUp.addProperty(ReceivedMessageHelper.ACTION_ID, TouchPortalPluginTestConstants.BaseCategory.Actions.ActionHoldable.ID);
+
out.println(jsonMessageHoldUp);
Thread.sleep(REASONABLE_TIME);
@@ -582,12 +629,14 @@ public void testReceiveActionHoldableDownAndUp() throws IOException, Interrupted
@Test
public void testReceiveActionHoldablePress() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
JsonObject jsonMessageHoldDown = new JsonObject();
jsonMessageHoldDown.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
jsonMessageHoldDown.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_ACTION);
jsonMessageHoldDown.addProperty(ReceivedMessageHelper.ACTION_ID, TouchPortalPluginTestConstants.BaseCategory.Actions.ActionHoldable.ID);
+
out.println(jsonMessageHoldDown);
Thread.sleep(REASONABLE_TIME);
@@ -600,6 +649,7 @@ public void testReceiveActionHoldablePress() throws IOException, InterruptedExce
@Test
public void testReceiveConnectorForSlider() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
JsonObject jsonMessageConnectorForSlider = new JsonObject();
@@ -618,6 +668,7 @@ public void testReceiveConnectorForSlider() throws IOException, InterruptedExcep
@Test
public void testReceiveConnectorForSliderWithData() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
JsonObject jsonMessageConnectorForSliderWithData = new JsonObject();
@@ -629,6 +680,7 @@ public void testReceiveConnectorForSliderWithData() throws IOException, Interrup
JsonObject dataText = new JsonObject();
dataText.addProperty(ReceivedMessageHelper.ACTION_DATA_ID, TouchPortalPluginTestConstants.BaseCategory.Connectors.ConnectorForSliderWithData.Text.ID);
dataText.addProperty(ReceivedMessageHelper.ACTION_DATA_VALUE, "Sliding!");
+ data.add(dataText);
jsonMessageConnectorForSliderWithData.add(ConnectorHelper.DATA, data);
out.println(jsonMessageConnectorForSliderWithData);
@@ -641,6 +693,7 @@ public void testReceiveConnectorForSliderWithData() throws IOException, Interrup
@Test
public void testUpdateConnectorValue() {
+ LOGGER.log(Level.FINE, "Now");
HashMap data = new HashMap<>();
data.put("dataId", "value");
assertFalse(this.touchPortalPluginTest.sendConnectorUpdate(null, null, null, null));
@@ -659,6 +712,7 @@ public void testUpdateConnectorValue() {
@Test
public void testReceiveConnectorForSliderWithNonData() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
JsonObject jsonMessageConnectorForSliderWithNonData = new JsonObject();
@@ -677,9 +731,11 @@ public void testReceiveConnectorForSliderWithNonData() throws IOException, Inter
@Test
public void testReceiveListChange() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_LIST_CHANGE);
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -691,10 +747,12 @@ public void testReceiveListChange() throws IOException, InterruptedException {
@Test
public void testReceiveListChangeNoListener() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
this.touchPortalPluginTest.connectThenPairAndListen(null);
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_LIST_CHANGE);
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -706,10 +764,12 @@ public void testReceiveListChangeNoListener() throws IOException, InterruptedExc
@Test
public void testReceiveActionNoListener() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
this.touchPortalPluginTest.connectThenPairAndListen(null);
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_ACTION);
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -721,9 +781,11 @@ public void testReceiveActionNoListener() throws IOException, InterruptedExcepti
@Test
public void testReceiveBadPlugin() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, "falsePluginId");
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_ACTION);
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -735,8 +797,10 @@ public void testReceiveBadPlugin() throws IOException, InterruptedException {
@Test
public void testReceiveNoMessageType() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -748,9 +812,11 @@ public void testReceiveNoMessageType() throws IOException, InterruptedException
@Test
public void testReceiveUnknownMessageType() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, "unknown");
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -762,6 +828,7 @@ public void testReceiveUnknownMessageType() throws IOException, InterruptedExcep
@Test
public void testReceiveInfo() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
TPInfoMessage sentTPInfoMessage = new TPInfoMessage();
sentTPInfoMessage.status = "paired";
sentTPInfoMessage.sdkVersion = 3L;
@@ -800,9 +867,11 @@ public void testReceiveInfo() throws IOException, InterruptedException {
@Test
public void testReceiveInfoMissingPropsAndNoListener() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
this.touchPortalPluginTest.connectThenPairAndListen(null);
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_INFO);
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -822,9 +891,11 @@ public void testReceiveInfoMissingPropsAndNoListener() throws IOException, Inter
@Test
public void testReceiveClose() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_CLOSE_PLUGIN);
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -837,6 +908,7 @@ public void testReceiveClose() throws IOException, InterruptedException {
@Test
public void testReceiveJSONFail() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println("Not a JSON Object");
@@ -848,6 +920,7 @@ public void testReceiveJSONFail() throws IOException, InterruptedException {
@Test
public void testReceiveEmpty() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println();
@@ -859,6 +932,7 @@ public void testReceiveEmpty() throws IOException, InterruptedException {
@Test
public void testReceivePart() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.print("This");
out.print("is");
@@ -874,25 +948,30 @@ public void testReceivePart() throws IOException, InterruptedException {
@Test
public void testReceiveBroadcast() throws IOException {
+ LOGGER.log(Level.FINE, "Now");
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_BROADCAST);
jsonMessage.addProperty(ReceivedMessageHelper.EVENT, ReceivedMessageHelper.EVENT_PAGE_CHANGE);
jsonMessage.addProperty(ReceivedMessageHelper.PAGE_NAME, "Page ONE");
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
}
@Test
public void testReceiveBroadcastMissingPropsAndNoListener() throws IOException {
+ LOGGER.log(Level.FINE, "Now");
this.touchPortalPluginTest.connectThenPairAndListen(null);
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_BROADCAST);
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
}
@Test
public void testReceiveSettings() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
JsonArray jsonSettings = new JsonArray();
JsonObject jsonSettingIP = new JsonObject();
@@ -923,10 +1002,12 @@ public void testReceiveSettings() throws IOException, InterruptedException {
@Test
public void testReceiveSettingsNoListener() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
this.touchPortalPluginTest.connectThenPairAndListen(null);
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_SETTINGS);
+
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -938,6 +1019,7 @@ public void testReceiveSettingsNoListener() throws IOException, InterruptedExcep
@Test
public void testSendSettingUpdate() throws IOException, InterruptedException {
+ LOGGER.log(Level.FINE, "Now");
assertFalse(this.touchPortalPluginTest.sendSettingUpdate("DOES NOT EXISTS", "VALUE", false));
TPInfoMessage sentTPInfoMessage = new TPInfoMessage();
@@ -982,6 +1064,7 @@ public void testSendSettingUpdate() throws IOException, InterruptedException {
@Test
public void testAnnotations() {
+ LOGGER.log(Level.FINE, "Now");
assertEquals(TouchPortalPluginTestConstants.ID, "com.christophecvb.touchportal.test.TouchPortalPluginTest");
assertEquals(TouchPortalPluginTestConstants.BaseCategory.ID, "com.christophecvb.touchportal.test.TouchPortalPluginTest.BaseCategory");
assertEquals(TouchPortalPluginTestConstants.BaseCategory.Actions.DummyWithDataTextAndNumber.ID, "com.christophecvb.touchportal.test.TouchPortalPluginTest.BaseCategory.action.dummyWithDataTextAndNumber");
@@ -992,6 +1075,7 @@ public void testAnnotations() {
@Test
public void testEntryTPAndConstants() throws IOException {
+ LOGGER.log(Level.FINE, "Now");
File testGeneratedResourcesDirectory = new File("../../../../build/generated/sources/annotationProcessor/java/test/resources");
BufferedReader reader = Files.newBufferedReader(Paths.get(new File(testGeneratedResourcesDirectory.getAbsolutePath() + "/entry.tp").getAbsolutePath()));
@@ -1071,6 +1155,7 @@ public void testEntryTPAndConstants() throws IOException {
@Test
public void testProperties() {
+ LOGGER.log(Level.FINE, "Now");
// Test reloadProperties without a Properties File
assertFalse(this.touchPortalPluginTest.reloadProperties());
@@ -1099,11 +1184,13 @@ public void testProperties() {
@Test
public void testPropertiesFail() {
+ LOGGER.log(Level.FINE, "Now");
assertFalse(this.touchPortalPluginTest.loadProperties("doesNot.exists"));
}
@Test
public void testPropertiesAccess() {
+ LOGGER.log(Level.FINE, "Now");
// No Loaded Properties File
assertNull(this.touchPortalPluginTest.removeProperty("non existent"));
assertNull(this.touchPortalPluginTest.getProperty("non existent"));
@@ -1112,6 +1199,7 @@ public void testPropertiesAccess() {
@Test
public void testIsUpdateAvailable() {
+ LOGGER.log(Level.FINE, "Now");
assertFalse(this.touchPortalPluginTest.isUpdateAvailable("", 0));
assertFalse(this.touchPortalPluginTest.isUpdateAvailable("https://raw.githubusercontent.com/ChristopheCVB/TouchPortalPluginSDK/master/Library/src/test/resources/TouchPortalPluginTest/plugin.config", 1)); // Uses plugin.version
assertTrue(this.touchPortalPluginTest.isUpdateAvailable("https://raw.githubusercontent.com/ChristopheCVB/TouchPortalPluginSDK/master/Library/src/test/resources/TouchPortalPluginTest/plugin.config", 0)); // Uses plugin.version
@@ -1119,6 +1207,7 @@ public void testIsUpdateAvailable() {
@Test
public void testOAuth2() throws IOException {
+ LOGGER.log(Level.FINE, "Now");
String host = "localhost";
String callbackPath = "/oauth";
int port = -1;
From bfd7e4ac2b4f506d0ea690fd472c1c9b3e5a3451 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Sun, 4 Dec 2022 22:42:27 +0100
Subject: [PATCH 30/41] core: (WIP) Modularization closes #54
---
.../touchportal/annotations/Action.java | 25 +-
.../annotations/ActionTranslation.java | 1 +
.../annotations/ActionTranslations.java | 4 +
.../touchportal/annotations/Connector.java | 25 +-
.../annotations/ConnectorValue.java | 2 +-
.../touchportal/annotations/Data.java | 2 +-
.../annotations/processor/DataProcessor.java | 1 +
.../touchportal/helpers/ActionHelper.java | 19 ++
.../touchportal/helpers/ConnectorHelper.java | 31 +++
.../touchportal/helpers/DataHelper.java | 40 +++
.../christophecvb/touchportal/TPAction.java | 12 +
.../touchportal/TPConnector.java | 8 +
.../touchportal/TPInvokable.java | 15 +
.../touchportal/TouchPortalPlugin.java | 260 ++++++++++++------
.../touchportal/model/TPActionMessage.java | 5 +
.../model/TPConnectorChangeMessage.java | 5 +
...Message.java => TPListChangedMessage.java} | 2 +-
.../touchportal/test/LibraryTests.java | 2 +-
.../TouchPortalPluginTest/plugin.config | 2 +-
README.md | 2 +-
.../TouchPortalSampleJavaPlugin.java | 13 +-
.../invokable/action/ExampleClassAction.java | 43 +++
.../connector/ExampleClassConnector.java | 39 +++
.../TouchPortalSampleKotlinPlugin.kt | 2 +-
24 files changed, 451 insertions(+), 109 deletions(-)
create mode 100644 Library/src/main/java/com/christophecvb/touchportal/TPAction.java
create mode 100644 Library/src/main/java/com/christophecvb/touchportal/TPConnector.java
create mode 100644 Library/src/main/java/com/christophecvb/touchportal/TPInvokable.java
rename Library/src/main/java/com/christophecvb/touchportal/model/{TPListChangeMessage.java => TPListChangedMessage.java} (94%)
create mode 100644 SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/invokable/action/ExampleClassAction.java
create mode 100644 SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/invokable/connector/ExampleClassConnector.java
diff --git a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Action.java b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Action.java
index ce829ac..31c279b 100644
--- a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Action.java
+++ b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Action.java
@@ -28,17 +28,30 @@
/**
* Action Annotation
*
- * Target is a Method
- *
- *
- * If your method only has @Data annotated parameters, it will be called automatically by the SDK.
- * If it is not the case, the SDK will call the TouchPortalPluginListener.onReceive(JsonObject jsonMessage) instead.
+ * Target is a Method or a Class extending TPAction
*
+ *
+ * -
+ * If used on a Method
+ *
+ * - If the method only has @Data annotated parameters, it will be called automatically by the SDK.
+ * - If it is not the case, the SDK will call the TouchPortalPluginListener.onReceive(JsonObject jsonMessage) instead.
+ *
+ *
+ * -
+ * If used on a Class, the SDK will
+ *
+ * - Create a new instance of the Class
+ * - Set the instance's {@link Data} annotated fields
+ * - Call the onInvoke method
+ *
+ *
+ *
*
* @see TP Documentation: Dynamic Actions
*/
@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
+@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Action {
/**
* Action id
diff --git a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ActionTranslation.java b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ActionTranslation.java
index 1830a22..6338933 100644
--- a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ActionTranslation.java
+++ b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ActionTranslation.java
@@ -29,6 +29,7 @@
*
*/
@Repeatable(ActionTranslations.class)
+@Target({ElementType.METHOD, ElementType.TYPE})
public @interface ActionTranslation {
/**
* ActionTranslation Language
diff --git a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ActionTranslations.java b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ActionTranslations.java
index 3efd044..37bcd53 100644
--- a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ActionTranslations.java
+++ b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ActionTranslations.java
@@ -1,5 +1,9 @@
package com.christophecvb.touchportal.annotations;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target({ElementType.METHOD, ElementType.TYPE})
public @interface ActionTranslations {
ActionTranslation[] value();
}
diff --git a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Connector.java b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Connector.java
index d07ecfc..5aafdd0 100644
--- a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Connector.java
+++ b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Connector.java
@@ -28,17 +28,30 @@
/**
* Connector Annotation
*
- * Target is a Method
- *
- *
- * If your method only has @Data annotated parameters, it will be called automatically by the SDK.
- * If it is not the case, the SDK will call the TouchPortalPluginListener.onReceive(JsonObject jsonMessage) instead.
+ * Target is a Method or a Class extending TPConnector
*
+ *
+ * -
+ * If used on a Method
+ *
+ * - If the method only has @Data annotated parameters, it will be called automatically by the SDK.
+ * - If it is not the case, the SDK will call the TouchPortalPluginListener.onReceive(JsonObject jsonMessage) instead.
+ *
+ *
+ * -
+ * If used on a Class, the SDK will
+ *
+ * - Create a new instance of the Class
+ * - Set the instance's {@link Data} annotated fields
+ * - Call the onInvoke method
+ *
+ *
+ *
*
* @see TP Documentation: Connectors
*/
@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
+@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Connector {
/**
* Connector id
diff --git a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ConnectorValue.java b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ConnectorValue.java
index de3eaa1..c1fdc12 100644
--- a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ConnectorValue.java
+++ b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/ConnectorValue.java
@@ -38,6 +38,6 @@
* @see TP Documentation: Connectors
*/
@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.PARAMETER)
+@Target({ElementType.PARAMETER, ElementType.FIELD})
public @interface ConnectorValue {
}
diff --git a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Data.java b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Data.java
index 1a57faf..a23a942 100644
--- a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Data.java
+++ b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Data.java
@@ -34,7 +34,7 @@
* @see TP Documentation: Action Data
*/
@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.PARAMETER)
+@Target({ElementType.PARAMETER, ElementType.FIELD})
public @interface Data {
/**
* Data id
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/DataProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/DataProcessor.java
index e1ebb7f..7d8af7c 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/DataProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/DataProcessor.java
@@ -19,6 +19,7 @@ public class DataProcessor {
/**
* Generates a JsonObject and a TypeSpec.Builder representing the {@link Data} for an {@link Action} or a {@link Connector}
*
+ * @param Action or Connector Annotation
* @param processor {@link TouchPortalPluginAnnotationsProcessor}
* @param roundEnv RoundEnvironment
* @param pluginElement Element
diff --git a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/ActionHelper.java b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/ActionHelper.java
index 907ae91..4ded488 100644
--- a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/ActionHelper.java
+++ b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/ActionHelper.java
@@ -24,6 +24,7 @@
import com.christophecvb.touchportal.annotations.Category;
import javax.lang.model.element.Element;
+import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
@@ -109,6 +110,24 @@ public static String getActionId(Class> pluginClass, Method actionMethod) {
return actionId;
}
+ /**
+ * Get the generated Action ID
+ *
+ * @param pluginClass Class
+ * @param actionField Field
+ * @return String actionId
+ */
+ public static String getActionId(Class> pluginClass, Field actionField) {
+ String actionId = "";
+
+ if (actionField.getDeclaringClass().isAnnotationPresent(Action.class)) {
+ Action action = actionField.getDeclaringClass().getDeclaredAnnotation(Action.class);
+ actionId = ActionHelper._getActionId(CategoryHelper.getCategoryId(pluginClass, action.categoryId()), (!action.id().isEmpty() ? action.id() : actionField.getDeclaringClass().getSimpleName()));
+ }
+
+ return actionId;
+ }
+
/**
* Internal - Get the formatted Action ID
*
diff --git a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/ConnectorHelper.java b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/ConnectorHelper.java
index 6e0e20c..993075f 100644
--- a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/ConnectorHelper.java
+++ b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/ConnectorHelper.java
@@ -24,6 +24,7 @@
import com.christophecvb.touchportal.annotations.Connector;
import javax.lang.model.element.Element;
+import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
@@ -105,6 +106,24 @@ public static String getConnectorId(Class> pluginClass, Method connectorMethod
return connectorId;
}
+ /**
+ * Get the generated Connector ID
+ *
+ * @param pluginClass Class
+ * @param connectorField Field
+ * @return String connectorId
+ */
+ public static String getConnectorId(Class> pluginClass, Field connectorField) {
+ String connectorId = "";
+
+ if (connectorField.getDeclaringClass().isAnnotationPresent(Connector.class)) {
+ Connector connector = connectorField.getDeclaringClass().getDeclaredAnnotation(Connector.class);
+ connectorId = ConnectorHelper.getConnectorId(pluginClass, connectorField.getDeclaringClass(), connector);
+ }
+
+ return connectorId;
+ }
+
/**
* Get the generated Connector ID
*
@@ -117,6 +136,18 @@ public static String getConnectorId(Class> pluginClass, Method connectorMethod
return ConnectorHelper._getConnectorId(CategoryHelper.getCategoryId(pluginClass, connector.categoryId()), !connector.id().isEmpty() ? connector.id() : connectorMethod.getName());
}
+ /**
+ * Get the generated Connector ID
+ *
+ * @param pluginClass Class
+ * @param connectorClass Class
+ * @param connector {@link Connector}
+ * @return String connectorId
+ */
+ public static String getConnectorId(Class> pluginClass, Class connectorClass, Connector connector) {
+ return ConnectorHelper._getConnectorId(CategoryHelper.getCategoryId(pluginClass, connector.categoryId()), !connector.id().isEmpty() ? connector.id() : connectorClass.getSimpleName());
+ }
+
/**
* Internal - Get the formatted Connector ID
*
diff --git a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/DataHelper.java b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/DataHelper.java
index c9e0da8..6bce8c9 100644
--- a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/DataHelper.java
+++ b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/DataHelper.java
@@ -23,6 +23,7 @@
import com.christophecvb.touchportal.annotations.*;
import javax.lang.model.element.Element;
+import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
@@ -150,6 +151,45 @@ else if (method.isAnnotationPresent(Connector.class)) {
return dataId;
}
+ /**
+ * Get the generated Data Id
+ *
+ * @param pluginClass Class
+ * @param field Field
+ * @return String dataId
+ */
+ public static String getDataId(Class> pluginClass, Field field) {
+ String dataId = "";
+
+ if (field.isAnnotationPresent(Data.class)) {
+ Data data = field.getAnnotation(Data.class);
+ if (!data.stateId().isEmpty()) {
+ String categoryId = null;
+ if (field.getDeclaringClass().isAnnotationPresent(Action.class)) {
+ Action action = field.getDeclaringClass().getAnnotation(Action.class);
+ categoryId = action.categoryId();
+ }
+ else if (field.getDeclaringClass().isAnnotationPresent(Connector.class)) {
+ Connector connector = field.getDeclaringClass().getAnnotation(Connector.class);
+ categoryId = connector.categoryId();
+ }
+ if (categoryId != null) {
+ dataId = StateHelper.getStateId(pluginClass, categoryId, data.stateId());
+ }
+ }
+ else {
+ if (field.getDeclaringClass().isAnnotationPresent(Action.class)) {
+ dataId = DataHelper._getDataId(ActionHelper.getActionId(pluginClass, field), data.id().isEmpty() ? field.getName() : data.id());
+ }
+ else if (field.getDeclaringClass().isAnnotationPresent(Connector.class)) {
+ dataId = DataHelper._getDataId(ConnectorHelper.getConnectorId(pluginClass, field), data.id().isEmpty() ? field.getName() : data.id());
+ }
+ }
+ }
+
+ return dataId;
+ }
+
/**
* Internal - Get the formatted Data Id
*
diff --git a/Library/src/main/java/com/christophecvb/touchportal/TPAction.java b/Library/src/main/java/com/christophecvb/touchportal/TPAction.java
new file mode 100644
index 0000000..054a147
--- /dev/null
+++ b/Library/src/main/java/com/christophecvb/touchportal/TPAction.java
@@ -0,0 +1,12 @@
+package com.christophecvb.touchportal;
+
+public abstract class TPAction extends TPInvokable {
+
+ public TPAction(T touchPortalPlugin) {
+ super(touchPortalPlugin);
+ }
+
+ protected Boolean isBeingHeld(String actionId) {
+ return this.touchPortalPlugin.isActionBeingHeld(actionId);
+ }
+}
\ No newline at end of file
diff --git a/Library/src/main/java/com/christophecvb/touchportal/TPConnector.java b/Library/src/main/java/com/christophecvb/touchportal/TPConnector.java
new file mode 100644
index 0000000..8e76c7a
--- /dev/null
+++ b/Library/src/main/java/com/christophecvb/touchportal/TPConnector.java
@@ -0,0 +1,8 @@
+package com.christophecvb.touchportal;
+
+public abstract class TPConnector extends TPInvokable {
+
+ public TPConnector(T touchPortalPlugin) {
+ super(touchPortalPlugin);
+ }
+}
\ No newline at end of file
diff --git a/Library/src/main/java/com/christophecvb/touchportal/TPInvokable.java b/Library/src/main/java/com/christophecvb/touchportal/TPInvokable.java
new file mode 100644
index 0000000..8a5ae7f
--- /dev/null
+++ b/Library/src/main/java/com/christophecvb/touchportal/TPInvokable.java
@@ -0,0 +1,15 @@
+package com.christophecvb.touchportal;
+
+import com.christophecvb.touchportal.model.TPListChangedMessage;
+
+abstract class TPInvokable {
+ protected final T touchPortalPlugin;
+
+ public TPInvokable(T touchPortalPlugin) {
+ this.touchPortalPlugin = touchPortalPlugin;
+ }
+
+ public abstract void onInvoke();
+
+ public abstract void onListChanged(TPListChangedMessage tpListChangedMessage);
+}
\ No newline at end of file
diff --git a/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java b/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
index deb2940..def900f 100644
--- a/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
+++ b/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
@@ -30,9 +30,7 @@
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Parameter;
+import java.lang.reflect.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
@@ -143,6 +141,10 @@ public abstract class TouchPortalPlugin {
* Executor Service for callbacks
*/
private final ExecutorService callbacksExecutor;
+ /**
+ * Registered {@link TPInvokable}s
+ */
+ private final HashMap> registeredInvokables = new HashMap<>();
/**
* Internal Gson Serializer/Deserializer
@@ -188,7 +190,7 @@ private Thread createListenerThread() {
TPMessageDeserializer tpMessageDeserializer = new TPMessageDeserializer();
tpMessageDeserializer.registerTPMessageType(ReceivedMessageHelper.TYPE_CLOSE_PLUGIN, TPClosePluginMessage.class);
tpMessageDeserializer.registerTPMessageType(ReceivedMessageHelper.TYPE_INFO, TPInfoMessage.class);
- tpMessageDeserializer.registerTPMessageType(ReceivedMessageHelper.TYPE_LIST_CHANGE, TPListChangeMessage.class);
+ tpMessageDeserializer.registerTPMessageType(ReceivedMessageHelper.TYPE_LIST_CHANGE, TPListChangedMessage.class);
tpMessageDeserializer.registerTPMessageType(ReceivedMessageHelper.TYPE_BROADCAST, TPBroadcastMessage.class);
tpMessageDeserializer.registerTPMessageType(ReceivedMessageHelper.TYPE_SETTINGS, TPSettingsMessage.class);
tpMessageDeserializer.registerTPMessageType(ReceivedMessageHelper.TYPE_ACTION, TPActionMessage.class);
@@ -233,7 +235,7 @@ private void onMessage(String socketMessage) throws SocketException, JsonParseEx
break;
case ReceivedMessageHelper.TYPE_LIST_CHANGE:
- TPListChangeMessage listChangeMessage = (TPListChangeMessage) tpMessage;
+ TPListChangedMessage listChangeMessage = (TPListChangedMessage) tpMessage;
if (this.touchPortalPluginListener != null) {
this.touchPortalPluginListener.onListChanged(listChangeMessage);
}
@@ -320,105 +322,175 @@ private void updateSettingFields(HashMap settings) {
}
private boolean onActionReceived(TPActionMessage tpActionMessage, JsonObject jsonAction, Boolean held) {
- boolean called = false;
+ boolean invoked = false;
if (tpActionMessage.actionId != null && !tpActionMessage.actionId.isEmpty()) {
- Method[] pluginActionMethods = Arrays.stream(this.pluginClass.getDeclaredMethods()).filter(method -> method.isAnnotationPresent(Action.class)).toArray(Method[]::new);
- for (Method method : pluginActionMethods) {
- String methodActionId = ActionHelper.getActionId(this.pluginClass, method);
- if (tpActionMessage.actionId.equals(methodActionId)) {
- try {
- Parameter[] parameters = method.getParameters();
- Object[] arguments = new Object[parameters.length];
- for (int parameterIndex = 0; parameterIndex < parameters.length; parameterIndex++) {
- Parameter parameter = parameters[parameterIndex];
- if (parameter.isAnnotationPresent(Data.class)) {
- arguments[parameterIndex] = tpActionMessage.getTypedDataValue(this.pluginClass, method, parameter);
- }
- else if (parameter.getType().isAssignableFrom(JsonObject.class)) {
- arguments[parameterIndex] = jsonAction;
- }
- else if (parameter.getType().isAssignableFrom(TPActionMessage.class)) {
- arguments[parameterIndex] = tpActionMessage;
- }
- if (arguments[parameterIndex] == null) {
- throw new MethodDataParameterException(method, parameter);
- }
+ if (this.registeredInvokables.containsKey(tpActionMessage.actionId)) {
+ Class extends TPInvokable> invokableClass = this.registeredInvokables.get(tpActionMessage.actionId);
+ try {
+ Class extends TouchPortalPlugin> typedTouchPortalPlugin = (Class extends TouchPortalPlugin>) ((ParameterizedType) invokableClass.getGenericSuperclass()).getActualTypeArguments()[0];
+ Constructor extends TPInvokable> constructor = invokableClass.getConstructor(typedTouchPortalPlugin);
+ TPInvokable tpInvokable = constructor.newInstance(this);
+
+ for (Field declaredField : invokableClass.getDeclaredFields()) {
+ if (declaredField.isAnnotationPresent(Data.class)) {
+ declaredField.setAccessible(true);
+ Object fieldValue = tpActionMessage.getTypedDataValue(this.pluginClass, declaredField);
+ declaredField.set(tpInvokable, fieldValue);
}
- this.heldActionsStates.put(tpActionMessage.actionId, held);
- this.callbacksExecutor.submit(() -> {
- try {
- method.setAccessible(true);
- method.invoke(this, arguments);
- }
- catch (Exception e) {
- TouchPortalPlugin.LOGGER.log(Level.SEVERE, "Action method could not be invoked", e);
- }
- finally {
- if (held == null || !held) {
- this.heldActionsStates.remove(tpActionMessage.actionId);
+ else if (declaredField.getType().isAssignableFrom(JsonObject.class)) {
+ declaredField.setAccessible(true);
+ declaredField.set(tpInvokable, jsonAction);
+ }
+ else if (declaredField.getType().isAssignableFrom(TPActionMessage.class)) {
+ declaredField.setAccessible(true);
+ declaredField.set(tpInvokable, tpActionMessage);
+ }
+ }
+
+ tpInvokable.onInvoke();
+
+ invoked = true;
+ }
+ catch (ReflectiveOperationException e) {
+ TouchPortalPlugin.LOGGER.log(Level.SEVERE, "Action could not be created or invoked", e);
+ }
+ }
+ else {
+ Method[] pluginActionMethods = Arrays.stream(this.pluginClass.getDeclaredMethods()).filter(method -> method.isAnnotationPresent(Action.class)).toArray(Method[]::new);
+ for (Method method : pluginActionMethods) {
+ String methodActionId = ActionHelper.getActionId(this.pluginClass, method);
+ if (tpActionMessage.actionId.equals(methodActionId)) {
+ try {
+ Parameter[] parameters = method.getParameters();
+ Object[] arguments = new Object[parameters.length];
+ for (int parameterIndex = 0; parameterIndex < parameters.length; parameterIndex++) {
+ Parameter parameter = parameters[parameterIndex];
+ if (parameter.isAnnotationPresent(Data.class)) {
+ arguments[parameterIndex] = tpActionMessage.getTypedDataValue(this.pluginClass, method, parameter);
+ }
+ else if (parameter.getType().isAssignableFrom(JsonObject.class)) {
+ arguments[parameterIndex] = jsonAction;
+ }
+ else if (parameter.getType().isAssignableFrom(TPActionMessage.class)) {
+ arguments[parameterIndex] = tpActionMessage;
+ }
+ if (arguments[parameterIndex] == null) {
+ throw new MethodDataParameterException(method, parameter);
}
}
- });
- called = true;
- }
- catch (MethodDataParameterException e) {
- TouchPortalPlugin.LOGGER.log(Level.WARNING, e.getMessage(), e);
+ this.heldActionsStates.put(tpActionMessage.actionId, held);
+ this.callbacksExecutor.submit(() -> {
+ try {
+ method.setAccessible(true);
+ method.invoke(this, arguments);
+ }
+ catch (Exception e) {
+ TouchPortalPlugin.LOGGER.log(Level.SEVERE, "Action method could not be invoked", e);
+ }
+ finally {
+ if (held == null || !held) {
+ this.heldActionsStates.remove(tpActionMessage.actionId);
+ }
+ }
+ });
+ invoked = true;
+ }
+ catch (MethodDataParameterException e) {
+ TouchPortalPlugin.LOGGER.log(Level.WARNING, e.getMessage(), e);
+ }
+ break;
}
- break;
}
}
}
- return called;
+ return invoked;
}
- private boolean onConnectorChangeReceived(TPConnectorChangeMessage tpConnectorChangeMessage, JsonObject jsonAction) {
- boolean called = false;
+ private boolean onConnectorChangeReceived(TPConnectorChangeMessage tpConnectorChangeMessage, JsonObject jsonConnectorChange) {
+ boolean invoked = false;
if (tpConnectorChangeMessage.connectorId != null && !tpConnectorChangeMessage.connectorId.isEmpty()) {
- Method[] pluginConnectorMethods = Arrays.stream(this.pluginClass.getDeclaredMethods()).filter(method -> method.isAnnotationPresent(Connector.class)).toArray(Method[]::new);
- for (Method method : pluginConnectorMethods) {
- String methodConnectorId = ConnectorHelper.getConnectorId(this.pluginClass, method);
- if (tpConnectorChangeMessage.connectorId.equals(methodConnectorId)) {
- try {
- Parameter[] parameters = method.getParameters();
- Object[] arguments = new Object[parameters.length];
- for (int parameterIndex = 0; parameterIndex < parameters.length; parameterIndex++) {
- Parameter parameter = parameters[parameterIndex];
- if (parameter.isAnnotationPresent(Data.class)) {
- arguments[parameterIndex] = tpConnectorChangeMessage.getTypedDataValue(this.pluginClass, method, parameter);
- }
- else if (parameter.isAnnotationPresent(ConnectorValue.class)) {
- arguments[parameterIndex] = tpConnectorChangeMessage.value;
- }
- else if (parameter.getType().isAssignableFrom(JsonObject.class)) {
- arguments[parameterIndex] = jsonAction;
- }
- else if (parameter.getType().isAssignableFrom(TPConnectorChangeMessage.class)) {
- arguments[parameterIndex] = tpConnectorChangeMessage;
- }
- if (arguments[parameterIndex] == null) {
- throw new MethodDataParameterException(method, parameter);
- }
+ if (this.registeredInvokables.containsKey(tpConnectorChangeMessage.connectorId)) {
+ Class extends TPInvokable> invokableClass = this.registeredInvokables.get(tpConnectorChangeMessage.connectorId);
+ try {
+ Class extends TouchPortalPlugin> typedTouchPortalPlugin = (Class extends TouchPortalPlugin>) ((ParameterizedType) invokableClass.getGenericSuperclass()).getActualTypeArguments()[0];
+ Constructor extends TPInvokable> constructor = invokableClass.getConstructor(typedTouchPortalPlugin);
+ TPInvokable tpInvokable = constructor.newInstance(this);
+
+ for (Field declaredField : invokableClass.getDeclaredFields()) {
+ if (declaredField.isAnnotationPresent(Data.class)) {
+ declaredField.setAccessible(true);
+ Object fieldValue = tpConnectorChangeMessage.getTypedDataValue(this.pluginClass, declaredField);
+ declaredField.set(tpInvokable, fieldValue);
+ }
+ else if (declaredField.isAnnotationPresent(ConnectorValue.class)) {
+ declaredField.setAccessible(true);
+ declaredField.set(tpInvokable, tpConnectorChangeMessage.value);
+ }
+ else if (declaredField.getType().isAssignableFrom(JsonObject.class)) {
+ declaredField.setAccessible(true);
+ declaredField.set(tpInvokable, jsonConnectorChange);
+ }
+ else if (declaredField.getType().isAssignableFrom(TPConnectorChangeMessage.class)) {
+ declaredField.setAccessible(true);
+ declaredField.set(tpInvokable, tpConnectorChangeMessage);
}
- this.currentConnectorValues.put(tpConnectorChangeMessage.getConstructedId(), tpConnectorChangeMessage.value);
- this.callbacksExecutor.submit(() -> {
- try {
- method.setAccessible(true);
- method.invoke(this, arguments);
- }
- catch (Exception e) {
- TouchPortalPlugin.LOGGER.log(Level.SEVERE, "Connector method could not be invoked", e);
- }
- });
- called = true;
}
- catch (MethodDataParameterException e) {
- TouchPortalPlugin.LOGGER.log(Level.WARNING, e.getMessage(), e);
+
+ tpInvokable.onInvoke();
+
+ invoked = true;
+ }
+ catch (ReflectiveOperationException e) {
+ TouchPortalPlugin.LOGGER.log(Level.SEVERE, "Action could not be created or invoked", e);
+ }
+ }
+ else {
+ Method[] pluginConnectorMethods = Arrays.stream(this.pluginClass.getDeclaredMethods()).filter(method -> method.isAnnotationPresent(Connector.class)).toArray(Method[]::new);
+ for (Method method : pluginConnectorMethods) {
+ String methodConnectorId = ConnectorHelper.getConnectorId(this.pluginClass, method);
+ if (tpConnectorChangeMessage.connectorId.equals(methodConnectorId)) {
+ try {
+ Parameter[] parameters = method.getParameters();
+ Object[] arguments = new Object[parameters.length];
+ for (int parameterIndex = 0; parameterIndex < parameters.length; parameterIndex++) {
+ Parameter parameter = parameters[parameterIndex];
+ if (parameter.isAnnotationPresent(Data.class)) {
+ arguments[parameterIndex] = tpConnectorChangeMessage.getTypedDataValue(this.pluginClass, method, parameter);
+ }
+ else if (parameter.isAnnotationPresent(ConnectorValue.class)) {
+ arguments[parameterIndex] = tpConnectorChangeMessage.value;
+ }
+ else if (parameter.getType().isAssignableFrom(JsonObject.class)) {
+ arguments[parameterIndex] = jsonConnectorChange;
+ }
+ else if (parameter.getType().isAssignableFrom(TPConnectorChangeMessage.class)) {
+ arguments[parameterIndex] = tpConnectorChangeMessage;
+ }
+ if (arguments[parameterIndex] == null) {
+ throw new MethodDataParameterException(method, parameter);
+ }
+ }
+ this.currentConnectorValues.put(tpConnectorChangeMessage.getConstructedId(), tpConnectorChangeMessage.value);
+ this.callbacksExecutor.submit(() -> {
+ try {
+ method.setAccessible(true);
+ method.invoke(this, arguments);
+ }
+ catch (Exception e) {
+ TouchPortalPlugin.LOGGER.log(Level.SEVERE, "Connector method could not be invoked", e);
+ }
+ });
+ invoked = true;
+ }
+ catch (MethodDataParameterException e) {
+ TouchPortalPlugin.LOGGER.log(Level.WARNING, e.getMessage(), e);
+ }
+ break;
}
- break;
}
}
}
- return called;
+ return invoked;
}
/**
@@ -437,6 +509,16 @@ private boolean sendPair() {
return paired;
}
+ /**
+ * Register a {@link TPAction} or {@link TPConnector}
+ *
+ * @param invokableId String
+ * @param invokableClass Class<{@link TPInvokable}>
+ */
+ protected void registerInvokable(String invokableId, Class extends TPInvokable> invokableClass) {
+ this.registeredInvokables.put(invokableId, invokableClass);
+ }
+
/**
* Get TPInfo
*
@@ -1264,9 +1346,9 @@ public interface TouchPortalPluginListener {
/**
* Called when a List Change Message is received
*
- * @param tpListChangeMessage TPListChangeMessage
+ * @param tpListChangedMessage TPListChangeMessage
*/
- void onListChanged(TPListChangeMessage tpListChangeMessage);
+ void onListChanged(TPListChangedMessage tpListChangedMessage);
/**
* Called when a Broadcast Message is received
diff --git a/Library/src/main/java/com/christophecvb/touchportal/model/TPActionMessage.java b/Library/src/main/java/com/christophecvb/touchportal/model/TPActionMessage.java
index ea6e1f0..2ecf1a4 100644
--- a/Library/src/main/java/com/christophecvb/touchportal/model/TPActionMessage.java
+++ b/Library/src/main/java/com/christophecvb/touchportal/model/TPActionMessage.java
@@ -23,6 +23,7 @@
import com.christophecvb.touchportal.helpers.DataHelper;
import com.christophecvb.touchportal.helpers.ReceivedMessageHelper;
+import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
@@ -41,6 +42,10 @@ public Object getTypedDataValue(Class> pluginClass, Method actionMethod, Param
return this.getTypedDataValue(actionMethodParameter.getParameterizedType().getTypeName(), DataHelper.getDataId(pluginClass, actionMethod, actionMethodParameter));
}
+ public Object getTypedDataValue(Class> pluginClass, Field actionField) {
+ return this.getTypedDataValue(actionField.getType().getTypeName(), DataHelper.getDataId(pluginClass, actionField));
+ }
+
public Object getTypedDataValue(String actionDataType, String actionDataId) {
Object value = null;
diff --git a/Library/src/main/java/com/christophecvb/touchportal/model/TPConnectorChangeMessage.java b/Library/src/main/java/com/christophecvb/touchportal/model/TPConnectorChangeMessage.java
index ae5db53..b865a25 100644
--- a/Library/src/main/java/com/christophecvb/touchportal/model/TPConnectorChangeMessage.java
+++ b/Library/src/main/java/com/christophecvb/touchportal/model/TPConnectorChangeMessage.java
@@ -24,6 +24,7 @@
import com.christophecvb.touchportal.helpers.DataHelper;
import com.christophecvb.touchportal.helpers.ReceivedMessageHelper;
+import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
@@ -44,6 +45,10 @@ public Object getTypedDataValue(Class> pluginClass, Method actionMethod, Param
return this.getTypedDataValue(connectorMethodParameter.getParameterizedType().getTypeName(), DataHelper.getDataId(pluginClass, actionMethod, connectorMethodParameter));
}
+ public Object getTypedDataValue(Class> pluginClass, Field actionField) {
+ return this.getTypedDataValue(actionField.getType().getTypeName(), DataHelper.getDataId(pluginClass, actionField));
+ }
+
public Object getTypedDataValue(String connectorDataType, String connectorDataId) {
Object value = null;
diff --git a/Library/src/main/java/com/christophecvb/touchportal/model/TPListChangeMessage.java b/Library/src/main/java/com/christophecvb/touchportal/model/TPListChangedMessage.java
similarity index 94%
rename from Library/src/main/java/com/christophecvb/touchportal/model/TPListChangeMessage.java
rename to Library/src/main/java/com/christophecvb/touchportal/model/TPListChangedMessage.java
index 83b2c77..f024390 100644
--- a/Library/src/main/java/com/christophecvb/touchportal/model/TPListChangeMessage.java
+++ b/Library/src/main/java/com/christophecvb/touchportal/model/TPListChangedMessage.java
@@ -20,7 +20,7 @@
package com.christophecvb.touchportal.model;
-public class TPListChangeMessage extends TPMessage {
+public class TPListChangedMessage extends TPMessage {
public String pluginId;
public String actionId;
public String listId;
diff --git a/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java b/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java
index b271368..55e2cf3 100644
--- a/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java
+++ b/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java
@@ -71,7 +71,7 @@ public void onInfo(TPInfoMessage tpInfoMessage) {
}
@Override
- public void onListChanged(TPListChangeMessage tpListChangeMessage) {
+ public void onListChanged(TPListChangedMessage tpListChangedMessage) {
}
@Override
diff --git a/Library/src/test/resources/TouchPortalPluginTest/plugin.config b/Library/src/test/resources/TouchPortalPluginTest/plugin.config
index 10fc40b..ec09544 100644
--- a/Library/src/test/resources/TouchPortalPluginTest/plugin.config
+++ b/Library/src/test/resources/TouchPortalPluginTest/plugin.config
@@ -1,4 +1,4 @@
#TouchPortalPluginTest
-#Sat Nov 26 23:11:43 CET 2022
+#Sun Dec 04 22:41:39 CET 2022
samplekey=Sample Value
plugin.version=1
diff --git a/README.md b/README.md
index d06b1ae..2e76fbd 100644
--- a/README.md
+++ b/README.md
@@ -91,7 +91,7 @@ public class MyTouchPortalPlugin extends TouchPortalPlugin implements TouchPorta
/**
* Called when a List Change Message is received
*/
- public void onListChanged(TPListChangeMessage tpListChangeMessage) { }
+ public void onListChanged(TPListChangeMessage tpListChangedMessage) { }
/**
* Called when a Broadcast Message is received
diff --git a/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java b/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
index bdfeca5..14a5a97 100644
--- a/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
+++ b/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
@@ -25,6 +25,8 @@
import com.christophecvb.touchportal.helpers.PluginHelper;
import com.christophecvb.touchportal.helpers.ReceivedMessageHelper;
import com.christophecvb.touchportal.model.*;
+import com.christophecvb.touchportal.samplejava.invokable.action.ExampleClassAction;
+import com.christophecvb.touchportal.samplejava.invokable.connector.ExampleClassConnector;
import com.google.gson.JsonObject;
import java.io.File;
@@ -98,14 +100,23 @@ public static void main(String... args) {
if (PluginHelper.COMMAND_START.equals(args[0])) {
// Initialize the Plugin
TouchPortalSampleJavaPlugin touchPortalSampleJavaPlugin = new TouchPortalSampleJavaPlugin();
+
+ // Register Invokable
+ touchPortalSampleJavaPlugin.registerInvokable(TouchPortalSampleJavaPluginConstants.BaseCategory.Actions.ExampleClassAction.ID, ExampleClassAction.class);
+ touchPortalSampleJavaPlugin.registerInvokable(TouchPortalSampleJavaPluginConstants.BaseCategory.Connectors.ExampleClassConnector.ID, ExampleClassConnector.class);
+
// Load a properties File
touchPortalSampleJavaPlugin.loadProperties("plugin.config");
+
// Get a property
TouchPortalSampleJavaPlugin.LOGGER.log(Level.INFO, touchPortalSampleJavaPlugin.getProperty("samplekey"));
+
// Set a property
touchPortalSampleJavaPlugin.setProperty("samplekey", "Value set from Plugin");
+
// Store the properties
touchPortalSampleJavaPlugin.storeProperties();
+
// Initiate the connection with the Touch Portal Plugin System
boolean connectedPairedAndListening = touchPortalSampleJavaPlugin.connectThenPairAndListen(touchPortalSampleJavaPlugin);
@@ -300,7 +311,7 @@ public void onInfo(TPInfoMessage tpInfoMessage) {
}
@Override
- public void onListChanged(TPListChangeMessage tpListChangeMessage) {
+ public void onListChanged(TPListChangedMessage tpListChangedMessage) {
}
@Override
diff --git a/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/invokable/action/ExampleClassAction.java b/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/invokable/action/ExampleClassAction.java
new file mode 100644
index 0000000..d484e1e
--- /dev/null
+++ b/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/invokable/action/ExampleClassAction.java
@@ -0,0 +1,43 @@
+package com.christophecvb.touchportal.samplejava.invokable.action;
+
+import com.christophecvb.touchportal.TPAction;
+import com.christophecvb.touchportal.TouchPortalPlugin;
+import com.christophecvb.touchportal.annotations.Action;
+import com.christophecvb.touchportal.annotations.ActionTranslation;
+import com.christophecvb.touchportal.annotations.Data;
+import com.christophecvb.touchportal.annotations.Language;
+import com.christophecvb.touchportal.model.TPListChangedMessage;
+import com.christophecvb.touchportal.samplejava.TouchPortalSampleJavaPlugin;
+
+import java.util.logging.Logger;
+
+@Action(
+ name = "Example Class Action",
+ format = "Example Class Action with param {$param$}",
+ categoryId = "BaseCategory"
+)
+@ActionTranslation(
+ language = Language.FRENCH,
+ name = "Exemple d'Action via une Classe",
+ format = "Exemple d'Action via une Classe avec le paramètre {$param$}"
+)
+public class ExampleClassAction extends TPAction {
+ private final static Logger LOGGER = Logger.getLogger(TouchPortalPlugin.class.getName());
+
+ @Data
+ private String param;
+
+ public ExampleClassAction(TouchPortalSampleJavaPlugin touchPortalPlugin) {
+ super(touchPortalPlugin);
+ }
+
+ @Override
+ public void onInvoke() {
+ LOGGER.info("ExampleClassAction.onInvoke this.param=" + this.param);
+ }
+
+ @Override
+ public void onListChanged(TPListChangedMessage tpListChangedMessage) {
+ LOGGER.info("ExampleClassAction.onListChanged");
+ }
+}
diff --git a/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/invokable/connector/ExampleClassConnector.java b/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/invokable/connector/ExampleClassConnector.java
new file mode 100644
index 0000000..8ffc387
--- /dev/null
+++ b/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/invokable/connector/ExampleClassConnector.java
@@ -0,0 +1,39 @@
+package com.christophecvb.touchportal.samplejava.invokable.connector;
+
+import com.christophecvb.touchportal.TPConnector;
+import com.christophecvb.touchportal.TouchPortalPlugin;
+import com.christophecvb.touchportal.annotations.Connector;
+import com.christophecvb.touchportal.annotations.ConnectorValue;
+import com.christophecvb.touchportal.annotations.Data;
+import com.christophecvb.touchportal.model.TPListChangedMessage;
+import com.christophecvb.touchportal.samplejava.TouchPortalSampleJavaPlugin;
+
+import java.util.logging.Logger;
+
+@Connector(
+ name = "Example Class Connector",
+ categoryId = "BaseCategory",
+ format = "Connect Example Class Connector with param {$param$}"
+)
+public class ExampleClassConnector extends TPConnector {
+ private final static Logger LOGGER = Logger.getLogger(TouchPortalPlugin.class.getName());
+
+ @ConnectorValue
+ private Integer value;
+ @Data
+ private String param;
+
+ public ExampleClassConnector(TouchPortalSampleJavaPlugin touchPortalPlugin) {
+ super(touchPortalPlugin);
+ }
+
+ @Override
+ public void onInvoke() {
+ LOGGER.info("Example Class Connector with param=" + this.param + " and value=" + this.value);
+ }
+
+ @Override
+ public void onListChanged(TPListChangedMessage tpListChangedMessage) {
+ LOGGER.info("ExampleClassConnector.onListChanged");
+ }
+}
diff --git a/SampleKotlin/src/main/kotlin/com/christophecvb/touchportal/samplekotlin/TouchPortalSampleKotlinPlugin.kt b/SampleKotlin/src/main/kotlin/com/christophecvb/touchportal/samplekotlin/TouchPortalSampleKotlinPlugin.kt
index 470fa00..d88020c 100644
--- a/SampleKotlin/src/main/kotlin/com/christophecvb/touchportal/samplekotlin/TouchPortalSampleKotlinPlugin.kt
+++ b/SampleKotlin/src/main/kotlin/com/christophecvb/touchportal/samplekotlin/TouchPortalSampleKotlinPlugin.kt
@@ -82,7 +82,7 @@ class TouchPortalSampleKotlinPlugin(parallelizeActions: Boolean) : TouchPortalPl
}
override fun onReceived(jsonMessage: JsonObject) {}
- override fun onListChanged(tpListChangeMessage: TPListChangeMessage) {}
+ override fun onListChanged(tpListChangedMessage: TPListChangedMessage) {}
override fun onInfo(tpInfoMessage: TPInfoMessage) {}
override fun onBroadcast(tpBroadcastMessage: TPBroadcastMessage) {}
override fun onSettings(tpSettingsMessage: TPSettingsMessage) {}
From 00ca01dd90a36e41fce822068a173c80dd4495af Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Thu, 15 Dec 2022 01:56:07 +0100
Subject: [PATCH 31/41] doc: Update Samples and README.md
---
README.md | 58 ++++++++++++-------
.../TouchPortalSampleJavaPlugin.java | 16 +++--
.../TouchPortalSampleKotlinPlugin.kt | 19 +++---
3 files changed, 57 insertions(+), 36 deletions(-)
diff --git a/README.md b/README.md
index 2e76fbd..9a5241f 100644
--- a/README.md
+++ b/README.md
@@ -103,16 +103,15 @@ public class MyTouchPortalPlugin extends TouchPortalPlugin implements TouchPorta
*/
public void onSettings(TPSettingsMessage tpSettingsMessage) { }
- /**
- * Called when a Notification Option Clicked Message is received
- */
- public void onNotificationOptionClicked(TPNotificationOptionClickedMessage tpNotificationOptionClickedMessage) {}
+ /**
+ * Called when a Notification Option Clicked Message is received
+ */
+ public void onNotificationOptionClicked(TPNotificationOptionClickedMessage tpNotificationOptionClickedMessage) { }
}
```
## Development and Interaction
-
-- The SDK will automatically callback your action methods if they only contain `@Data` annotated parameters
+The SDK will automatically invoke your action methods if they contain only `@Data` annotated parameters
```java
public class MyTouchPortalPlugin extends TouchPortalPlugin implements TouchPortalPlugin.TouchPortalPluginListener {
@@ -125,14 +124,14 @@ public class MyTouchPortalPlugin extends TouchPortalPlugin implements TouchPorta
*/
@Action(description = "Long Description of Dummy Action with Data Text", format = "Set text to {$text$}", categoryId = "BaseCategory")
private void actionWithText(@Data String text) {
- TouchPortalSamplePlugin.LOGGER.log(Level.INFO, "Action actionWithText received: " + text);
+ MyTouchPortalPlugin.LOGGER.log(Level.INFO, "Action actionWithText received: " + text);
}
// ...
}
```
-- Otherwise, call your actions manually in the `onReceived(JsonObject jsonMessage)` method
+Otherwise, call your actions manually in the `onReceived(JsonObject jsonMessage)` method
```java
public class MyTouchPortalPlugin extends TouchPortalPlugin implements TouchPortalPlugin.TouchPortalPluginListener {
@@ -157,7 +156,7 @@ public class MyTouchPortalPlugin extends TouchPortalPlugin implements TouchPorta
}
```
-- Don't forget to initialize all your services once you receive the onInfo event. The TPInfoMessage will also contain the initial values of your settings.
+Don't forget to initialize all your services once you receive the onInfo event. The TPInfoMessage will also contain the initial values of your settings.
```java
public class MyTouchPortalPlugin extends TouchPortalPlugin implements TouchPortalPlugin.TouchPortalPluginListener {
@@ -174,7 +173,7 @@ public class MyTouchPortalPlugin extends TouchPortalPlugin implements TouchPorta
}
```
-- Finally, send messages back to TouchPortal when you want to update your states
+Finally, send messages back to TouchPortal when you want to update your states
```java
public class MyTouchPortalPlugin extends TouchPortalPlugin implements TouchPortalPlugin.TouchPortalPluginListener {
@@ -194,16 +193,24 @@ public class MyTouchPortalPlugin extends TouchPortalPlugin implements TouchPorta
}
```
-## Use Annotations to describe your plugin and package it
+## Use Annotations to describe your plugin
+
+The provided Annotations help you in the automatic generation of the `entry.tp` file (necessary for packaging and deployment of your plugin)
+
+Current supported annotations include: Plugin, Category, Action, Data, State, Event and Setting
-- The provided Annotations help you in the automatic generation of the `entry.tp` file (necessary for packaging and deployment of your plugin)
-- Current supported annotations include: Plugin, Category, Action, Data, State, Event and Setting
-- More examples can be found in the sample modules
+More examples can be found in the sample modules
```java
// ...
-@Plugin(version = BuildConfig.VERSION_CODE, colorDark = "#203060", colorLight = "#4070F0", name = "My Touch Portal Plugin")
+@Plugin(
+ name = "My Touch Portal Plugin",
+ version = BuildConfig.VERSION_CODE,
+ colorDark = "#203060",
+ colorLight = "#4070F0",
+ parentCategory = ParentCategory.MISC
+)
public class MyTouchPortalPlugin extends TouchPortalPlugin {
//...
@@ -212,7 +219,11 @@ public class MyTouchPortalPlugin extends TouchPortalPlugin {
*
* @param text String
*/
- @Action(description = "Long Description of Dummy Action with Data", format = "Set text to {$text$}", categoryId = "BaseCategory")
+ @Action(
+ description = "Long Description of Dummy Action with Data",
+ format = "Set text to {$text$}",
+ categoryId = "BaseCategory"
+ )
private void dummyWithData(@Data String text) {
LOGGER.log(Level.Info, "Action dummyWithData received: " + text);
}
@@ -238,13 +249,16 @@ public class MyTouchPortalPlugin extends TouchPortalPlugin {
## Prepackaging
-- Add the Plugin icon and extra resources into the `src/main/resources/` directory of your module
+Add the Plugin icon and extra resources into the `src/main/resources/` directory of your module
-## Build
+## Clean, Build and Package
-- Use the common `gradlew clean` task to clean your build directories.
-- Use the common `gradlew build` task to build your project with the Annotations.
-- Use the `gradlew packagePlugin` task to pack your plugin into a `.tpp` file. Output files will be in your module `build/plugin` directory.
+- Clean Project
+ - `gradlew clean`
+- Build Project
+ - `gradlew build`
+- Package Project
+ - `gradlew packagePlugin` task to pack your plugin into a `.tpp` file. Output files will be in your module's `build/plugin` directory.
## Debugging tips
@@ -259,4 +273,4 @@ public class MyTouchPortalPlugin extends TouchPortalPlugin {
- Main Class: `your.package.YourTouchPortalPlugin`
- Arguments: `start`
- Working Directory: `YourModule/build/plugin/YourTouchPortalPlugin`
-[![Touch Portal Plugin SDK Gradle Application Configuration](https://raw.githubusercontent.com/ChristopheCVB/TouchPortalPluginSDK/master/resources/TP%20Plugin%20SDK%20Gradle%20Application%20Configuration.png)](#debugging-tips)
+![Touch Portal Plugin SDK Gradle Application Configuration](https://raw.githubusercontent.com/ChristopheCVB/TouchPortalPluginSDK/master/resources/TP%20Plugin%20SDK%20Gradle%20Application%20Configuration.png)
diff --git a/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java b/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
index 14a5a97..c7f15fc 100644
--- a/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
+++ b/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
@@ -33,8 +33,13 @@
import java.util.logging.Level;
import java.util.logging.Logger;
-@SuppressWarnings("unused")
-@Plugin(version = BuildConfig.VERSION_CODE, colorDark = "#203060", colorLight = "#4070F0", name = "Touch Portal Plugin Example", parentCategory = ParentCategory.CONTENT)
+@Plugin(
+ version = BuildConfig.VERSION_CODE,
+ colorDark = "#203060",
+ colorLight = "#4070F0",
+ name = BuildConfig.NAME,
+ parentCategory = ParentCategory.CONTENT
+)
public class TouchPortalSampleJavaPlugin extends TouchPortalPlugin implements TouchPortalPlugin.TouchPortalPluginListener {
/**
* Logger
@@ -80,7 +85,7 @@ private enum Categories {
* Setting of type number definition example
*/
@Setting(name = "Update Delay", defaultValue = "10", minValue = 10, maxValue = 30)
- private int updateDelaySetting;
+ private int updateDelaySetting = 10;
/**
* Setting of type String and is read only definition example
@@ -122,7 +127,7 @@ public static void main(String... args) {
if (connectedPairedAndListening) {
// Update a State with the ID from the Generated Constants Class
- boolean stateUpdated = touchPortalSampleJavaPlugin.sendStateUpdate(TouchPortalSampleJavaPluginConstants.BaseCategory.States.CustomStateWithEvent.ID, "2");
+ touchPortalSampleJavaPlugin.sendStateUpdate(TouchPortalSampleJavaPluginConstants.BaseCategory.States.CustomStateWithEvent.ID, "2");
// Create a new State
touchPortalSampleJavaPlugin.sendCreateState("BaseCategory", "createdState1", "Created State 01", System.currentTimeMillis() + "1");
@@ -147,7 +152,8 @@ public static void main(String... args) {
touchPortalSampleJavaPlugin.sendConnectorUpdate(TouchPortalSampleJavaPluginConstants.ID, TouchPortalSampleJavaPluginConstants.BaseCategory.Connectors.ConnectorSimple.ID, 90, null);
try {
Thread.sleep(1000);
- } catch (InterruptedException ignored) {}
+ } catch (InterruptedException ignored) {
+ }
touchPortalSampleJavaPlugin.sendConnectorUpdate(TouchPortalSampleJavaPluginConstants.ID, TouchPortalSampleJavaPluginConstants.BaseCategory.Connectors.ConnectorSimple.ID, 50, null);
}
}
diff --git a/SampleKotlin/src/main/kotlin/com/christophecvb/touchportal/samplekotlin/TouchPortalSampleKotlinPlugin.kt b/SampleKotlin/src/main/kotlin/com/christophecvb/touchportal/samplekotlin/TouchPortalSampleKotlinPlugin.kt
index d88020c..7e23c6c 100644
--- a/SampleKotlin/src/main/kotlin/com/christophecvb/touchportal/samplekotlin/TouchPortalSampleKotlinPlugin.kt
+++ b/SampleKotlin/src/main/kotlin/com/christophecvb/touchportal/samplekotlin/TouchPortalSampleKotlinPlugin.kt
@@ -20,25 +20,27 @@
package com.christophecvb.touchportal.samplekotlin
-import com.christophecvb.touchportal.annotations.Action
-import com.christophecvb.touchportal.annotations.Category
-import com.christophecvb.touchportal.annotations.Plugin
import com.christophecvb.touchportal.helpers.PluginHelper
import com.christophecvb.touchportal.TouchPortalPlugin
-import com.christophecvb.touchportal.annotations.Data
+import com.christophecvb.touchportal.annotations.*
import com.christophecvb.touchportal.model.*
import com.google.gson.JsonObject
import java.util.logging.Level
import java.util.logging.Logger
import kotlin.system.exitProcess
-@Suppress("unused")
-@Plugin(version = BuildConfig.VERSION_CODE, colorDark = "#556677", colorLight = "#112233")
+@Plugin(
+ name = BuildConfig.NAME,
+ version = BuildConfig.VERSION_CODE,
+ colorDark = "#556677",
+ colorLight = "#112233",
+ parentCategory = ParentCategory.MISC
+)
class TouchPortalSampleKotlinPlugin(parallelizeActions: Boolean) : TouchPortalPlugin(parallelizeActions), TouchPortalPlugin.TouchPortalPluginListener {
companion object {
/**
- * Logger
+ * Logger used within the plugin
*/
private val LOGGER = Logger.getLogger(TouchPortalPlugin::class.java.name)
@@ -51,7 +53,7 @@ class TouchPortalSampleKotlinPlugin(parallelizeActions: Boolean) : TouchPortalPl
// Initiate the connection with the Touch Portal Plugin System
val connectedPairedAndListening = touchPortalSampleKotlinPlugin.connectThenPairAndListen(touchPortalSampleKotlinPlugin)
- @Suppress("ControlFlowWithEmptyBody")
+
if (connectedPairedAndListening) {
// Let's go!
LOGGER.log(Level.INFO, "Plugin with ID[${TouchPortalSampleKotlinPluginConstants.ID}] Connected and Paired!")
@@ -61,7 +63,6 @@ class TouchPortalSampleKotlinPlugin(parallelizeActions: Boolean) : TouchPortalPl
}
}
- @Suppress("unused")
enum class Categories {
@Category(imagePath = "images/icon-24.png")
BaseCategory
From e775dcec812fee4b5416eaf7279524ff7e8fd959 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Fri, 16 Dec 2022 01:17:44 +0100
Subject: [PATCH 32/41] core: Call TPInvokable.onInvoke from callbacksExecutor
---
.../touchportal/TouchPortalPlugin.java | 33 ++++++++++++++++---
README.md | 2 +-
2 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java b/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
index def900f..1a75cd0 100644
--- a/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
+++ b/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
@@ -347,12 +347,25 @@ else if (declaredField.getType().isAssignableFrom(TPActionMessage.class)) {
}
}
- tpInvokable.onInvoke();
+ this.heldActionsStates.put(tpActionMessage.actionId, held);
+ this.callbacksExecutor.submit(() -> {
+ try {
+ tpInvokable.onInvoke();
+ }
+ catch (Exception e) {
+ TouchPortalPlugin.LOGGER.log(Level.SEVERE, "Action could not be invoked", e);
+ }
+ finally {
+ if (held == null || !held) {
+ this.heldActionsStates.remove(tpActionMessage.actionId);
+ }
+ }
+ });
invoked = true;
}
catch (ReflectiveOperationException e) {
- TouchPortalPlugin.LOGGER.log(Level.SEVERE, "Action could not be created or invoked", e);
+ TouchPortalPlugin.LOGGER.log(Level.WARNING, "Action could not be instanced", e);
}
}
else {
@@ -396,7 +409,7 @@ else if (parameter.getType().isAssignableFrom(TPActionMessage.class)) {
invoked = true;
}
catch (MethodDataParameterException e) {
- TouchPortalPlugin.LOGGER.log(Level.WARNING, e.getMessage(), e);
+ TouchPortalPlugin.LOGGER.log(Level.WARNING, "Action method data parameters could not be retrieved", e);
}
break;
}
@@ -436,12 +449,20 @@ else if (declaredField.getType().isAssignableFrom(TPConnectorChangeMessage.class
}
}
- tpInvokable.onInvoke();
+ this.currentConnectorValues.put(tpConnectorChangeMessage.getConstructedId(), tpConnectorChangeMessage.value);
+ this.callbacksExecutor.submit(() -> {
+ try {
+ tpInvokable.onInvoke();
+ }
+ catch (Exception e) {
+ TouchPortalPlugin.LOGGER.log(Level.SEVERE, "Connector could not be invoked", e);
+ }
+ });
invoked = true;
}
catch (ReflectiveOperationException e) {
- TouchPortalPlugin.LOGGER.log(Level.SEVERE, "Action could not be created or invoked", e);
+ TouchPortalPlugin.LOGGER.log(Level.WARNING, "Connector could not be created or invoked", e);
}
}
else {
@@ -470,6 +491,7 @@ else if (parameter.getType().isAssignableFrom(TPConnectorChangeMessage.class)) {
throw new MethodDataParameterException(method, parameter);
}
}
+
this.currentConnectorValues.put(tpConnectorChangeMessage.getConstructedId(), tpConnectorChangeMessage.value);
this.callbacksExecutor.submit(() -> {
try {
@@ -480,6 +502,7 @@ else if (parameter.getType().isAssignableFrom(TPConnectorChangeMessage.class)) {
TouchPortalPlugin.LOGGER.log(Level.SEVERE, "Connector method could not be invoked", e);
}
});
+
invoked = true;
}
catch (MethodDataParameterException e) {
diff --git a/README.md b/README.md
index 9a5241f..6445d72 100644
--- a/README.md
+++ b/README.md
@@ -164,7 +164,7 @@ public class MyTouchPortalPlugin extends TouchPortalPlugin implements TouchPorta
public void onInfo(TPInfoMessage tpInfoMessage) {
// TPInfoMessage will contain the initial settings stored by TP
- // -> Note that your annotated Settings fields will be up to date at this point
+ // -> Note that your annotated Settings fields will be up-to-date at this point
// continue plugin initialization
}
From d7f8526051577c49189f393900b100077ccf4d23 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Tue, 20 Dec 2022 02:05:07 +0100
Subject: [PATCH 33/41] core: TPInvokable.onListChanged core: Use
callbacksExecutor
---
.../helpers/ReceivedMessageHelper.java | 4 +-
.../touchportal/TouchPortalPlugin.java | 59 ++++++++++++++-----
.../touchportal/test/LibraryTests.java | 4 +-
3 files changed, 48 insertions(+), 19 deletions(-)
diff --git a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/ReceivedMessageHelper.java b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/ReceivedMessageHelper.java
index 2af3ced..b6e7c96 100644
--- a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/ReceivedMessageHelper.java
+++ b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/ReceivedMessageHelper.java
@@ -40,7 +40,7 @@ public class ReceivedMessageHelper {
public static final String TYPE_CONNECTOR_CHANGE = "connectorChange";
public static final String TYPE_SHORT_CONNECTOR_ID_NOTIFICATION = "shortConnectorIdNotification";
public static final String TYPE_INFO = "info";
- public static final String TYPE_LIST_CHANGE = "listChange";
+ public static final String TYPE_LIST_CHANGED = "listChange";
public static final String TYPE_CLOSE_PLUGIN = "closePlugin";
public static final String TYPE_BROADCAST = "broadcast";
public static final String TYPE_SETTINGS = "settings";
@@ -87,7 +87,7 @@ public static boolean isTypeAction(JsonObject jsonMessage) {
* @return boolean isMessageAListChange
*/
public static boolean isTypeListChange(JsonObject jsonMessage) {
- return ReceivedMessageHelper.TYPE_LIST_CHANGE.equals(ReceivedMessageHelper.getType(jsonMessage));
+ return ReceivedMessageHelper.TYPE_LIST_CHANGED.equals(ReceivedMessageHelper.getType(jsonMessage));
}
/**
diff --git a/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java b/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
index 1a75cd0..700c690 100644
--- a/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
+++ b/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
@@ -26,6 +26,7 @@
import com.christophecvb.touchportal.model.deserializer.TPMessageDeserializer;
import com.google.gson.*;
import okhttp3.*;
+import org.jetbrains.annotations.NotNull;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
@@ -190,7 +191,7 @@ private Thread createListenerThread() {
TPMessageDeserializer tpMessageDeserializer = new TPMessageDeserializer();
tpMessageDeserializer.registerTPMessageType(ReceivedMessageHelper.TYPE_CLOSE_PLUGIN, TPClosePluginMessage.class);
tpMessageDeserializer.registerTPMessageType(ReceivedMessageHelper.TYPE_INFO, TPInfoMessage.class);
- tpMessageDeserializer.registerTPMessageType(ReceivedMessageHelper.TYPE_LIST_CHANGE, TPListChangedMessage.class);
+ tpMessageDeserializer.registerTPMessageType(ReceivedMessageHelper.TYPE_LIST_CHANGED, TPListChangedMessage.class);
tpMessageDeserializer.registerTPMessageType(ReceivedMessageHelper.TYPE_BROADCAST, TPBroadcastMessage.class);
tpMessageDeserializer.registerTPMessageType(ReceivedMessageHelper.TYPE_SETTINGS, TPSettingsMessage.class);
tpMessageDeserializer.registerTPMessageType(ReceivedMessageHelper.TYPE_ACTION, TPActionMessage.class);
@@ -230,21 +231,40 @@ private void onMessage(String socketMessage) throws SocketException, JsonParseEx
this.updateSettingFields(this.tpInfoMessage.settings);
if (this.touchPortalPluginListener != null) {
- this.touchPortalPluginListener.onInfo(this.tpInfoMessage);
+ this.callbacksExecutor.submit(() -> {
+ this.touchPortalPluginListener.onInfo(this.tpInfoMessage);
+ });
}
break;
- case ReceivedMessageHelper.TYPE_LIST_CHANGE:
- TPListChangedMessage listChangeMessage = (TPListChangedMessage) tpMessage;
+ case ReceivedMessageHelper.TYPE_LIST_CHANGED:
+ TPListChangedMessage tpListChangedMessage = (TPListChangedMessage) tpMessage;
+ if (this.registeredInvokables.containsKey(tpListChangedMessage.actionId)) {
+ Class extends TPInvokable> invokableClass = this.registeredInvokables.get(tpListChangedMessage.actionId);
+ try {
+ TPInvokable tpInvokable = this.instantiateTPInvokable(invokableClass);
+
+ this.callbacksExecutor.submit(() -> {
+ tpInvokable.onListChanged(tpListChangedMessage);
+ });
+ }
+ catch (ReflectiveOperationException e) {
+ TouchPortalPlugin.LOGGER.log(Level.WARNING, "Invokable could not be created or its onListChanged could not be invoked", e);
+ }
+ }
if (this.touchPortalPluginListener != null) {
- this.touchPortalPluginListener.onListChanged(listChangeMessage);
+ this.callbacksExecutor.submit(() -> {
+ this.touchPortalPluginListener.onListChanged(tpListChangedMessage);
+ });
}
break;
case ReceivedMessageHelper.TYPE_BROADCAST:
TPBroadcastMessage tpBroadcastMessage = (TPBroadcastMessage) tpMessage;
if (this.touchPortalPluginListener != null) {
- this.touchPortalPluginListener.onBroadcast(tpBroadcastMessage);
+ this.callbacksExecutor.submit(() -> {
+ this.touchPortalPluginListener.onBroadcast(tpBroadcastMessage);
+ });
}
break;
@@ -254,14 +274,18 @@ private void onMessage(String socketMessage) throws SocketException, JsonParseEx
this.updateSettingFields(tpSettingsMessage.settings);
if (this.touchPortalPluginListener != null) {
- this.touchPortalPluginListener.onSettings(tpSettingsMessage);
+ this.callbacksExecutor.submit(() -> {
+ this.touchPortalPluginListener.onSettings(tpSettingsMessage);
+ });
}
break;
case ReceivedMessageHelper.TYPE_NOTIFICATION_OPTION_CLICKED:
TPNotificationOptionClickedMessage tpNotificationOptionClickedMessage = (TPNotificationOptionClickedMessage) tpMessage;
if (this.touchPortalPluginListener != null) {
- this.touchPortalPluginListener.onNotificationOptionClicked(tpNotificationOptionClickedMessage);
+ this.callbacksExecutor.submit(() -> {
+ this.touchPortalPluginListener.onNotificationOptionClicked(tpNotificationOptionClickedMessage);
+ });
}
break;
@@ -293,7 +317,9 @@ private void onMessage(String socketMessage) throws SocketException, JsonParseEx
}
if (!called) {
if (this.touchPortalPluginListener != null) {
- this.touchPortalPluginListener.onReceived(jsonMessage);
+ this.callbacksExecutor.submit(() -> {
+ this.touchPortalPluginListener.onReceived(jsonMessage);
+ });
}
}
}
@@ -303,6 +329,13 @@ private void onMessage(String socketMessage) throws SocketException, JsonParseEx
}
}
+ private TPInvokable instantiateTPInvokable(Class extends TPInvokable> invokableClass) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
+ Class extends TouchPortalPlugin> typedTouchPortalPlugin = (Class extends TouchPortalPlugin>) ((ParameterizedType) invokableClass.getGenericSuperclass()).getActualTypeArguments()[0];
+ Constructor extends TPInvokable> constructor = invokableClass.getConstructor(typedTouchPortalPlugin);
+ TPInvokable tpInvokable = constructor.newInstance(this);
+ return tpInvokable;
+ }
+
private void updateSettingFields(HashMap settings) {
Field[] pluginSettingFields = Arrays.stream(this.pluginClass.getDeclaredFields()).filter(field -> field.isAnnotationPresent(Setting.class)).toArray(Field[]::new);
for (String settingName : settings.keySet()) {
@@ -327,9 +360,7 @@ private boolean onActionReceived(TPActionMessage tpActionMessage, JsonObject jso
if (this.registeredInvokables.containsKey(tpActionMessage.actionId)) {
Class extends TPInvokable> invokableClass = this.registeredInvokables.get(tpActionMessage.actionId);
try {
- Class extends TouchPortalPlugin> typedTouchPortalPlugin = (Class extends TouchPortalPlugin>) ((ParameterizedType) invokableClass.getGenericSuperclass()).getActualTypeArguments()[0];
- Constructor extends TPInvokable> constructor = invokableClass.getConstructor(typedTouchPortalPlugin);
- TPInvokable tpInvokable = constructor.newInstance(this);
+ TPInvokable tpInvokable = this.instantiateTPInvokable(invokableClass);
for (Field declaredField : invokableClass.getDeclaredFields()) {
if (declaredField.isAnnotationPresent(Data.class)) {
@@ -425,9 +456,7 @@ private boolean onConnectorChangeReceived(TPConnectorChangeMessage tpConnectorCh
if (this.registeredInvokables.containsKey(tpConnectorChangeMessage.connectorId)) {
Class extends TPInvokable> invokableClass = this.registeredInvokables.get(tpConnectorChangeMessage.connectorId);
try {
- Class extends TouchPortalPlugin> typedTouchPortalPlugin = (Class extends TouchPortalPlugin>) ((ParameterizedType) invokableClass.getGenericSuperclass()).getActualTypeArguments()[0];
- Constructor extends TPInvokable> constructor = invokableClass.getConstructor(typedTouchPortalPlugin);
- TPInvokable tpInvokable = constructor.newInstance(this);
+ TPInvokable tpInvokable = this.instantiateTPInvokable(invokableClass);
for (Field declaredField : invokableClass.getDeclaredFields()) {
if (declaredField.isAnnotationPresent(Data.class)) {
diff --git a/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java b/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java
index 55e2cf3..d71df95 100644
--- a/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java
+++ b/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java
@@ -734,7 +734,7 @@ public void testReceiveListChange() throws IOException, InterruptedException {
LOGGER.log(Level.FINE, "Now");
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
- jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_LIST_CHANGE);
+ jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_LIST_CHANGED);
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
@@ -751,7 +751,7 @@ public void testReceiveListChangeNoListener() throws IOException, InterruptedExc
this.touchPortalPluginTest.connectThenPairAndListen(null);
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty(ReceivedMessageHelper.PLUGIN_ID, TouchPortalPluginTestConstants.ID);
- jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_LIST_CHANGE);
+ jsonMessage.addProperty(ReceivedMessageHelper.TYPE, ReceivedMessageHelper.TYPE_LIST_CHANGED);
PrintWriter out = new PrintWriter(this.serverSocketClient.getOutputStream(), true);
out.println(jsonMessage);
From 2135ebbe10d51d5cee2fb6c78c3170f611c8ff1d Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Tue, 20 Dec 2022 16:11:26 +0100
Subject: [PATCH 34/41] core: Revert to System Java instalation
---
.../com/christophecvb/touchportal/helpers/PluginHelper.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
index 66febb3..34a590c 100644
--- a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
+++ b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
@@ -59,7 +59,7 @@ public class PluginHelper {
/**
* Touch Portal Plugin System TP_JAVA_FILE
*/
- public static final String TP_JAVA = "%TP_JAVA_FILE%";
+ public static final String TP_JAVA = "java";
/**
* Touch Portal entry file
*/
From 5c77140b19cd01d07d1b92d22869a6225eeb0f2f Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Tue, 20 Dec 2022 17:05:50 +0100
Subject: [PATCH 35/41] core: Revert to System Java instalation
---
.../annotations/processor/PluginProcessor.java | 8 ++++----
.../christophecvb/touchportal/helpers/PluginHelper.java | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java
index eb5182b..7ddbbdc 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java
@@ -44,10 +44,10 @@ public static Pair process(TouchPortalPluginAnnota
jsonConfiguration.addProperty(PluginHelper.CONFIGURATION_COLOR_LIGHT, plugin.colorLight());
jsonConfiguration.addProperty(PluginHelper.CONFIGURATION_PARENT_CATEGORY, plugin.parentCategory().getKey());
jsonPlugin.add(PluginHelper.CONFIGURATION, jsonConfiguration);
- jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND, PluginHelper.TP_JAVA + " -Dapple.awt.UIElement=true -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
- jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND + PluginHelper.PLUGIN_START_COMMAND_SUFFIX_WIN, PluginHelper.TP_JAVA + " -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
- jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND + PluginHelper.PLUGIN_START_COMMAND_SUFFIX_MACOS, PluginHelper.TP_JAVA + " -Dapple.awt.UIElement=true -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
- jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND + PluginHelper.PLUGIN_START_COMMAND_SUFFIX_LINUX, PluginHelper.TP_JAVA + " -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
+ jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND, "java -Dapple.awt.UIElement=true -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
+ jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND + PluginHelper.PLUGIN_START_COMMAND_SUFFIX_WIN, "java -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
+ jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND + PluginHelper.PLUGIN_START_COMMAND_SUFFIX_MACOS, "java -Dapple.awt.UIElement=true -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
+ jsonPlugin.addProperty(PluginHelper.PLUGIN_START_COMMAND + PluginHelper.PLUGIN_START_COMMAND_SUFFIX_LINUX, "java -jar ./" + pluginElement.getSimpleName() + ".jar " + PluginHelper.COMMAND_START);
TypeSpec.Builder settingsTypeSpecBuilder = TypeSpec.classBuilder("Settings").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
JsonArray jsonSettings = new JsonArray();
diff --git a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
index 34a590c..66febb3 100644
--- a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
+++ b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
@@ -59,7 +59,7 @@ public class PluginHelper {
/**
* Touch Portal Plugin System TP_JAVA_FILE
*/
- public static final String TP_JAVA = "java";
+ public static final String TP_JAVA = "%TP_JAVA_FILE%";
/**
* Touch Portal entry file
*/
From ee1d08995c2f21b2784968a9caa20e14612cd303 Mon Sep 17 00:00:00 2001
From: Christophe Carvalho Vilas-Boas
Date: Tue, 20 Dec 2022 17:41:19 +0100
Subject: [PATCH 36/41] core: 9.0.0
---
build.gradle | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/build.gradle b/build.gradle
index 0d0f82d..8bff204 100644
--- a/build.gradle
+++ b/build.gradle
@@ -4,8 +4,8 @@ allprojects {
}
}
-ext.versionMajor = 8
-ext.versionMinor = 4
+ext.versionMajor = 9
+ext.versionMinor = 0
ext.versionPatch = 0
ext.isRelease = System.getenv('IS_RELEASE') == 'YES'
From 170d48323f307078cba247fbe2d5cba1f4622f2b Mon Sep 17 00:00:00 2001
From: Pjiesco <55349095+Pjiesco@users.noreply.github.com>
Date: Fri, 6 Oct 2023 14:13:04 +0200
Subject: [PATCH 37/41] Feat: TriggerEvent (#63)
---
.../helpers/SentMessageHelper.java | 3 ++
.../touchportal/TouchPortalPlugin.java | 31 ++++++++++++++++++-
.../touchportal/test/LibraryTests.java | 13 ++++++++
.../TouchPortalSampleJavaPlugin.java | 6 ++++
4 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/SentMessageHelper.java b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/SentMessageHelper.java
index a852b12..bfb1339 100644
--- a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/SentMessageHelper.java
+++ b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/SentMessageHelper.java
@@ -34,6 +34,7 @@ public class SentMessageHelper {
public static final String TYPE_SETTING_UPDATE = "settingUpdate";
public static final String TYPE_SHOW_NOTIFICATION = "showNotification";
public static final String TYPE_CONNECTOR_UPDATE = "connectorUpdate";
+ public static final String TYPE_TRIGGER_EVENT = "triggerEvent";
public static final String INSTANCE_ID = "instanceId";
public static final String ID = GenericHelper.ID;
public static final String VALUE = GenericHelper.VALUE;
@@ -48,5 +49,7 @@ public class SentMessageHelper {
public static final String CONNECTOR_ID = "connectorId";
public static final String SHORT_ID = "shortId";
public static final String PARENT_GROUP = "parentGroup";
+ public static final String EVENT_ID = "eventId";
+ public static final String STATES = "states";
}
\ No newline at end of file
diff --git a/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java b/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
index 700c690..9ba6233 100644
--- a/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
+++ b/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
@@ -26,7 +26,6 @@
import com.christophecvb.touchportal.model.deserializer.TPMessageDeserializer;
import com.google.gson.*;
import okhttp3.*;
-import org.jetbrains.annotations.NotNull;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
@@ -1050,6 +1049,36 @@ public boolean sendShowNotification(String notificationId, String title, String
return sent;
}
+ /**
+ * Send a Trigger Event message to the Touch Portal Plugin System
+ *
+ * @param eventId String
+ * @param states Map<String, Object> Key value pair of state id and value
+ * @return Boolean sent
+ */
+ public boolean sendTriggerEvent(String eventId, Map states) {
+ boolean sent = false;
+ if (eventId != null && !eventId.isEmpty()) {
+ JsonObject triggerEventMessage = new JsonObject();
+ triggerEventMessage.addProperty(SentMessageHelper.TYPE, SentMessageHelper.TYPE_TRIGGER_EVENT);
+ triggerEventMessage.addProperty(SentMessageHelper.EVENT_ID, eventId);
+
+ if (states != null && !states.isEmpty()) {
+ JsonObject jsonStates = new JsonObject();
+
+ states.forEach((id, value) -> {
+ jsonStates.addProperty(id, String.valueOf(value));
+ });
+ triggerEventMessage.add(SentMessageHelper.STATES, jsonStates);
+ }
+
+ sent = this.send(triggerEventMessage);
+ TouchPortalPlugin.LOGGER.info("Trigger Event [" + eventId + "] Sent [" + sent + "]");
+ }
+
+ return sent;
+ }
+
/**
* Send a Connector Update Message to the Touch Portal Plugin System
*
diff --git a/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java b/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java
index d71df95..dc16d5a 100644
--- a/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java
+++ b/Library/src/test/java/com/christophecvb/touchportal/test/LibraryTests.java
@@ -395,6 +395,19 @@ public void testSendFail() {
assertFalse(this.touchPortalPluginTest.sendRemoveState("BaseCategory", "StateId"));
}
+ @Test
+ public void testTriggerEvent() {
+ LOGGER.log(Level.FINE, "Now");
+ assertFalse(this.touchPortalPluginTest.sendTriggerEvent(null, null));
+ assertFalse(this.touchPortalPluginTest.sendTriggerEvent("", null));
+
+ assertTrue(this.touchPortalPluginTest.sendTriggerEvent(TouchPortalPluginTestConstants.BaseCategory.Events.CustomState.ID, null));
+
+ HashMap states = new HashMap<>();
+ states.put(TouchPortalPluginTestConstants.BaseCategory.States.CustomState.ID, "StateValue");
+ assertTrue(this.touchPortalPluginTest.sendTriggerEvent(TouchPortalPluginTestConstants.BaseCategory.Events.CustomState.ID, states));
+ }
+
@Test
public void testReceiveActionNoId() throws IOException, InterruptedException {
LOGGER.log(Level.FINE, "Now");
diff --git a/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java b/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
index c7f15fc..2737b69 100644
--- a/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
+++ b/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
@@ -30,6 +30,8 @@
import com.google.gson.JsonObject;
import java.io.File;
+import java.util.HashMap;
+import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -155,6 +157,10 @@ public static void main(String... args) {
} catch (InterruptedException ignored) {
}
touchPortalSampleJavaPlugin.sendConnectorUpdate(TouchPortalSampleJavaPluginConstants.ID, TouchPortalSampleJavaPluginConstants.BaseCategory.Connectors.ConnectorSimple.ID, 50, null);
+
+ HashMap states = new HashMap<>();
+ states.put(TouchPortalSampleJavaPluginConstants.BaseCategory.States.CustomStateWithEvent.ID, "Value");
+ touchPortalSampleJavaPlugin.sendTriggerEvent(TouchPortalSampleJavaPluginConstants.BaseCategory.Events.CustomStateWithEvent.ID, states);
}
}
}
From 1964ce0f9cea3af972386b3c4233c986e3d757f1 Mon Sep 17 00:00:00 2001
From: Pjiesco <55349095+Pjiesco@users.noreply.github.com>
Date: Fri, 6 Oct 2023 14:14:49 +0200
Subject: [PATCH 38/41] Feat: forceUpdate (#64)
Co-authored-by: Christophe Carvalho Vilas-Boas
---
.../com/christophecvb/touchportal/helpers/SentMessageHelper.java | 1 +
.../java/com/christophecvb/touchportal/TouchPortalPlugin.java | 1 +
2 files changed, 2 insertions(+)
diff --git a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/SentMessageHelper.java b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/SentMessageHelper.java
index bfb1339..afa854a 100644
--- a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/SentMessageHelper.java
+++ b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/SentMessageHelper.java
@@ -49,6 +49,7 @@ public class SentMessageHelper {
public static final String CONNECTOR_ID = "connectorId";
public static final String SHORT_ID = "shortId";
public static final String PARENT_GROUP = "parentGroup";
+ public static final String FORCE_UPDATE = "forceUpdate";
public static final String EVENT_ID = "eventId";
public static final String STATES = "states";
diff --git a/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java b/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
index 9ba6233..7beec98 100644
--- a/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
+++ b/Library/src/main/java/com/christophecvb/touchportal/TouchPortalPlugin.java
@@ -904,6 +904,7 @@ public boolean sendCreateState(String categoryId, String stateId, String parentG
createStateMessage.addProperty(SentMessageHelper.ID, stateId);
createStateMessage.addProperty(SentMessageHelper.DESCRIPTION, description);
createStateMessage.addProperty(SentMessageHelper.DEFAULT_VALUE, valueStr);
+ createStateMessage.addProperty(SentMessageHelper.FORCE_UPDATE, true);
if (parentGroup == null || parentGroup.isEmpty()) {
classLoop:
for (Class> subClass : this.pluginClass.getDeclaredClasses()) {
From cc5c91577aa8ec79dec329249b7971c34f5a9be7 Mon Sep 17 00:00:00 2001
From: Pjiesco <55349095+Pjiesco@users.noreply.github.com>
Date: Fri, 6 Oct 2023 16:56:03 +0200
Subject: [PATCH 39/41] Change `sdk` to `api` (#66)
---
.../touchportal/annotations/processor/PluginProcessor.java | 2 +-
.../com/christophecvb/touchportal/helpers/PluginHelper.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java
index 7ddbbdc..f68dcde 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/PluginProcessor.java
@@ -35,7 +35,7 @@ public static Pair process(TouchPortalPluginAnnota
TypeSpec.Builder pluginTypeSpecBuilder = SpecUtils.createPluginTypeSpecBuilder(pluginElement, plugin);
JsonObject jsonPlugin = new JsonObject();
- jsonPlugin.addProperty(PluginHelper.SDK, PluginHelper.TOUCH_PORTAL_PLUGIN_VERSION);
+ jsonPlugin.addProperty(PluginHelper.API, PluginHelper.TOUCH_PORTAL_PLUGIN_VERSION);
jsonPlugin.addProperty(PluginHelper.VERSION, plugin.version());
jsonPlugin.addProperty(PluginHelper.NAME, PluginHelper.getPluginName(pluginElement, plugin));
jsonPlugin.addProperty(PluginHelper.ID, PluginHelper.getPluginId(pluginElement));
diff --git a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
index 66febb3..fc777ec 100644
--- a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
+++ b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/PluginHelper.java
@@ -29,7 +29,7 @@
* Touch Portal Plugin Plugin Helper
*/
public class PluginHelper {
- public static final String SDK = "sdk";
+ public static final String API = "api";
public static final String VERSION = "version";
public static final String NAME = GenericHelper.NAME;
public static final String ID = GenericHelper.ID;
From ca95a1ffb65c8cd4a7a6db66b8774fded83f72b0 Mon Sep 17 00:00:00 2001
From: "lgtm-com[bot]" <43144390+lgtm-com[bot]@users.noreply.github.com>
Date: Fri, 6 Oct 2023 17:14:48 +0200
Subject: [PATCH 40/41] Add CodeQL workflow for GitHub code scanning (#53)
Co-authored-by: LGTM Migrator
---
.github/workflows/codeql.yml | 41 ++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
create mode 100644 .github/workflows/codeql.yml
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
new file mode 100644
index 0000000..2e7379e
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,41 @@
+name: "CodeQL"
+
+on:
+ push:
+ branches: [ "master", "develop" ]
+ pull_request:
+ branches: [ "master" ]
+ schedule:
+ - cron: "28 7 * * 6"
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: [ java ]
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v2
+ with:
+ languages: ${{ matrix.language }}
+ queries: +security-and-quality
+
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v2
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v2
+ with:
+ category: "/language:${{ matrix.language }}"
From b034dd9421ccc5c8de22daddf070ca9ebf9d5f77 Mon Sep 17 00:00:00 2001
From: Pjiesco <55349095+Pjiesco@users.noreply.github.com>
Date: Thu, 26 Oct 2023 09:30:31 +0200
Subject: [PATCH 41/41] [API 7] Setting Tooltip (#65)
* Feat: Setting Tooltip
* fix: use java 8
* Remove empty lines
* Check if empty
* use UpperCamelCase instead of Full uppercase
* Check if empty
---
.../touchportal/annotations/Setting.java | 13 +++++++++++
.../processor/SettingProcessor.java | 16 ++++++++++++++
.../processor/utils/SpecUtils.java | 22 +++++++++++++++++++
.../touchportal/helpers/SettingHelper.java | 7 ++++++
.../TouchPortalSampleJavaPlugin.java | 7 ++++--
5 files changed, 63 insertions(+), 2 deletions(-)
diff --git a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Setting.java b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Setting.java
index eded71f..6d276dc 100644
--- a/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Setting.java
+++ b/Annotations/src/main/java/com/christophecvb/touchportal/annotations/Setting.java
@@ -99,4 +99,17 @@
* @return boolean isReadOnly
*/
boolean isReadOnly() default false;
+
+ /**
+ * Setting Tooltip
+ *
+ * @return {@link Tooltip} tooltip
+ */
+ Tooltip tooltip() default @Tooltip(body = "");
+
+ @interface Tooltip {
+ String title() default "";
+ String body();
+ String docUrl() default "";
+ }
}
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java
index 589f1c3..6e27f22 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/SettingProcessor.java
@@ -34,6 +34,22 @@ public static Pair process(TouchPortalPluginAnnota
jsonSetting.addProperty(SettingHelper.TYPE, desiredTPType);
jsonSetting.addProperty(SettingHelper.DEFAULT, setting.defaultValue());
jsonSetting.addProperty(SettingHelper.IS_READ_ONLY, setting.isReadOnly());
+
+ if (!setting.tooltip().body().isEmpty()) {
+ JsonObject tooltip = new JsonObject();
+
+ tooltip.addProperty(SettingHelper.Tooltip.BODY, setting.tooltip().body());
+
+ if (!setting.tooltip().title().isEmpty()) {
+ tooltip.addProperty(SettingHelper.Tooltip.TITLE, setting.tooltip().title());
+ }
+ if (!setting.tooltip().docUrl().isEmpty()) {
+ tooltip.addProperty(SettingHelper.Tooltip.DOC_URL, setting.tooltip().docUrl());
+ }
+
+ jsonSetting.add(SettingHelper.TOOLTIP, tooltip);
+ }
+
switch (desiredTPType) {
case SettingHelper.TYPE_TEXT:
if (setting.maxLength() > 0) {
diff --git a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/utils/SpecUtils.java b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/utils/SpecUtils.java
index c681c16..044022f 100644
--- a/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/utils/SpecUtils.java
+++ b/AnnotationsProcessor/src/main/java/com/christophecvb/touchportal/annotations/processor/utils/SpecUtils.java
@@ -197,9 +197,31 @@ public static TypeSpec.Builder createSettingTypeSpecBuilder(Element settingEleme
stateTypeSpecBuilder.addField(SpecUtils.getStaticFinalDoubleFieldSpec("max_value", setting.maxValue()));
}
+ if (!setting.tooltip().body().isEmpty()) {
+ stateTypeSpecBuilder.addType(createSettingTooltipTypeSpecBuilder(setting.tooltip()).build());
+ }
+
return stateTypeSpecBuilder;
}
+ /**
+ * Generates a TypeSpec.Builder with Constants for the {@link Setting.Tooltip}
+ *
+ * @param tooltip {@link Setting.Tooltip}
+ * @return TypeSpec.Builder tooltipTypeSpecBuilder
+ */
+ public static TypeSpec.Builder createSettingTooltipTypeSpecBuilder(Setting.Tooltip tooltip) {
+ TypeSpec.Builder tooltipTypeSpecBuilder = TypeSpec.classBuilder("Tooltip").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+ tooltipTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("body", tooltip.body()));
+ if (!tooltip.title().isEmpty()) {
+ tooltipTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("title", tooltip.title()));
+ }
+ if (!tooltip.title().isEmpty()) {
+ tooltipTypeSpecBuilder.addField(SpecUtils.getStaticFinalStringFieldSpec("docUrl", tooltip.docUrl()));
+ }
+ return tooltipTypeSpecBuilder;
+ }
+
/**
* Generates a TypeSpec.Builder with Constants for the {@link State}
*
diff --git a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/SettingHelper.java b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/SettingHelper.java
index e559e98..a78eff3 100644
--- a/Helpers/src/main/java/com/christophecvb/touchportal/helpers/SettingHelper.java
+++ b/Helpers/src/main/java/com/christophecvb/touchportal/helpers/SettingHelper.java
@@ -39,6 +39,13 @@ public class SettingHelper {
public static final String MIN_VALUE = "minValue";
public static final String MAX_VALUE = "maxValue";
public static final String IS_READ_ONLY = "readOnly";
+ public static final String TOOLTIP = "tooltip";
+
+ public static class Tooltip {
+ public static final String TITLE = "title";
+ public static final String BODY = "body";
+ public static final String DOC_URL = "docUrl";
+ }
/**
* Get the generated Setting Name
diff --git a/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java b/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
index 2737b69..0f96873 100644
--- a/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
+++ b/SampleJava/src/main/java/com/christophecvb/touchportal/samplejava/TouchPortalSampleJavaPlugin.java
@@ -31,7 +31,6 @@
import java.io.File;
import java.util.HashMap;
-import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -80,7 +79,11 @@ private enum Categories {
/**
* Setting of type text definition example
*/
- @Setting(name = "IP", defaultValue = "localhost", maxLength = 15)
+ @Setting(name = "IP", defaultValue = "localhost", maxLength = 15, tooltip = @Setting.Tooltip(
+ title = "IP address",
+ body = "ip address to connect to",
+ docUrl = "https://example.com"
+ ))
private String ipSetting;
/**