Maven site generation using advanced Markdown? - maven

We are using Markdown in our Maven generated site. Works like a charm. AFAIK the plugin uses Flexmark under the hood, which supports the Admonition extensions.
We would like to use them too, the infoboxes are quite helpful for documentation. Our site configuration in the pom.xml looks like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.8.2</version>
</plugin>
How could we configure it to recognise the additional markdown?

This question is a little old but I have been trying to figure this out for using the Gitlab extension for math equations and the short answer is I don't think you can do it out of the box.
The maven-site-plugin uses the doxia-module-markdown module for markdown which uses Flexmark internally but it is pre-configured with the extensions that it uses for this.
Here's a link to the code and the exact snippet from
// Initialize the Flexmark parser and renderer, once and for all
static
{
MutableDataSet flexmarkOptions = new MutableDataSet();
// Enable the extensions that we used to have in Pegdown
flexmarkOptions.set( com.vladsch.flexmark.parser.Parser.EXTENSIONS, Arrays.asList(
EscapedCharacterExtension.create(),
AbbreviationExtension.create(),
AutolinkExtension.create(),
DefinitionExtension.create(),
TypographicExtension.create(),
TablesExtension.create(),
WikiLinkExtension.create(),
StrikethroughExtension.create()
) );
// ...
}
I think that you could possibly fork this project, add the extensions you need, and add it as a dependency to the maven-site-plugin and it might work like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.8.2</version>
<dependencies>
<dependency>
<groupId>${my-forked-groupId}</groupId>
<artifactId>${my-forked-artifactId}</artifactId>
<version>${my-forked-version}</version>
</dependency>
</dependencies>
</plugin>
This in my opinion is less than ideal and I will probably be exploring other (non-maven) options to get the result I'm looking for but will probably still try this out in the next day or so and if I get it working I'll send a link to the code in case anybody else can benefit from it.

Related

Maven property overriding conflict between parent/bom

I am currently facing an issue with my maven configuration. I was thinking it will work in a way where versions in MyBom will have higher priority on the grand-grand-parent defined versions.
This is the setup :
enter image description here
In spring-dependencies, I have this version <atomikos.version>4.0.6</atomikos.version>.
In myBom, I have this version <atomikos.version>5.0.106</atomikos.version>.
Both spring-dependencies and MyBom have the
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jta</artifactId>
<version>${atomikos.version}</version>
</dependency>
I have imported the bom as usual in "MyParent":
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.test</groupId>
<artifactId>myBom</artifactId>
<version>${myBom.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Finally, in "MyProject", when I am showing the effective pom, it uses the version 4.0.6 coming from the spring-dependencies.
I was expecting the version to be 5.0.106 as the bom redefine it in a sublayer.
Note that it can work with any dependency which is common between bom and parent.
So, currently, my only viable solution is to manually set the the version in "MyParent" which is making the creation of "MyBom" useless...
Can you confirm what is correct ? My assumption (meaning I have a misconfiguration somewhere) or the current behavior, meaning "MyBom" is worthless.
As far as I know, "direct" entries in the dependencyManagement always take precedent over BOMs, not matter what the inheritance level is.
You should probably just override the <atomikos.version> property.
This is not possible to override parents version from "MyBom" project. The only solution is to remove the spring-boot-starter-parent as parent and import the spring-dependencies at same level of "MyBom" import.
I found the solution but I would like to thank #J Fabian Meyer to also point the correct solution.
The dependencyManagement is just a declaration of what the version of the dependency should be when really used as a project dependency. Thus you still should declare (use) the myBom dependency. Also, the scope "import" is invalid.
See the documentation
https://maven.apache.org/pom.html#dependency-management
https://maven.apache.org/pom.html#Dependencies

When should I use mapstruct or converters with java 8 to avoid error-prone?

At work, we use MapStruct in many SpringBoot projects with Java 8 REST Full applications and when we need to map Entity to DTO or DTO to Response or in similar cases. But today my friend showed me a great advantage of using a simple Converter instead of MapStruct.
This is a simple example using MapStrurct:
#Mapper(componentModel="spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface AccountMapper {
#Mapping(source = "customerBank.customerId", target = "customerId")
AccountResponse toResponse(AccountBank accountBank);
}
It works perfectly but actually in the case of someone change the customerId attribute by another name and forgets to change this mapper we will have a Runtime error.
The pros for Converter is we will have a Compile time error and avoid Runtime error.
Please, let me know if someone managed to share how to avoid Runtime error, like my presented scenario, using MapStruct, due to Converter does not bring the same advantage.
My question is: Is it possible to use MapStruct with efficiency, I mean without Runtime error prone?
If I understand well, you would like to have a compile-time error for wrong property naming, using MapStruct custom mapping.
If so, you should add a necessary build plugin in your pom.xml (if you use maven).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
And of course declare a property for MapStruct version:
<properties>
<mapstruct.version>1.4.1.Final</mapstruct.version>
</properties>
After compiling the project, with the added plugin, the annotation processor will generate full implementation:
public class AccountMapperImpl implements AccountMapper
In target\generated-sources\annotations folder.
You can check generated source of the implementation class, all is set and carefully checked.
In case of unexisting property names in #Mapping annotation, the compiler will throw an error.

