diff --git a/.github/workflows/javadoc.yml b/.github/workflows/javadoc.yml index 0235f811..c31cf4bb 100644 --- a/.github/workflows/javadoc.yml +++ b/.github/workflows/javadoc.yml @@ -15,11 +15,11 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17' + java-version: '21' # Given the fact that this is a multimodule project, build process will take long time so we activate caching # To know more: https://maven.apache.org/extensions/maven-build-cache-extension/cache.html cache: 'maven' diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 1b1e9aa6..f13d6d0e 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -6,8 +6,12 @@ name: Java CI with Maven on: push: branches: [ main ] + paths-ignore: + - '**.md' pull_request: branches: [ main ] + paths-ignore: + - '**.md' permissions: contents: read @@ -19,11 +23,11 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17' + java-version: '21' # Given the fact that this is a multimodule project, build process will take long time so we activate caching # To know more: https://maven.apache.org/extensions/maven-build-cache-extension/cache.html cache: 'maven' diff --git a/README.api.md b/README.api.md index d50ce812..bcd520bf 100644 --- a/README.api.md +++ b/README.api.md @@ -1,68 +1,5 @@ # API -Using [`httpie`](https://httpie.io/): -```shell -# You can also pass as many HTML content as you want -# Response will be of 'application/json' content type -http -vf :8080/convert \ - extension='.js' \ - contents[]='
' \ - contents[]='' - -HTTP/1.1 200 -Content-Type: application/json - -{ - "status": "SUCCESS" - "content": [ - { - "content": "const targetElement_000 = document.querySelector(`:root > body`);\r\n\r\n\r\nconst hr_000 = document.createElement('hr');\r\ntargetElement_000.appendChild(hr_000);\r\n", - "filename": "inline.0.js" - }, - { - "content": "const targetElement_001 = document.querySelector(`:root > body`);\r\n\r\n\r\nconst button_000 = document.createElement('button');\r\nbutton_000.setAttribute(`disabled`, `true`);\r\nconst text_000 = document.createTextNode(`click me, please :sob:`);\r\nbutton_000.appendChild(text_000);\r\ntargetElement_001.appendChild(button_000);\r\n", - "filename": "inline.1.js" - } - ] -} -``` - -Or, give the following two files contents: -> ```json -> { "extension": ".js" } // ./multipart-options.json -> ``` -> -> ```html -> -> -> -> -> ... -> ... -> ... -> ``` - -```shell -# You can call the API with multiple **files** and at most one **options** -# Response will be of 'multipart/form-data' content type -http -vf :8080/convert/files \ - 'files@./sample.html;type=multipart/form-data' \ - 'options@multipart-options.json;type=application/json' - -HTTP/1.1 200 -Content-Type: multipart/form-data;boundary=3N0wqEqnb7AC3WD8M1cYYG-vLfHDND_JdE90 - ---3N0wqEqnb7AC3WD8M1cYYG-vLfHDND_JdE90 -Content-Disposition: form-data; name="0.sample.html.js" -Content-Type: application/octet-stream -Content-Length: 4156 - -const targetElement_000 = document.querySelector(`:root > body`); -[... truncated for brievity] -``` - ---- - After starting the `jsgenerator-api` as described in the [README.md](./README.md), you can read: + OpenAPI spec. at: [http://localhost:8080/openapi.yaml](http://localhost:8080/openapi.yaml) @@ -79,10 +16,160 @@ Both accept options as follow: "pattern": "inline-filename-pattern", "variableNameStrategy": "TYPE_BASED", "variableDeclaration": "LET", - "extension": ".extension", + "extension": ".jsgenerator.js", + "commentConversionModeActivated": true, + "querySelectorAdded": true, "contents": [ "string" ] } ``` -> **NOTE:** The `"content"` field is mandatory for `POST /convert` and forbidden for `POST /convert/files` \ No newline at end of file +> **NOTE:** The `"contents"` field is mandatory for `POST /convert` and forbidden for `POST /convert/files` + + +--- + +Using [`curl`](https://curl.se/): + ++ `POST /convert` +```shell +# You can also pass as many HTML content as you want +# Response will be of 'application/json' content type +curl -H 'content-type: application/json' -X POST --data '{"contents": ["
js-jsgenerator
"]}' http://localhost:8080/convert + +#Response +{"content":[{"filename":"inline.0.jsgenerator.js","content":"let targetElement_001 = document.querySelector(`:root > body`);\r\n\r\n\r\nlet div_001 = document.createElement('div');\r\nlet text_001 = document.createTextNode(`js-generator`);\r\ndiv_001.appendChild(text_001);\r\ntargetElement_001.appendChild(div_001);\r\n"}],"status":"SUCCESS"} +``` + ++ `POST /convert/files` +```shell +# You can call the API with multiple **files** and at most one **options** +# Response will be of 'multipart/form-data' content type +curl -s -X POST -H 'content-type: multipart/form-data' -F files=@illustrations/sample.html -F "options={ \"querySelectorAdded\": true, \"variableDeclaration\": \"VAR\" }; type=application/json" http://localhost:8080/convert/files + +# -s flag is added in order to prevent curl to mix response and progress meter +#if not added, this will happen: 100 5280 100 4275 100 1005 117k 28194 --:--:-- --:--:-- --:--:-- 147kment.createTextNode(` `); + +#Response + +--d2a-7NlH3rlmcFC3loiJxDxom6iojCunhkzzH +Content-Disposition: form-data; name="inline.0.jsgenerator.js" +Content-Type: application/octet-stream +Content-Length: 4069 + +var targetElement_001 = document.querySelector(`:root > body`); + + +var html_001 = document.createElement('html'); +var text_001 = document.createTextNode(` `); +html_001.appendChild(text_001); + +var head_001 = document.createElement('head'); +var text_002 = document.createTextNode(` `); +head_001.appendChild(text_002); + +var meta_001 = document.createElement('meta'); +meta_001.setAttribute(`charset`, `utf-8`); +head_001.appendChild(meta_001); +var text_003 = document.createTextNode(` `); +head_001.appendChild(text_003); + +var title_001 = document.createElement('title'); +var text_004 = document.createTextNode(`Sample`); +title_001.appendChild(text_004); +head_001.appendChild(title_001); +var text_005 = document.createTextNode(` `); +head_001.appendChild(text_005); + +var link_001 = document.createElement('link'); +link_001.setAttribute(`rel`, `stylesheet`); +link_001.setAttribute(`href`, ``); +head_001.appendChild(link_001); +var text_006 = document.createTextNode(` `); +head_001.appendChild(text_006); +html_001.appendChild(head_001); +var text_007 = document.createTextNode(` `); +html_001.appendChild(text_007); + +var body_001 = document.createElement('body'); +var text_008 = document.createTextNode(` `); +body_001.appendChild(text_008); + +var div_001 = document.createElement('div'); +div_001.setAttribute(`id`, `container`); +var text_009 = document.createTextNode(` `); +div_001.appendChild(text_009); + +var div_002 = document.createElement('div'); +div_002.setAttribute(`id`, `header`); +var text_010 = document.createTextNode(` `); +div_002.appendChild(text_010); + +var h1_001 = document.createElement('h1'); +var text_011 = document.createTextNode(`Sample`); +h1_001.appendChild(text_011); +div_002.appendChild(h1_001); +var text_012 = document.createTextNode(` `); +div_002.appendChild(text_012); + +var img_001 = document.createElement('img'); +img_001.setAttribute(`src`, `kanye.jpg`); +img_001.setAttribute(`alt`, `kanye`); +div_002.appendChild(img_001); +var text_013 = document.createTextNode(` `); +div_002.appendChild(text_013); +div_001.appendChild(div_002); +var text_014 = document.createTextNode(` `); +div_001.appendChild(text_014); + +var div_003 = document.createElement('div'); +div_003.setAttribute(`id`, `main`); +var text_015 = document.createTextNode(` `); +div_003.appendChild(text_015); + +var h2_001 = document.createElement('h2'); +var text_016 = document.createTextNode(`Main`); +h2_001.appendChild(text_016); +div_003.appendChild(h2_001); +var text_017 = document.createTextNode(` `); +div_003.appendChild(text_017); + +var p_001 = document.createElement('p'); +var text_018 = document.createTextNode(`This is the main content.`); +p_001.appendChild(text_018); +div_003.appendChild(p_001); +var text_019 = document.createTextNode(` `); +div_003.appendChild(text_019); + +var img_002 = document.createElement('img'); +img_002.setAttribute(`src`, ``); +img_002.setAttribute(`alt`, ``); +div_003.appendChild(img_002); +var text_020 = document.createTextNode(` `); +div_003.appendChild(text_020); +div_001.appendChild(div_003); +var text_021 = document.createTextNode(` `); +div_001.appendChild(text_021); + +var div_004 = document.createElement('div'); +div_004.setAttribute(`id`, `footer`); +var text_022 = document.createTextNode(` `); +div_004.appendChild(text_022); + +var p_002 = document.createElement('p'); +var text_023 = document.createTextNode(`Copyright - 2019`); +p_002.appendChild(text_023); +div_004.appendChild(p_002); +var text_024 = document.createTextNode(` `); +div_004.appendChild(text_024); +div_001.appendChild(div_004); +var text_025 = document.createTextNode(` `); +div_001.appendChild(text_025); +body_001.appendChild(div_001); +var text_026 = document.createTextNode(` `); +body_001.appendChild(text_026); +html_001.appendChild(body_001); +targetElement_001.appendChild(html_001); + +--d2a-7NlH3rlmcFC3loiJxDxom6iojCunhkzzH-- +``` diff --git a/README.cli.md b/README.cli.md index 15aed949..59c234c0 100644 --- a/README.cli.md +++ b/README.cli.md @@ -1,18 +1,18 @@ # Command Line Interface ```shell -let targetElement_000 = document.querySelector(`:root > body`); +let targetElement_001 = document.querySelector(`:root > body`); -let div_000 = document.createElement('div'); -let text_000 = document.createTextNode(`I am a `); -div_000.appendChild(text_000); +let div_001 = document.createElement('div'); +let text_001 = document.createTextNode(`I am a `); +div_001.appendChild(text_001); -let strong_000 = document.createElement('strong'); -let text_001 = document.createTextNode(`tea pot`); -strong_000.appendChild(text_001); -div_000.appendChild(strong_000); -targetElement_000.appendChild(div_000); +let strong_001 = document.createElement('strong'); +let text_002 = document.createTextNode(`tea pot`); +strong_001.appendChild(text_002); +div_001.appendChild(strong_001); +targetElement_001.appendChild(div_001); ``` --- @@ -20,7 +20,8 @@ targetElement_000.appendChild(div_000); `jsgenerator` has several options that can be used in a console here is an example of use below ```text -Usage: jsgenerator [-htV] [-e=] [--inline-pattern=] +Usage: jsgenerator [-chtV] [-qs] [-e=] + [--inline-pattern=] [-k=] [--path-pattern=] [-s=] [--stdin-pattern=] @@ -28,6 +29,7 @@ Usage: jsgenerator [-htV] [-e=] [--inline-pattern=] tegy>] [-i=...]... [...] Translating files, stdin or inline from HTML to JS [...] file paths to translate content, parsed as HTML + -c, --comment optional comments -e, --ext= output files' extension -h, --help Show this help message and exit. -i, --inline=... @@ -38,6 +40,23 @@ Translating files, stdin or inline from HTML to JS variable declaration keyword --path-pattern= pattern for path-based output filenames + -qs, --query-selector + What the browser renders depends on whether "document. + querySelector(':root > body')" is added to the + output. If added, the browser will render the + output successfully, it is useful for debugging + purpose, + to verify that the js output matches what the + html input does. + If not, if the user tries to run the output as + it is then the browser will not be able to render, + it will show a blank page. + So, it depends on what the user wants to do with + the output. + "https://jsfiddle.net/", "https://codepen. + io/pen/" and Browser Console help to give a quick + feedback. + -s, --selector= Target element selector --stdin-pattern= @@ -46,4 +65,4 @@ Translating files, stdin or inline from HTML to JS -V, --version Print version information and exit. --variable-name-generation-strategy= Variable names generation strategy -``` \ No newline at end of file +``` diff --git a/README.desktop.md b/README.desktop.md new file mode 100644 index 00000000..3554a3db --- /dev/null +++ b/README.desktop.md @@ -0,0 +1,3 @@ +> Screenshot of the current desktop version: +> +> ![Screenshot of the current desktop version](illustrations/screenshot_current_desktop_version.png) diff --git a/README.md b/README.md index e6218842..e1febd94 100644 --- a/README.md +++ b/README.md @@ -44,23 +44,11 @@ We would like to give credit to [jsoup](https://jsoup.org/) / [jsoup GitHub Repo ## Requirements -+ JDK 17 - > **Because we use modern JavaFX** - > - > **NOTE:** For native build (CLI, for eg.), we use GraalVM with JDK 17. - > - > Recent versions of GraalVM are not bundling `native-image` CLI by default. - > We are required to install is manually, by running: - > ```shell - > # Where `gu` is an executable bundled with GraalVM - > gu install native-image - > ``` ++ JDK 21 + Maven 4 > Because of its unique features over maven 3: > namely, multi module dependency resolution under common parent, when running a maven goal only on some child -+ Spring 5.3.22 - > A framework to bootstrap dependency injection and inversion of control for our modules -+ Spring Boot 2.7.3 ++ Spring Boot 3.3.1 > Leverage convention over configuration and autoconfiguration discovery to enforce consistent a behaviour > throughout our frontends @@ -80,13 +68,14 @@ js-generator: ## Architecture | THE MODULE | ITS CONTENT && DEPENDENCIES | PACKAGING | -|------------------------------------|-------------------------------------|-----------| -| js-generator | Bill of Material, global properties | POM | -| jsgenerator-core | Core API, Spring Boot auto-conf | JAR | -| jsgenerator-slim-api | jsgenerator-core, spring-web | JAR | -| jsgenerator-slim-cli | jsgenerator-core, picocli | JAR | -| [jsgenerator-api](./README.api.md) | jsgenerator-slim-api | FAT JAR | -| [jsgenerator-cli](./README.cli.md) | jsgenerator-slim-cli | FAT JAR | +|------------------------------------|-------------------------------------|-------| +| js-generator | Bill of Material, global properties | POM | +| jsgenerator-core | Core API, Spring Boot auto-conf | JAR | +| jsgenerator-slim-api | jsgenerator-core, spring-web | JAR | +| jsgenerator-slim-cli | jsgenerator-core, picocli | JAR | +| [jsgenerator-api](./README.api.md) | jsgenerator-slim-api | FAT JAR | +| [jsgenerator-cli](./README.cli.md) | jsgenerator-slim-cli | FAT JAR | +| [jsgenerator-desktop](./README.desktop.md) | jsgenerator-core, javafx-fxml | JAR | > **NOTE:** FAT JAR packaged modules are mere wrappers around slim modules. The separation is important because then, > the test modules can use slim JARs as dependencies, unlike FAT JARs. This has to do with how "normal" vs. FAT JARs @@ -113,30 +102,43 @@ mvn clean test > > ![](illustrations/intellij-maven-runner-configuration.png) -API Server +API Server : [jsgenerator-api](./README.api.md) ```shell # After starting the server, visit http://localhost:8080 mvn --also-make --projects jsgenerator-api clean spring-boot:run ``` -Command Line Interface (CLI) +Command Line Interface (CLI) : [jsgenerator-cli](./README.cli.md) ```shell # After reading the help, play out with different CLI options mvn --also-make --projects jsgenerator-cli clean spring-boot:run -Dspring-boot.run.arguments=--help # For example: -mvn --also-make --projects :jsgenerator-cli clean spring-boot:run \ - -Dspring-boot.run.arguments="--tty --inline '
I am a tea pot
'" +mvn --also-make --projects jsgenerator-cli clean spring-boot:run -Dspring-boot.run.arguments="--tty --inline '
I am a tea pot
'" + +# It's also possible to create the jar first +mvn clean package + +# then run the following commands and replace {version} by the current one (0.0.1-SNAPSHOT at this time) +java -jar jsgenerator-cli/target/jsgenerator-cli-{version}.jar # java -jar jsgenerator-cli/target/jsgenerator-cli-0.0.1-SNAPSHOT.jar --help +java -jar jsgenerator-cli/target/jsgenerator-cli-{version}.jar --tty --inline '
I am a tea pot
' +``` + +Desktop : [jsgenerator-desktop](./README.desktop.md) +```shell +# Create the jar first +mvn clean package + +# then run this command and replace {version} by the current one (0.0.1-SNAPSHOT at this time) +java -jar jsgenerator-desktop/target/jsgenerator-desktop-{version}.jar # java -jar jsgenerator-desktop/target/jsgenerator-desktop-0.0.1-SNAPSHOT.jar ``` + ## Packaging ```shell # Will compile all the modules into JAR (or FAT JAR - see the table above) mvn clean package - -# Additionally, build CLI into native executable (require GraalVM - see requirements above) -./cli-build.sh ``` # Contribute diff --git a/cli-build.sh b/cli-build.sh deleted file mode 100755 index a9fca043..00000000 --- a/cli-build.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env sh -set -euxo - -_NATIVE_DIRECTORY="$(mktemp --directory --tmpdir="$(dirname "$(realpath "$0")")/jsgenerator-cli/target" native-XXXXXX)" -cat "$(dirname "$(realpath "$0")")/jsgenerator-cli/target/"*.original > "${_NATIVE_DIRECTORY}/jsgenerator-cli.jar" - -unzip ./jsgenerator-cli/target/*.jar -d "${_NATIVE_DIRECTORY}/" -_CLASSPATH="$(find "${_NATIVE_DIRECTORY}/BOOT-INF/lib" | tr '\n' ':')" -_CLASSPATH="${_NATIVE_DIRECTORY}/jsgenerator-cli.jar:${_CLASSPATH}:${_NATIVE_DIRECTORY}/BOOT-INF/classes" - -cp -R "${_NATIVE_DIRECTORY}/META-INF" "${_NATIVE_DIRECTORY}/BOOT-INF/classes" -native-image \ - "-H:Name=${1:-jsgenerator}" \ - --class-path "${_CLASSPATH}" \ - --module-path "${_CLASSPATH}" \ - --module com.osscameroon.jsgenerator.cli/com.osscameroon.jsgenerator.cli.JsGeneratorCli diff --git a/illustrations/sample.html b/illustrations/sample.html new file mode 100644 index 00000000..459b4962 --- /dev/null +++ b/illustrations/sample.html @@ -0,0 +1,25 @@ + + + + + + Sample + + + +
+ +
+

Main

+

This is the main content.

+ +
+ +
+ + \ No newline at end of file diff --git a/illustrations/screenshot_current_desktop_version.png b/illustrations/screenshot_current_desktop_version.png new file mode 100644 index 00000000..8368e761 Binary files /dev/null and b/illustrations/screenshot_current_desktop_version.png differ diff --git a/jsgenerator-api/pom.xml b/jsgenerator-api/pom.xml index b75b2287..22cb263d 100644 --- a/jsgenerator-api/pom.xml +++ b/jsgenerator-api/pom.xml @@ -17,6 +17,10 @@ + + org.graalvm.buildtools + native-maven-plugin + org.springframework.boot spring-boot-maven-plugin diff --git a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/Configuration.java b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/Configuration.java index ba27273d..34feb9f9 100644 --- a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/Configuration.java +++ b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/Configuration.java @@ -1,17 +1,9 @@ package com.osscameroon.jsgenerator.core; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - import static com.osscameroon.jsgenerator.core.VariableDeclaration.LET; import static com.osscameroon.jsgenerator.core.VariableNameStrategy.ofTypeBased; -@Data -@NoArgsConstructor -@AllArgsConstructor public class Configuration { - private static final String ROOT_BODY = ":root > body"; private String targetElementSelector = ROOT_BODY; @@ -30,36 +22,62 @@ public class Configuration { private VariableDeclaration variableDeclaration = LET; private VariableNameStrategy variableNameStrategy = ofTypeBased(); - public Configuration(final VariableDeclaration variableDeclaration) { - this(variableDeclaration, ofTypeBased()); + public Configuration() { + } + + public Configuration(VariableDeclaration variableDeclaration, + boolean querySelectorAdded, + boolean commentConversionModeActivated) { + this.querySelectorAdded = querySelectorAdded; + this.variableDeclaration = variableDeclaration; + this.commentConversionModeActivated = commentConversionModeActivated; } - public Configuration(final VariableDeclaration variableDeclaration, final boolean querySelectorAdded, final boolean commentConversionModeActivated) { - this(variableDeclaration, ofTypeBased(), querySelectorAdded, commentConversionModeActivated); + public Configuration(VariableDeclaration variableDeclaration, + boolean querySelectorAdded) { + this.querySelectorAdded = querySelectorAdded; + this.variableDeclaration = variableDeclaration; } - public Configuration(final VariableDeclaration variableDeclaration, final boolean querySelectorAdded) { - this(variableDeclaration, ofTypeBased(), querySelectorAdded, true); + public Configuration(VariableDeclaration variableDeclaration, + VariableNameStrategy variableNameStrategy, + boolean querySelectorAdded, + boolean commentConversionModeActivated) { + this.querySelectorAdded = querySelectorAdded; + this.variableDeclaration = variableDeclaration; + this.variableNameStrategy = variableNameStrategy; + this.commentConversionModeActivated = commentConversionModeActivated; } + public Configuration(String targetElementSelector, + boolean querySelectorAdded, + boolean commentConversionModeActivated, + VariableDeclaration variableDeclaration, + VariableNameStrategy variableNameStrategy) { + this.querySelectorAdded = querySelectorAdded; + this.variableDeclaration = variableDeclaration; + this.variableNameStrategy = variableNameStrategy; + this.targetElementSelector = targetElementSelector; + this.commentConversionModeActivated = commentConversionModeActivated; + } + + public String getTargetElementSelector() { + return targetElementSelector; + } - public Configuration(final String targetElementSelector, - final VariableDeclaration variableDeclaration) { - this(targetElementSelector, true, true, variableDeclaration, ofTypeBased()); + public boolean isQuerySelectorAdded() { + return querySelectorAdded; } - public Configuration(final String targetElementSelector, - final VariableDeclaration variableDeclaration, final boolean querySelectorAdded, final boolean commentConversionModeActivated) { - this(targetElementSelector, querySelectorAdded, commentConversionModeActivated, variableDeclaration, ofTypeBased()); + public boolean isCommentConversionModeActivated() { + return commentConversionModeActivated; } - public Configuration(final VariableDeclaration variableDeclaration, - final VariableNameStrategy variableNameStrategy) { - this(ROOT_BODY, true, true, variableDeclaration, variableNameStrategy); + public VariableDeclaration getVariableDeclaration() { + return variableDeclaration; } - public Configuration(final VariableDeclaration variableDeclaration, - final VariableNameStrategy variableNameStrategy, final boolean querySelectorAdded, final boolean commentConversionModeActivated) { - this(ROOT_BODY, querySelectorAdded, commentConversionModeActivated, variableDeclaration, variableNameStrategy); + public VariableNameStrategy getVariableNameStrategy() { + return variableNameStrategy; } -} \ No newline at end of file +} diff --git a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/Converter.java b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/Converter.java index bcc10711..74d9fc60 100644 --- a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/Converter.java +++ b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/Converter.java @@ -1,7 +1,7 @@ package com.osscameroon.jsgenerator.core; import com.osscameroon.jsgenerator.core.internal.ConverterDefault; -import lombok.NonNull; +import org.springframework.lang.NonNull; import java.io.IOException; import java.io.InputStream; diff --git a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/OutputStreamResolver.java b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/OutputStreamResolver.java index 41d48185..17cf928a 100644 --- a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/OutputStreamResolver.java +++ b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/OutputStreamResolver.java @@ -3,7 +3,7 @@ import com.osscameroon.jsgenerator.core.internal.InlineOutputStreamResolver; import com.osscameroon.jsgenerator.core.internal.PathOutputStreamResolver; import com.osscameroon.jsgenerator.core.internal.StdinOutputStreamResolver; -import lombok.NonNull; +import org.springframework.lang.NonNull; import java.util.Map; diff --git a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/VariableNameStrategy.java b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/VariableNameStrategy.java index 42b2ea1d..c74871a6 100644 --- a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/VariableNameStrategy.java +++ b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/VariableNameStrategy.java @@ -2,7 +2,7 @@ import com.osscameroon.jsgenerator.core.internal.RandomVariableNameStrategy; import com.osscameroon.jsgenerator.core.internal.TypeBasedVariableNameStrategy; -import lombok.NonNull; +import org.springframework.lang.NonNull; @FunctionalInterface public interface VariableNameStrategy { diff --git a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/InlineOutputStreamResolver.java b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/InlineOutputStreamResolver.java index 84f5d732..70fe06a2 100644 --- a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/InlineOutputStreamResolver.java +++ b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/InlineOutputStreamResolver.java @@ -1,7 +1,7 @@ package com.osscameroon.jsgenerator.core.internal; import com.osscameroon.jsgenerator.core.OutputStreamResolver; -import lombok.NonNull; +import org.springframework.lang.NonNull; import java.util.Map; diff --git a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/PathOutputStreamResolver.java b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/PathOutputStreamResolver.java index 2819e5ec..c30b2537 100644 --- a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/PathOutputStreamResolver.java +++ b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/PathOutputStreamResolver.java @@ -1,7 +1,7 @@ package com.osscameroon.jsgenerator.core.internal; import com.osscameroon.jsgenerator.core.OutputStreamResolver; -import lombok.NonNull; +import org.springframework.lang.NonNull; import java.util.Map; diff --git a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/RandomVariableNameStrategy.java b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/RandomVariableNameStrategy.java index 730a78c6..f41b2f15 100644 --- a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/RandomVariableNameStrategy.java +++ b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/RandomVariableNameStrategy.java @@ -1,7 +1,7 @@ package com.osscameroon.jsgenerator.core.internal; import com.osscameroon.jsgenerator.core.VariableNameStrategy; -import lombok.NonNull; +import org.springframework.lang.NonNull; import static java.util.UUID.randomUUID; diff --git a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/StdinOutputStreamResolver.java b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/StdinOutputStreamResolver.java index 6d2a2ffe..5f214e95 100644 --- a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/StdinOutputStreamResolver.java +++ b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/StdinOutputStreamResolver.java @@ -1,7 +1,7 @@ package com.osscameroon.jsgenerator.core.internal; import com.osscameroon.jsgenerator.core.OutputStreamResolver; -import lombok.NonNull; +import org.springframework.lang.NonNull; import java.util.Map; diff --git a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/TypeBasedVariableNameStrategy.java b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/TypeBasedVariableNameStrategy.java index 143b6cbd..f5f5de2f 100644 --- a/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/TypeBasedVariableNameStrategy.java +++ b/jsgenerator-core/src/main/java/com/osscameroon/jsgenerator/core/internal/TypeBasedVariableNameStrategy.java @@ -1,7 +1,7 @@ package com.osscameroon.jsgenerator.core.internal; import com.osscameroon.jsgenerator.core.VariableNameStrategy; -import lombok.NonNull; +import org.springframework.lang.NonNull; import java.util.HashMap; import java.util.Map; diff --git a/jsgenerator-core/src/main/java/module-info.java b/jsgenerator-core/src/main/java/module-info.java index 6de056e4..0d74b538 100644 --- a/jsgenerator-core/src/main/java/module-info.java +++ b/jsgenerator-core/src/main/java/module-info.java @@ -4,10 +4,10 @@ opens com.osscameroon.jsgenerator.core.autoconfigure; - requires lombok; requires org.jsoup; requires spring.boot; requires spring.context; requires spring.boot.autoconfigure; + requires spring.core; } diff --git a/jsgenerator-desktop/pom.xml b/jsgenerator-desktop/pom.xml index 0c7d9e6e..b7cb3f75 100644 --- a/jsgenerator-desktop/pom.xml +++ b/jsgenerator-desktop/pom.xml @@ -9,179 +9,45 @@ ${revision} - 4.0.0 - jsgenerator-desktop - jsgenerator-desktop - 17.0.2 - 0.0.8 - com.osscameroon.jsgenerator.desktop.HelloApplication + com.osscameroon.jsgenerator.desktop.autoconfigure.JsGeneratorDesktop - - - - org.springframework.boot - spring-boot-starter - - com.osscameroon jsgenerator-core - - - - org.openjfx - javafx-controls - ${javafx.version} - org.openjfx javafx-fxml - ${javafx.version} - - - org.openjfx - javafx-web - ${javafx.version} - - org.controlsfx - controlsfx - 11.1.1 - - - com.dlsc.formsfx - formsfx-core - 11.5.0 - - - org.openjfx - * - - - - - net.synedra - validatorfx - 0.4.0 - - - org.openjfx - * - - - - - org.kordamp.ikonli - ikonli-javafx - 12.3.1 - - - org.kordamp.bootstrapfx - bootstrapfx-core - 0.4.0 - - - eu.hansolo - tilesfx - 17.1.9 - - - org.openjfx - * - - - - - - - - eu.hansolo.fx - countries - 17.0.22 - - - - - - - - eu.hansolo.fx - heatmap - 17.0.9 - - - - - - - eu.hansolo - toolboxfx - 17.0.28 - - - - - - - - eu.hansolo - toolbox - 17.0.22 - - - - - - - - org.openjfx - javafx-swing - 20-ea+4 - - - - - org.openjfx - javafx-maven-plugin - ${javafx.plugin.version} - - - - default-cli - - ${mainClass} - app - app - app - true - true - true - - - + org.graalvm.buildtools + native-maven-plugin + + + org.springframework.boot + spring-boot-maven-plugin + + false + + + + org.apache.maven.plugins + maven-compiler-plugin + + 22 + 22 + diff --git a/jsgenerator-desktop/src/main/java/com/osscameroon/jsgenerator/desktop/HelloApplication.java b/jsgenerator-desktop/src/main/java/com/osscameroon/jsgenerator/desktop/HelloApplication.java deleted file mode 100644 index 95ea741e..00000000 --- a/jsgenerator-desktop/src/main/java/com/osscameroon/jsgenerator/desktop/HelloApplication.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.osscameroon.jsgenerator.desktop; - -import javafx.application.Application; -import javafx.fxml.FXMLLoader; -import javafx.scene.Scene; -import javafx.stage.Stage; - -import java.io.IOException; - -public class HelloApplication extends Application { - @Override - public void start(Stage stage) throws IOException { - FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml")); - Scene scene = new Scene(fxmlLoader.load(), 320, 240); - stage.setTitle("Hello!"); - stage.setScene(scene); - stage.show(); - } - - public static void main(String[] args) { - launch(); - } -} \ No newline at end of file diff --git a/jsgenerator-desktop/src/main/java/com/osscameroon/jsgenerator/desktop/HelloController.java b/jsgenerator-desktop/src/main/java/com/osscameroon/jsgenerator/desktop/HelloController.java deleted file mode 100644 index 7e3cfb26..00000000 --- a/jsgenerator-desktop/src/main/java/com/osscameroon/jsgenerator/desktop/HelloController.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.osscameroon.jsgenerator.desktop; - -import javafx.fxml.FXML; -import javafx.scene.control.Label; - -public class HelloController { - @FXML - private Label welcomeText; - - @FXML - protected void onHelloButtonClick() { - welcomeText.setText("Welcome to JavaFX Application!"); - } -} \ No newline at end of file diff --git a/jsgenerator-desktop/src/main/java/com/osscameroon/jsgenerator/desktop/autoconfigure/JsGeneratorDesktop.java b/jsgenerator-desktop/src/main/java/com/osscameroon/jsgenerator/desktop/autoconfigure/JsGeneratorDesktop.java new file mode 100644 index 00000000..8af9795d --- /dev/null +++ b/jsgenerator-desktop/src/main/java/com/osscameroon/jsgenerator/desktop/autoconfigure/JsGeneratorDesktop.java @@ -0,0 +1,62 @@ +package com.osscameroon.jsgenerator.desktop.autoconfigure; + +import com.osscameroon.jsgenerator.core.autoconfigure.JsGeneratorCoreAutoconfigure; +import com.osscameroon.jsgenerator.desktop.controller.FxmlNavigator; +import com.osscameroon.jsgenerator.desktop.controller.FxmlResolver; +import com.osscameroon.jsgenerator.desktop.controller.HelloViewController; +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.stage.Stage; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Lazy; +import org.springframework.core.io.ClassPathResource; + +import java.io.IOException; + +@ImportAutoConfiguration(JsGeneratorCoreAutoconfigure.class) +@SpringBootApplication(scanBasePackageClasses = HelloViewController.class) +public class JsGeneratorDesktop extends Application { + private static ApplicationContext context; + private static FxmlResolver fxmlResolver; + private static Scene scene; + + public static void main(String[] args) { + context = SpringApplication.run(JsGeneratorDesktop.class, args); + fxmlResolver = context.getBean(FxmlResolver.class); + launch(JsGeneratorDesktop.class, args); + } + + /** + * Inject this bean to navigate from one view to another, like a router. + * + * @return + */ + @Bean + @Lazy + public FxmlNavigator fxmlNavigator() { + return scene::setRoot; + } + + @Bean + public FxmlResolver fxmlResolver() { + return path -> { + path = "com/osscameroon/jsgenerator/desktop/controller/%s.fxml".formatted(path); + final var loader = new FXMLLoader(new ClassPathResource(path).getURL()); + loader.setControllerFactory(context::getBean); + return (Parent) loader.load(); + }; + } + + @Override + public void start(Stage stage) throws IOException { + final var parent = fxmlResolver.resolve("hello-view"); + stage.setScene(scene = new Scene(parent)); + stage.show(); + } +} diff --git a/jsgenerator-desktop/src/main/java/com/osscameroon/jsgenerator/desktop/controller/FxmlNavigator.java b/jsgenerator-desktop/src/main/java/com/osscameroon/jsgenerator/desktop/controller/FxmlNavigator.java new file mode 100644 index 00000000..67d0487e --- /dev/null +++ b/jsgenerator-desktop/src/main/java/com/osscameroon/jsgenerator/desktop/controller/FxmlNavigator.java @@ -0,0 +1,8 @@ +package com.osscameroon.jsgenerator.desktop.controller; + +import javafx.scene.Parent; + +@FunctionalInterface +public interface FxmlNavigator { + void navigate(Parent parent); +} diff --git a/jsgenerator-desktop/src/main/java/com/osscameroon/jsgenerator/desktop/controller/FxmlResolver.java b/jsgenerator-desktop/src/main/java/com/osscameroon/jsgenerator/desktop/controller/FxmlResolver.java new file mode 100644 index 00000000..b74cf34e --- /dev/null +++ b/jsgenerator-desktop/src/main/java/com/osscameroon/jsgenerator/desktop/controller/FxmlResolver.java @@ -0,0 +1,10 @@ +package com.osscameroon.jsgenerator.desktop.controller; + +import javafx.scene.Parent; + +import java.io.IOException; + +@FunctionalInterface +public interface FxmlResolver { + Parent resolve(String relativePathWithoutExtension) throws IOException; +} diff --git a/jsgenerator-desktop/src/main/java/com/osscameroon/jsgenerator/desktop/controller/HelloViewController.java b/jsgenerator-desktop/src/main/java/com/osscameroon/jsgenerator/desktop/controller/HelloViewController.java new file mode 100644 index 00000000..aa18df1f --- /dev/null +++ b/jsgenerator-desktop/src/main/java/com/osscameroon/jsgenerator/desktop/controller/HelloViewController.java @@ -0,0 +1,34 @@ +package com.osscameroon.jsgenerator.desktop.controller; + +import com.osscameroon.jsgenerator.core.Converter; +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.control.TextArea; +import org.springframework.stereotype.Component; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +@Component +public final class HelloViewController { + private final Converter converter; + + @FXML + private TextArea inputArea; + @FXML + private Label outputLabel; + + public HelloViewController(Converter converter) { + this.converter = converter; + } + + @FXML + private void convert() throws IOException { + try (var stream = new ByteArrayOutputStream()) { + converter.convert(new ByteArrayInputStream(inputArea.textProperty().getValue().getBytes()), stream); + outputLabel.setText(stream.toString(StandardCharsets.UTF_8)); + } + } +} diff --git a/jsgenerator-desktop/src/main/java/module-info.java b/jsgenerator-desktop/src/main/java/module-info.java index 6eb03ff2..eeebdaca 100644 --- a/jsgenerator-desktop/src/main/java/module-info.java +++ b/jsgenerator-desktop/src/main/java/module-info.java @@ -1,18 +1,18 @@ module com.osscameroon.jsgenerator.desktop { + exports com.osscameroon.jsgenerator.desktop.autoconfigure; + exports com.osscameroon.jsgenerator.desktop.controller; + + opens com.osscameroon.jsgenerator.desktop.controller to javafx.fxml, spring.beans; + opens com.osscameroon.jsgenerator.desktop.autoconfigure to javafx.fxml, spring.beans; requires com.osscameroon.jsgenerator.core; - requires lombok; - requires javafx.controls; - requires javafx.fxml; - requires javafx.web; - requires org.controlsfx.controls; - requires com.dlsc.formsfx; - requires net.synedra.validatorfx; - requires org.kordamp.ikonli.javafx; - requires org.kordamp.bootstrapfx.core; - requires eu.hansolo.tilesfx; + requires spring.boot.autoconfigure; + requires spring.boot; + requires spring.context; - opens com.osscameroon.jsgenerator.desktop to javafx.fxml; - exports com.osscameroon.jsgenerator.desktop; -} \ No newline at end of file + requires javafx.graphics; + requires javafx.controls; + requires javafx.fxml; + requires spring.core; +} diff --git a/jsgenerator-desktop/src/main/resources/application.yml b/jsgenerator-desktop/src/main/resources/application.yml new file mode 100644 index 00000000..29ae4af4 --- /dev/null +++ b/jsgenerator-desktop/src/main/resources/application.yml @@ -0,0 +1,3 @@ +spring: + banner: + location: classpath:/banner.txt diff --git a/jsgenerator-desktop/src/main/resources/banner.txt b/jsgenerator-desktop/src/main/resources/banner.txt new file mode 100644 index 00000000..5c9612c8 --- /dev/null +++ b/jsgenerator-desktop/src/main/resources/banner.txt @@ -0,0 +1,9 @@ + + _ _____ _____ ______ _ _ ______ _____ _______ ____ _____ _____ ______ _____ _ _________ ____ _____ + | |/ ____|/ ____| ____| \ | | ____| __ \ /\|__ __/ __ \| __ \ | __ \| ____|/ ____| |/ /__ __/ __ \| __ \ + | | (___ | | __| |__ | \| | |__ | |__) | / \ | | | | | | |__) |_____| | | | |__ | (___ | ' / | | | | | | |__) | + _ | |\___ \| | |_ | __| | . ` | __| | _ / / /\ \ | | | | | | _ /______| | | | __| \___ \| < | | | | | | ___/ + | |__| |____) | |__| | |____| |\ | |____| | \ \ / ____ \| | | |__| | | \ \ | |__| | |____ ____) | . \ | | | |__| | | + \____/|_____/ \_____|______|_| \_|______|_| \_\/_/ \_\_| \____/|_| \_\ |_____/|______|_____/|_|\_\ |_| \____/|_| + + diff --git a/jsgenerator-desktop/src/main/resources/com/osscameroon/jsgenerator/desktop/controller/hello-view.fxml b/jsgenerator-desktop/src/main/resources/com/osscameroon/jsgenerator/desktop/controller/hello-view.fxml new file mode 100644 index 00000000..ce6799d1 --- /dev/null +++ b/jsgenerator-desktop/src/main/resources/com/osscameroon/jsgenerator/desktop/controller/hello-view.fxml @@ -0,0 +1,18 @@ + + + + + + + + + +