diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..dc391ff
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,17 @@
+name: Java CI
+
+on: [push]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up JDK 17
+ uses: actions/setup-java@v2
+ with:
+ java-version: '17'
+ distribution: 'adopt'
+ - name: Build with Maven
+ run: mvn --batch-mode --update-snapshots --no-transfer-progress clean test
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
new file mode 100644
index 0000000..7254456
--- /dev/null
+++ b/.github/workflows/deploy.yml
@@ -0,0 +1,27 @@
+name: Publish package to the Maven Central Repository
+on:
+ release:
+ types: [created]
+jobs:
+ publish:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up Maven Central Repository
+ uses: actions/setup-java@v2
+ with:
+ java-version: '17'
+ distribution: 'adopt'
+ server-id: ossrh
+ server-username: MAVEN_USERNAME
+ server-password: MAVEN_PASSWORD
+ - id: install-secret-key
+ name: Install gpg secret key
+ run: |
+ cat <(echo -e "${{ secrets.OSSRH_GPG_SECRET_KEY }}") | gpg --batch --import
+ gpg --list-secret-keys --keyid-format LONG
+ - name: Publish package
+ run: mvn --batch-mode --no-transfer-progress "-Dgpg.passphrase=${{ secrets.OSSRH_GPG_SECRET_KEY_PASSPHRASE }}" clean deploy
+ env:
+ MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
+ MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bba7b53
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/target/
+/.idea/
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..83a8183
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Ouest-France/SIPA Tech
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8bf796e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,71 @@
+# bp-contract-generator-java
+
+Here is an easy and programmatic way to generate block provider contracts. Contracts are valid by design and will fit
+perfectly with the BMS.
+
+This fluid API helps you to declare multiple block types with theirs endpoint, parameters and associated templates.
+
+You simply need to generate the object and let your favorite JSON framework serialize it.
+
+## How to install
+
+```xml
+
+
+ io.github.ouest-france
+ bp-contract-generator
+ 1.0.0
+
+```
+
+## Demonstration
+
+Here is an example with a block type that takes an input text, sends it to a remote service (for demonstration only),
+and outputs the bolded text with different templates.
+
+```java
+
+@RequestMapping("/block-provider")
+@RestController
+@RequiredArgsConstructor
+public class BlockProviderResource {
+
+ @GetMapping("/configurations")
+ public ResponseEntity> configurations() {
+ return ResponseEntity.ok(
+ BlockProviderGenerator.create()
+ // the block type
+ .addType("bold").withVersion(1, 0, 0)
+
+ // declare the endpoint url
+ .withEndpoint("https://localhost/block-configurations", "GET", "pure")
+
+ // the input text
+ .addParameter("text")
+ .configurableAsString()
+ .required()
+ .withTitle("Text")
+ .withDescription("Text to display as bold")
+
+ // send this parameter to the endpoint as a query parameter
+ .inEndpoint(QUERY, STRING)
+ .registerParameter()
+
+ // first template to output using html tag
+ .addTemplate("html-tag")
+ .withSource("{{ text }}")
+ .registerTemplate()
+
+ // second template to output using css style
+ .addTemplate("html-css")
+ .withSource("{{ text }}")
+ .registerTemplate()
+
+ .registerType()
+ .generate()
+ );
+ }
+
+}
+```
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..94f5b2e
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,124 @@
+
+
+ 4.0.0
+
+ io.github.ouest-france
+ bp-contract-generator
+ 1.0.0
+
+
+ UTF-8
+ UTF-8
+ 8
+ 8
+ 2.8.9
+ 5.1.0
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit-jupiter-engine.version}
+ test
+
+
+
+ com.google.code.gson
+ gson
+ ${gson.version}
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.2.1
+
+
+ attach-sources
+
+ jar-no-fork
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.3.1
+
+ sipa.blockprovider.*
+
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 1.5
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+ --pinentry-mode
+ loopback
+
+
+
+
+
+
+
+
+
+ scm:git:${project.scm.url}
+ scm:git:${project.scm.url}
+ git@github.com:ouest-france/bp-contract-generator-java.git
+ HEAD
+
+
+
+
+ poussma
+ Mathieu POOUSSE
+
+
+
+
+
+ MIT
+ https://opensource.org/licenses/MIT
+ repo
+
+
+
+ bp-contract-generator-java
+ https://github.com/ouest-france/bp-contract-generator-java
+ A library to easily generate block provider contracts
+
+
+
+ ossrh
+ Central Repository OSSRH
+ https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/
+
+
+
+
diff --git a/src/main/java/sipa/blockprovider/BlockProviderGenerator.java b/src/main/java/sipa/blockprovider/BlockProviderGenerator.java
new file mode 100644
index 0000000..dde6a27
--- /dev/null
+++ b/src/main/java/sipa/blockprovider/BlockProviderGenerator.java
@@ -0,0 +1,49 @@
+package sipa.blockprovider;
+
+import sipa.blockprovider.domain.BlockType;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * The main class to generate block provider contracts.
+ */
+public class BlockProviderGenerator {
+
+ /**
+ * Prepare a new block provider builder.
+ *
+ * @return see description
+ */
+ public static BlockProviderGenerator create() {
+ return new BlockProviderGenerator();
+ }
+
+ private BlockProviderGenerator() {
+
+ }
+
+ private final List types = new ArrayList<>();
+
+ /**
+ * Add a block type to the block provider.
+ *
+ * @param name the name of the block type
+ * @return the builder
+ */
+ public BlockTypeBuilder addType(final String name) {
+ final BlockTypeBuilder builder = new BlockTypeBuilder(this, name);
+ this.types.add(builder);
+ return builder;
+ }
+
+ /**
+ * Finalize the block provider.
+ *
+ * @return a ready to serialize list of declared block types
+ */
+ public List generate() {
+ return this.types.stream().map(type -> type.blockType).collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/sipa/blockprovider/BlockTypeBuilder.java b/src/main/java/sipa/blockprovider/BlockTypeBuilder.java
new file mode 100644
index 0000000..2036c7f
--- /dev/null
+++ b/src/main/java/sipa/blockprovider/BlockTypeBuilder.java
@@ -0,0 +1,98 @@
+package sipa.blockprovider;
+
+import sipa.blockprovider.domain.BlockConfiguration;
+import sipa.blockprovider.domain.BlockType;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Consumer;
+
+/**
+ * The class to generate block type.
+ */
+public class BlockTypeBuilder {
+
+ final BlockType blockType;
+ private final BlockProviderGenerator owner;
+ BlockConfiguration blockConfiguration;
+
+ BlockTypeBuilder(final BlockProviderGenerator owner, final String name) {
+ this.owner = owner;
+ this.blockType = new BlockType(this.blockConfiguration = new BlockConfiguration());
+ this.blockType.setName(name);
+ }
+
+ /**
+ * Finalize the block type.
+ *
+ * @return the block provider builder
+ */
+ public BlockProviderGenerator registerType() {
+ if (this.blockConfiguration.getTemplates().size() == 0) {
+ // create default empty template
+ addTemplate("default").registerTemplate();
+ }
+ return this.owner;
+ }
+
+ /**
+ * This gives you a way to add / remove / replace custom properties to the section with the specified title.
+ *
+ * @param title the title of the section to customize
+ * @param consumer the consumer method that modifies the properties
+ * @return the block type builder
+ */
+ public BlockTypeBuilder customizeSection(final String title, final Consumer