Update code generated by Swagger code-gen

I have generated the code from swagger.yaml file using swagger code-gen in spring.
Now I have updated the swagger.yaml file for my API and added few more HTTP operations.
Will it be possible to update the existing code generated previously automatically without merging it manually?
I guess you are talking about the Controllers generated by codegen, that you have then implemented. They are overwritten after each generation, which means you will have to manually merge the code to add the changes every time... which is really annoying.
Well the best workflow I could find was to use the interfaceOnly option to generate only the model and interface classes in the target directory, and then manually create the controllers that implement those interfaces.
Lets say you update your API specification file with one more GET operation, the interface is regenerated with that new operation and you will just have to adjust your controller to implement that new method (super quick and easy with modern IDE), everything else remain the same and you have more control over your code (splitting controllers in different folders...etc...).
Here is config I used for the plugin:
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>2.2.3</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>./api-contract/petstore.yml</inputSpec>
<language>spring</language>
<configOptions>
<sourceFolder>swagger</sourceFolder>
<java8>true</java8>
<interfaceOnly>true</interfaceOnly>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
You can check a complete example project using Spring Boot with swagger-codegen-maven-plugin here.
Cheers
Having the same issue, I found the solution to start with by applying git
commit the current status
run the generator
use git to stage the intended changes but do not stage reversal of your manual edits
commit and continue
I just start with this approach but it seems to work at least for php-slim where only one file (index.php) is changed when regenerating.

How to enable Rhino (or any JavaScript Engine) in CQ 5.6?

