diff --git a/README.md b/README.md index 5c378ce9..022dd7aa 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ It is a **Maven plugin** that generates **project's documentation directly to co > * [Usage](http://bsorrentino.github.io/maven-confluence-plugin/usage.html) > * [Use YAML Site Definition](http://bsorrentino.github.io/maven-confluence-plugin/site_yaml_guide.html) > * [Use XML Site Definition](http://bsorrentino.github.io/maven-confluence-plugin/site_xml_guide.html) +> * [Use JSON Site Definition](http://bsorrentino.github.io/maven-confluence-plugin/site_json_guide.html) ### Format > * [Markdown Syntax Support](http://bsorrentino.github.io/maven-confluence-plugin/markdown_guide.html) > * [Storage Format Support](http://bsorrentino.github.io/maven-confluence-plugin/storageformat_guide.html) @@ -29,7 +30,8 @@ For pratical samples refer to folder/module [test-publishing](https://github.com Date | Release | Info --- |-----------------------------------------------------------------------------------------------------| --- - **Jun 3, 2022** | [Release 7.6](https://github.com/bsorrentino/maven-confluence-plugin/releases/tag/v7.6) | Merged PR [#201](https://github.com/bsorrentino/maven-confluence-plugin/pull/267) "**added function to define jira instance baseurl**", that fix issue [#136](https://github.com/bsorrentino/maven-confluence-plugin/issues/136). Thanks to [tspindler](https://github.com/tspindler) for contribution + **Jul 3, 2022** | [Release 7.7](https://github.com/bsorrentino/maven-confluence-plugin/releases/tag/v7.7) | Merged PR [#266](https://github.com/bsorrentino/maven-confluence-plugin/pull/266) "**Adding JSON Support**". Thanks to [jksevend](https://github.com/jksevend) for contribution. + **Jun 3, 2022** | [Release 7.6](https://github.com/bsorrentino/maven-confluence-plugin/releases/tag/v7.6) | Merged PR [#267](https://github.com/bsorrentino/maven-confluence-plugin/pull/267) "**added function to define jira instance baseurl**", that fix issue [#136](https://github.com/bsorrentino/maven-confluence-plugin/issues/136). Thanks to [tspindler](https://github.com/tspindler) for contribution **Apr 1, 2022** | [Release 7.5](https://github.com/bsorrentino/maven-confluence-plugin/releases/tag/v7.5) | Fix empty table cell not handled properly. Refer to [#264](https://github.com/bsorrentino/maven-confluence-plugin/issues/264). **Jan 10, 2022** | [Release 7.4](https://github.com/bsorrentino/maven-confluence-plugin/releases/tag/v7.4) | Fix problem with **encoding**. Refer to [#261](https://github.com/bsorrentino/maven-confluence-plugin/issues/261). **Aug 09, 2021** | [Release 7.3.2](https://github.com/bsorrentino/maven-confluence-plugin/releases/tag/v7.3.2) | Fix problem with **ReadTimeout** & **WriteTimeout**. Refer to [#256](https://github.com/bsorrentino/maven-confluence-plugin/issues/256). see the PR [#257](https://github.com/bsorrentino/maven-confluence-plugin/pull/257) for details. Thanks to [qwazer](https://github.com/qwazer) for contribution diff --git a/addon-scrollversions/pom.xml b/addon-scrollversions/pom.xml index 25840936..ac11e291 100644 --- a/addon-scrollversions/pom.xml +++ b/addon-scrollversions/pom.xml @@ -5,7 +5,7 @@ maven-confluence-parent org.bsc.maven - 7.6 + 7.7 4.0.0 diff --git a/core/pom.xml b/core/pom.xml index 430ec2c4..88d966db 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -5,7 +5,7 @@ maven-confluence-parent org.bsc.maven - 7.6 + 7.7 4.0.0 diff --git a/core/src/main/java/org/bsc/confluence/model/SiteFactory.java b/core/src/main/java/org/bsc/confluence/model/SiteFactory.java index e88ac561..e939ca5b 100644 --- a/core/src/main/java/org/bsc/confluence/model/SiteFactory.java +++ b/core/src/main/java/org/bsc/confluence/model/SiteFactory.java @@ -4,6 +4,7 @@ */ package org.bsc.confluence.model; +import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.xml.XmlFactory; @@ -23,107 +24,110 @@ import static java.lang.String.format; /** - * * @author bsorrentino */ public interface SiteFactory { - - @Log - final class LogHolder {} - + + @Log + final class LogHolder { + } + interface Folder { Site createSiteFromFolder(); - + } - + interface Model { - + Site createSiteFromModel(Map variables); - + /** - * * @param siteDescriptor * @param variables * @return * @throws Exception */ - default Site createFrom( java.io.File siteDescriptor, Map variables ) throws Exception { - + default Site createFrom(java.io.File siteDescriptor, Map variables) throws Exception { + if (variables == null) throw new java.lang.IllegalArgumentException("variables is null!"); - - final String ext = + + final String ext = Optional.ofNullable(FilenameUtils.getExtension(siteDescriptor.getName())) - .map( v -> v.toLowerCase() ) - .orElse(""); - + .map(v -> v.toLowerCase()) + .orElse(""); + // _createSite lambda function - final Function> _createSite = ( String preprocessedDescriptor ) -> { - + final Function> _createSite = (String preprocessedDescriptor) -> { + final CompletableFuture result = new CompletableFuture<>(); - - switch( ext ) { - case "xml": - { - try { - final ObjectMapper mapper = new ObjectMapper(new XmlFactory()); - mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); - result.complete( mapper.readValue( preprocessedDescriptor, Site.class ) ); - } - catch( Exception e ) { - result.completeExceptionally(e); - } - - break; - } - case "yml": - case "yaml": - { - try { - final ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); - result.complete( mapper.readValue( preprocessedDescriptor, Site.class ) ); - } - catch( Exception e ) { - result.completeExceptionally(e); + switch (ext) { + case "xml": { + try { + final ObjectMapper mapper = new ObjectMapper(new XmlFactory()); + mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + result.complete(mapper.readValue(preprocessedDescriptor, Site.class)); + } catch (Exception e) { + result.completeExceptionally(e); + } + + break; } + case "yml": + case "yaml": { + try { - break; - } - default: - result.completeExceptionally(new IllegalArgumentException( - format("file extension [%s] not supported! Currently only '.xml' and '.yaml' are valid", ext))); + final ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + result.complete(mapper.readValue(preprocessedDescriptor, Site.class)); + } catch (Exception e) { + result.completeExceptionally(e); + } + + break; + } + case "json": + try { + final ObjectMapper mapper = new ObjectMapper(new JsonFactory()); + result.complete(mapper.readValue(preprocessedDescriptor, Site.class)); + } catch (Exception e) { + result.completeExceptionally(e); + } + default: + result.completeExceptionally(new IllegalArgumentException( + format("file extension [%s] not supported! Currently only '.xml', '.yaml' and '.json'" + + "are valid", ext))); } - + return result; }; // end lambda function byte[] siteDescriptorBytes; - try( java.io.InputStream is = new FileInputStream(siteDescriptor.toPath().toFile()) ) { - siteDescriptorBytes = IOUtils.toByteArray( is ); + try (java.io.InputStream is = new FileInputStream(siteDescriptor.toPath().toFile())) { + siteDescriptorBytes = IOUtils.toByteArray(is); } // JAVA 11 // siteDescriptorBytes = Files.readAllBytes(siteDescriptor.toPath()); final String content = new String(siteDescriptorBytes, StandardCharsets.UTF_8); - + final Optional siteProcessor = SiteProcessorService.getDefaultPreprocessorService(); - + final CompletableFuture future = - siteProcessor.map( p -> p.process(content, variables) - .thenCompose( _createSite ) - // uncomment if you want process source content ignoring preprocess exception - //.exceptionally( e -> _createSite.apply(content).join() ) - ) - .orElseGet( () -> { - LogHolder.log.fine( format("a Preprocessor service is not configurated") ); - return _createSite.apply(content); - }); + siteProcessor.map(p -> p.process(content, variables) + .thenCompose(_createSite) + // uncomment if you want process source content ignoring preprocess exception + //.exceptionally( e -> _createSite.apply(content).join() ) + ) + .orElseGet(() -> { + LogHolder.log.fine(format("a Preprocessor service is not configurated")); + return _createSite.apply(content); + }); return future.join(); - - + + } } } diff --git a/core/src/test/kotlin/org/bsc/confluence/model/SiteLoadTest.kt b/core/src/test/kotlin/org/bsc/confluence/model/SiteLoadTest.kt index 1bfd2899..3b13645a 100644 --- a/core/src/test/kotlin/org/bsc/confluence/model/SiteLoadTest.kt +++ b/core/src/test/kotlin/org/bsc/confluence/model/SiteLoadTest.kt @@ -1,19 +1,16 @@ package org.bsc.confluence.model -import com.fasterxml.jackson.databind.DeserializationConfig import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.databind.JsonMappingException import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.dataformat.xml.XmlFactory +import com.fasterxml.jackson.databind.json.JsonMapper import com.fasterxml.jackson.dataformat.xml.XmlMapper import com.fasterxml.jackson.dataformat.yaml.YAMLFactory +import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test import java.nio.file.Files import java.nio.file.Paths -import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule - - class SiteLoadTest { @@ -39,6 +36,15 @@ class SiteLoadTest { } } + private fun loadFromJSON(resource: String, c: ( site:Site ) -> Unit = {}) { + val mapper = JsonMapper() //ObjectMapper(XmlFactory()) + javaClass.classLoader.getResourceAsStream(resource).use { `is` -> + val site = mapper.readValue(`is`, Site::class.java) + assertNotNull(site) + c(site) + } + } + @Test fun testIssue182() = assertThrows(JsonMappingException::class.java) { loadFromYAML("site-issue182.yaml") @@ -93,5 +99,27 @@ class SiteLoadTest { } } + @Test + fun testLoadFromJSON() { + val tempDirectory = Files.createTempDirectory(null) + + loadFromJSON("site.json") { site -> + val basedir = Paths.get(tempDirectory.toString()) + site.basedir = basedir + + assertNotNull(site.home) + val uri = Paths.get(basedir.toString(), "encoding.confluence").toUri() + assertEquals( uri, site.home.uri) + val children = site.home.children + assertNotNull(children) + assertEquals(2, children.size) + val attachments = site.home.attachments + assertNotNull(attachments) + assertEquals(1, attachments.size) + val labels = site.labels + assertNotNull(labels) + assertEquals(2, labels.size) + } + } } \ No newline at end of file diff --git a/core/src/test/resources/site.json b/core/src/test/resources/site.json new file mode 100644 index 00000000..20f7ba3a --- /dev/null +++ b/core/src/test/resources/site.json @@ -0,0 +1,37 @@ +{ + "home": { + "uri": "encoding.confluence", + "children": [ + { + "name": "page 1", + "uri": "page1.md" + }, + { + "name": "page 2", + "uri": "page2.md", + "attachments": [ + { + "name": "attach1.png", + "uri": "attach1.png", + "comment": "attach1_comment", + "contentType": "image/png", + "version": 1 + } + ] + } + ], + "attachments": [ + { + "name": "home.png", + "uri": "home.png", + "comment": "home_comment", + "contentType": "image/png", + "version": 1 + } + ] + }, + "labels": [ + "encoding", + "test" + ] +} \ No newline at end of file diff --git a/deprecated/test-integration/src/test/resources/plugin-project-goals-in-subpage/pom.xml b/deprecated/test-integration/src/test/resources/plugin-project-goals-in-subpage/pom.xml index bfba8d5b..00774c71 100644 --- a/deprecated/test-integration/src/test/resources/plugin-project-goals-in-subpage/pom.xml +++ b/deprecated/test-integration/src/test/resources/plugin-project-goals-in-subpage/pom.xml @@ -48,7 +48,7 @@ org.codehaus.plexus plexus-utils - 3.0.8 + 3.0.16 junit diff --git a/deprecated/test-integration/src/test/resources/simple-plugin-project/pom.xml b/deprecated/test-integration/src/test/resources/simple-plugin-project/pom.xml index bfba8d5b..00774c71 100644 --- a/deprecated/test-integration/src/test/resources/simple-plugin-project/pom.xml +++ b/deprecated/test-integration/src/test/resources/simple-plugin-project/pom.xml @@ -48,7 +48,7 @@ org.codehaus.plexus plexus-utils - 3.0.8 + 3.0.16 junit diff --git a/gitlog+jira/pom.xml b/gitlog+jira/pom.xml index 6483337d..5ccfbfb3 100644 --- a/gitlog+jira/pom.xml +++ b/gitlog+jira/pom.xml @@ -5,7 +5,7 @@ maven-confluence-parent org.bsc.maven - 7.6 + 7.7 4.0.0 diff --git a/plugin-reporting/pom.xml b/plugin-reporting/pom.xml index 43757262..cbfb2b31 100755 --- a/plugin-reporting/pom.xml +++ b/plugin-reporting/pom.xml @@ -5,7 +5,7 @@ maven-confluence-parent org.bsc.maven - 7.6 + 7.7 diff --git a/plugin-reporting/src/main/java/org/bsc/mojo/ConfluenceDeployMojo.java b/plugin-reporting/src/main/java/org/bsc/mojo/ConfluenceDeployMojo.java index 7e736b19..e193c543 100644 --- a/plugin-reporting/src/main/java/org/bsc/mojo/ConfluenceDeployMojo.java +++ b/plugin-reporting/src/main/java/org/bsc/mojo/ConfluenceDeployMojo.java @@ -597,7 +597,12 @@ private ReportingResolutionListener resolveProject() { artifactMetadataSource, null, Collections.singletonList(listener)); } catch (Exception e) { - getLog().warn("An error occurred while resolving project dependencies.", e); + if( getLog().isDebugEnabled() ) { + getLog().warn("An error occurred while resolving project dependencies.", e); + } + else { + getLog().warn(format("An error occurred while resolving project dependencies.\n%s", e.getMessage()) ); + } } return listener; diff --git a/plugin-reporting/src/site/markdown/site_json_guide.md b/plugin-reporting/src/site/markdown/site_json_guide.md new file mode 100644 index 00000000..5c8d534e --- /dev/null +++ b/plugin-reporting/src/site/markdown/site_json_guide.md @@ -0,0 +1,141 @@ + +# Introduction + +From release 7.7 we can describe a complete site's layout using a **json format**. Through site schema you can set root page (called home) its children's tree, add attachments and labels. + +Use it is pretty straightforward, put your **`site.json`** in **`${basedir}/src/site/confluence`** folder and describe your preferred layout following the [site schema](https://raw.githubusercontent.com/bsorrentino/maven-confluence-plugin/master/schemas/site-schema-7.7.json). + +## Site template + +To simplify understanding, below there is a simple site descriptor template + +```json +{ + "home": { + "uri": "encoding.confluence", + "children": [ + { + "name": "page 1", + "uri": "page1.md" + }, + { + "name": "page 2", + "uri": "page2.md", + "attachments": [ + { + "name": "attach1.png", + "uri": "attach1.png", + "comment": "attach1_comment", + "contentType": "image/png", + "version": 1 + } + ] + } + ], + "attachments": [ + { + "name": "home.png", + "uri": "home.png", + "comment": "home_comment", + "contentType": "image/png", + "version": 1 + } + ] + }, + "labels": [ + "encoding", + "test" + ] +} +``` + +## properties description + +### site + +| Attribute| Description | mandatory | +|-------------|----------------|--------------| +| space-key | space key (if set overrides the equivalent pom configuration) | no | + + +### home + +| Attribute| Description | mandatory | +|-------------|----------------|--------------| +| uri | Content's source | no | +| name | Title of page | no (if uri is defined)| +| parentPageId | parent page id (if set overrides the equivalent pom configuration) | no | +| parentPage | parent page name (if set overrides the equivalent pom configuration) | no | +| ignoreVariables | if it is `true` the variables `${...}` are not injected during page processing | no | + +### children array + +`children` is an array of object with the following schema: + +| Attribute| Description | mandatory | +|-------------|----------------|--------------| +| uri | Content's source | no | +| name | Title of page | no (if uri is defined)| +| parentPage | parent page name (if set overrides the equivalent pom configuration) | no | +| ignoreVariables | if it is `true` the variables `${...}` are not injected during page processing | no | + +### attachments array + +`attachments` is an array of object with the following schema: + + Attribute| Description | mandatory + ---- | ----- | ---- + uri | Content's source or a **directory** | no + name | Name of attachment or a [glob pattern][1] | no (if uri is defined) + comment | | no + contentType | | yes + version | | no + +#### Directory support + +from version `5.0-rc4` the `attachment` supports also the file inclusion from directory + +**Example** + +```json +"attachments": [ + { + "name": "*.png", + "uri": "myfolder", + "comment": "file from myfolder", + "contentType": "image/png", + "version": 1 + }, + { + "uri": "myfolder", + "comment": "file from myfolder", + "contentType": "image/png", + "version": 1 + } +] + +``` + +### labels array + +`labels` is an array of string + +## Note: + +### The **URI** format + +The **uri** attribute could refer to + +* **File** resource +> We can refer to file in **absolute** way using **file** scheme (e.g. ` file:///Documents/page.confluence `) or in **relative** way not using any scheme. In that case the path will be resolved starting from **site home** + +* **Classpath** resource +> We can refer to resource using **classpath** schema. (e.g. ` classpath:page.confluence `) + +* **Network** resource +> We can refer to resource using **http** scheme. (e.g. ` http://www.thesite.com/page.confluence `) + +## Using Freemarker in the Site Definition +See YAML definition for details. Freemarker is not dependent on the output format and can be used in the same fashion. + +[1]: https://docs.oracle.com/javase/7/docs/api/java/nio/file/FileSystem.html#getPathMatcher(java.lang.String) \ No newline at end of file diff --git a/plugin-reporting/src/site/markdown/site_xml_guide.md b/plugin-reporting/src/site/markdown/site_xml_guide.md index e1f9ed91..021dcf7f 100644 --- a/plugin-reporting/src/site/markdown/site_xml_guide.md +++ b/plugin-reporting/src/site/markdown/site_xml_guide.md @@ -1,9 +1,9 @@ # Introduction -From release 3.3.0 we can describe a complete site's layout using an xml file. Through site schema you can set root page (called home) its children's tree, add attachments and labels. +From release 3.3.0 we can describe a complete site's layout using a **xml format**. Through site schema you can set root page (called home) its children's tree, add attachments and labels. -Use it is pretty straightforward, put your **`site.xml`** in **`${basedir}/src/site/confluence`** folder and describe your preferred layout following the [site schema](https://raw.githubusercontent.com/bsorrentino/maven-confluence-plugin/master/schemas/site-schema-6.0.xsd). +Use it is pretty straightforward, put your **`site.xml`** in **`${basedir}/src/site/confluence`** folder and describe your preferred layout following the [site schema](https://raw.githubusercontent.com/bsorrentino/maven-confluence-plugin/master/schemas/site-schema-6.9.xsd). ## Site template diff --git a/plugin-reporting/src/site/site.xml b/plugin-reporting/src/site/site.xml index a7383871..d7652a13 100644 --- a/plugin-reporting/src/site/site.xml +++ b/plugin-reporting/src/site/site.xml @@ -22,6 +22,7 @@ + diff --git a/pom.xml b/pom.xml index dce44936..03dc2f46 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.bsc.maven maven-confluence-parent pom - 7.6 + 7.7 CONFLUENCE-REPORTING::Parent Maven's plugin that allow to generate "project's documentation" directly to confluence allowing, in the same time, to keep in-sync both project & documentation @@ -88,7 +88,7 @@ 1.8 1.8 - 1.5.20 + 1.6.0 @@ -138,7 +138,7 @@ org.codehaus.plexus plexus-utils - 3.0.8 + 3.0.16 org.apache.maven.plugin-tools diff --git a/processor-commonmark/pom.xml b/processor-commonmark/pom.xml index 0ce0b1bc..e62d5b07 100644 --- a/processor-commonmark/pom.xml +++ b/processor-commonmark/pom.xml @@ -5,7 +5,7 @@ maven-confluence-parent org.bsc.maven - 7.6 + 7.7 4.0.0 diff --git a/processor-freemarker/pom.xml b/processor-freemarker/pom.xml index a7a71bff..b854a493 100644 --- a/processor-freemarker/pom.xml +++ b/processor-freemarker/pom.xml @@ -5,7 +5,7 @@ org.bsc.maven maven-confluence-parent - 7.6 + 7.7 maven-confluence-processor-freemarker CONFLUENCE-REPORTING::Freemaker::Processor diff --git a/schemas/site-schema-7.7.json b/schemas/site-schema-7.7.json new file mode 100644 index 00000000..e7b5504b --- /dev/null +++ b/schemas/site-schema-7.7.json @@ -0,0 +1,84 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "home": { + "type": "object", + "properties": { + "uri": { + "type": "string" + }, + "children": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "attachments": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "comment": { + "type": "string" + }, + "contentType": { + "type": "string" + }, + "version": { + "type": "number" + } + } + } + } + }, + "required": [ + "name", + "uri" + ] + } + }, + "attachments": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "comment": { + "type": "string" + }, + "contentType": { + "type": "string" + }, + "version": { + "type": "number" + } + } + } + } + } + }, + "labels": { + "type": "array", + "items": { + "type": "string" + } + } + } +} diff --git a/service-rest-api/pom.xml b/service-rest-api/pom.xml index 8765b75c..024e02a6 100644 --- a/service-rest-api/pom.xml +++ b/service-rest-api/pom.xml @@ -5,7 +5,7 @@ maven-confluence-parent org.bsc.maven - 7.6 + 7.7 4.0.0 diff --git a/service-xmlrpc-api/pom.xml b/service-xmlrpc-api/pom.xml index b7afea71..5e285526 100644 --- a/service-xmlrpc-api/pom.xml +++ b/service-xmlrpc-api/pom.xml @@ -5,7 +5,7 @@ maven-confluence-parent org.bsc.maven - 7.6 + 7.7 4.0.0 diff --git a/test-plugin/pom.xml b/test-plugin/pom.xml index 21aa67da..7505f4b0 100644 --- a/test-plugin/pom.xml +++ b/test-plugin/pom.xml @@ -6,7 +6,7 @@ maven-confluence-parent org.bsc.maven - 7.6 + 7.7 diff --git a/test-publishing/pom.xml b/test-publishing/pom.xml index ca4c72ed..467b97c7 100644 --- a/test-publishing/pom.xml +++ b/test-publishing/pom.xml @@ -3,7 +3,7 @@ maven-confluence-parent org.bsc.maven - 7.6 + 7.7 4.0.0