I have some custom logic where I need to evaluate a simple boolean expression. In my IDE I have some unit tests that run fine, but when I'm trying to use it on my CQ 5.6.1 instance, the ScriptEngineManager can't find a JavaScript engine. Though this should be part of a standard java installation on any environment.
ScriptEngineManager sef = new ScriptEngineManager();
ScriptEngine se = sef.getEngineByName("JavaScript");
In the pom I have the following which usually helps:
<Import-Package>*;resolution:=optional</Import-Package>
Usually some system libraries aren't exposed in OSGi when you don't put it into the bootdelegation in the sling.properties, but this didn't work either:
org.osgi.framework.bootdelegation=org.w3c.*,com.sun.script.*,com.yourkit.*, ${org.apache.sling.launcher.bootdelegation}
What else could I try?
EDIT:
Also regarding my comment to Christians answer. I found out that there should be a service in the OSGi:
http://svn.apache.org/repos/asf/sling/trunk/bundles/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineFactory.java
But when I try to reference it with the following code, my servlet isn't active anymore:
#Reference
private transient ScriptEngineFactory sef = null;
So it seems it can't inject the factory for some reason. I've seen there could be more than one service implementing this interface, how would I target the correct one (linked above)?
EDIT2:
I now even tried to reference the Rhino factory directly:
#Reference(target = "(component.name=org.apache.sling.scripting.javascript.internal.RhinoJavaScriptEngineFactory)")
private transient ScriptEngineFactory sef = null;
With this my servlet tells me it is satisfied:
["Satisfied","Service Name: javax.script.ScriptEngineFactory","Target Filter: (component.name=org.apache.sling.scripting.javascript.internal.RhinoJavaScriptEngineFactory)","Multiple: single","Optional: mandatory","Policy: static","Bound Service ID 2004 (org.apache.sling.scripting.javascript.internal.RhinoJavaScriptEngineFactory)"]
But if I access my servlet it doesn't get triggered and the SlingDefaultServlet takes over. Without the above #Reference it is accessible, so it has to do something with it.
You need an OSGi capable ScriptEngineManager. See https://devnotesblog.wordpress.com/2011/09/07/scripting-using-jsr-223-in-an-osgi-environment/
After almost a whole day of trial and error I found 2 major problems:
First: My compiler plugin was set to use 1.8; I had to revert that to 1.6 so my maven-scr-plugin would create proper manifests again and injection of OSGi services actually works:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
I have to investigate later how it would be possible to increase that to at least 1.7 (I tried but didn't work either).
Second and the actual answer for my question is simple:
#Reference
private transient ScriptEngineManager sem = null;
Also I had to use javascript instead of JavaScript for the getEngineByName method from the manager. To see what is registered for the engine, you can check out the following path in your OSGi console:
/system/console/status-slingscripting
There all available ScriptEngine are listed with their registered names, extensions and MIME Types.

Integrate Activiti Modeler using Maven

How one can integrate Activiti Modeler into their own web application and keep all the advantages Maven suggests?
The probem is that Activiti Modeler in Maven is part of Activiti Explorer. There are several questions online from people who want to develop their own web applications, use Modeler to edit the processes, but don't need other Explorer features.
For example, Activiti BPM without activiti-explorer or How To Integrate Activiti Modeller Into own Web Application
I have managed to do this using Maven overlay feature:
1) include overlay of Explorer web app, but include only the Modeler files:
pom.xml:
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-webapp-explorer2</artifactId>
<version>${activiti-version}</version>
<type>war</type>
<scope>compile</scope>
</dependency>
....
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<overlays>
<overlay>
<groupId>org.activiti</groupId>
<artifactId>activiti-webapp-explorer2</artifactId>
<includes>
<include>WEB-INF/classes/stencilset.json</include>
<include>editor-app/**</include>
<include>modeler.html</include>
</includes>
</overlay>
</overlays>
</configuration>
</plugin>
2) add modeler Spring resources. They are used to retrieve and to save models (note: not process definitions, it's kinda different thing) and also to serve the stencilset:
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-modeler</artifactId>
<version>${activiti-version}</version>
</dependency>
3) that would be it but it won't actually work in your application unless it is called "activiti-explorer". Add a file to your project called "editor-app/app-cfg.js", and add the following content there:
editor-app/app-cfg.js:
'use strict';
var ACTIVITI = ACTIVITI || {};
ACTIVITI.CONFIG = {
'contextRoot' : window.location.pathname.substring(0,window.location.pathname.lastIndexOf('/')),
};
This is actually a copy of the native app-cfg, which contains the strange "/activiti-explorer/service" setting for context root. We change it to more generic setting. It will be used to retrieve models from the repository. Our file will overlay the one that ships with explorer webapp.
Notes:
a) you have to manage conversion of process definitions to models by yourselves. For an idea, see https://github.com/Activiti/Activiti/blob/activiti-5.19.0.1/modules/activiti-explorer/src/main/java/org/activiti/editor/ui/ConvertProcessDefinitionPopupWindow.java
b) I had to avoid using one Jackson Object Mapper for everything, I haven't research why this didn't work:
<bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper">
</bean>
<mvc:annotation-driven>
<!-- using the same objectMapper leads to stencilset resource being served as string -->
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="objectMapper"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
Don't do this or research more, as this actually breaks the stencilcet resurce serving part of the "activiti-modeler". It starts serving stencilset as a malformed string instead normal json.
c) I had no idea how to inject CSRF security headers in the Modeler saving function, so I switched it off - if you don't use Spring Security, discard this

Resources