Can't use <xsl:evaluate> in Saxon 9.7 - saxon

I'm running the XML Maven Plugin with this POM fragment:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<version>1.0.1</version>
<executions>
<execution>
<goals>
<goal>transform</goal>
</goals>
</execution>
</executions>
<configuration>
<transformationSets>
<transformationSet>
<dir>${basedir}/target/xml</dir>
<stylesheet>${basedir}/target/typesetting/fop/xslt/PhotoBook-fo.xslt</stylesheet>
</transformationSet>
</transformationSets>
</configuration>
<dependencies>
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
<version>9.7.0-15</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
The stylesheet contains a feature, <xsl:evaluate>, that is part of XSLT 3.0, which I understand is supported in Saxon-HE 9.7.0. The stylesheet correctly declares the XSLT version:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
But processing this fragment:
<xsl:for-each select="xhtml:tr[1]/xhtml:td">
<xsl:element name="table-column" namespace="http://www.w3.org/1999/XSL/Format">
<xsl:attribute name="column-width">
<xsl:evaluate select="#width"/>
</xsl:attribute>
</xsl:element>
</xsl:for-each>
I get
[INFO] --- xml-maven-plugin:1.0.1:transform (default) # birds-portfolio-1 ---
Static error at xsl:evaluate on line 132 column 56 of xhtml5-fo.xslt:
XTSE0010: Unknown XSLT element: evaluate
What am I missing? Thanks.

Saxon 9.7 HE does not support any XSLT 3.0 language feature, you need PE or EE for that (http://saxonica.com/html/documentation/xsl-elements/evaluate.html). The only enhancement you get in 9.7 HE with version="3.0" stylesheets is access to XPath 3.0 expressions (like let) and functions (like serialize or parse-xml).
As for your code, are you sure you need xsl:evaluate? It seems
<xsl:attribute name="column-width" select="#width"/>
might suffice, unless your width attribute contains an XPath expression you need to evaluate.
I would even replace
<xsl:for-each select="xhtml:tr[1]/xhtml:td">
<xsl:element name="table-column" namespace="http://www.w3.org/1999/XSL/Format">
<xsl:attribute name="column-width">
<xsl:evaluate select="#width"/>
</xsl:attribute>
</xsl:element>
</xsl:for-each>
with
<xsl:for-each select="xhtml:tr[1]/xhtml:td">
<table-column xmlns="http://www.w3.org/1999/XSL/Format" column-width="{#width}"/>
</xsl:for-each>

Martin Honnen already helpfully pointed out (+1) that Saxon 9.7 HE doesn't support XSLT 3.0, but I wanted to add another possibility for future readers who may have problems in this area: If Saxon 9.7 EE or PE fails to find a proper license key, it appears to continue to work with reduced functionality, perhaps as it would under HE.
On the one hand, this sort of graceful degradation can be helpful, but on the other hand, it can also be confusing to licensed EE or PE users who don't expect this behavior when failing to properly place a license key file on a new machine setup.

Related

Issue with custom codegen with openapigenerator maven plugin?

I am working on custom codegen using maven openapi generator plugin. I created a custom code generator project which has one java class named CustomCodegen.java with extends SpringCodegen and I have overridden the processOpts method where I added a new .mustache file which will be generated as *Exception.java class.
package com.swagger.blog.codegen;
public class CustomCodegen extends SpringCodegen {
#Override
public void processOpts() {
apiTemplateFiles.put("emptyinputexception.mustache", "Exception.java");}
#Override
public String getName() {
return "custom";
}
I have registered a service under src/main/resources/META-INF/services and created a file named
org.openapitools.codegen.CodegenConfig with content com.
swagger.blog.codegen.CustomCodegen(class which has the code). The name of the jar is swagger-codegen.
<groupId>com.swagger.blog</groupId>
<artifactId>swagger-codegen</artifactId>
<version>1.0.0-SNAPSHOT</version>
Now I want to use this custom generator on my other project and create a stub out of it. As shown on the code block below, I have used "custom" as the generatorName from the name we set on the CustomCodegen class and the custom generator dependency is used on the dependencies section of the open api generator plugin. I did mvn clean install to generate stub out of it. But when i do mvn clean install i get an error--> "Exception in thread "main" java.util.ServiceConfigurationError: org.openapitools.codegen.CodegenConfig: Provider com.swagger.blog.codegen.CustomCodegen not found". I can only find one topic on similar error on internet https://github.com/swagger-api/swagger-codegen/issues/7518. Can someone help with this or provide a github repo with similar custom code generator or sample project please Thanks for taking time to read this. Any suggestions will be greatly appretiated. The openapi generator plugin looks like this:
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>6.0.0</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<!-- specify the OpenAPI spec -->
<inputSpec>${project.basedir}/src/main/resources/openapi.json</inputSpec>
<!-- target to generate java client code -->
<generatorName>custom</generatorName>
<!-- override the default library to jersey2 -->
<library>spring-boot</library>
<output>${project.build.directory}/generated-sources</output>
<templateDirectory>${project.basedir}/templates</templateDirectory>
<configOptions>
<dateLibrary>java8</dateLibrary>
<sourceFolder>main/java</sourceFolder>
<artifactId>hi</artifactId>
<groupId>swaggerhub</groupId>
<basePackage>com.something</basePackage>
<invokerPackage>com.something</invokerPackage>
<configPackage>com.something.config</configPackage>
<modelPackage>com.something.model</modelPackage>
<apiPackage>com.something.api</apiPackage>
</configOptions>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.swagger.blog</groupId>
<artifactId>swagger-codegen</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>

Map sap:quickinfo into generated Java entity with odata-core

I create an OData client from an EDMX file using com.sap.cloud.sdk.datamodel.odata-core
(https://sap.github.io/cloud-sdk/docs/java/features/odata/generate-typed-odata-v2-and-v4-client-for-java).
My EDMX file contains the properties with sap:quickinfo values like
<Property Name="NAME" sap:label="C-Name" sap:heading="CUST" sap:quickinfo="Customer Name" [...] >
The generated fields looks like this
#SerializedName("NAME")
#JsonProperty("NAME")
#Nullable
#ODataField(odataName = "NAME")
private String nAME;
and I need an additional annotation like #Quickinfo("Customer Name").
Is there any way I can get this quickinfo mapped into an annotation to the generated entity?
I use this parameters for the generator:
<plugin>
<groupId>com.sap.cloud.sdk.datamodel</groupId>
<artifactId>odata-generator-maven-plugin</artifactId>
<version>3.52.0</version>
<executions>
<execution>
<id>generate-consumption</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputDirectory>${project.basedir}/sap/</inputDirectory>
<outputDirectory>${project.build.directory}/generated-sources/sap/</outputDirectory>
<deleteOutputDirectory>true</deleteOutputDirectory>
<packageName>app.customers</packageName>
<defaultBasePath>sap/opu/odata/SAP/</defaultBasePath>
<compileScope>COMPILE</compileScope>
<serviceMethodsPerEntitySet>false</serviceMethodsPerEntitySet>
<nameSource>NAME</nameSource>
</configuration>
</execution>
</executions>
</plugin>
Disclaimer:
I'm a member of the SAP Cloud SDK for Java development team.
The SAP Cloud SDK's OpenApi generator is a wrapper of the open source OpenApi Generator (we are using version 5.0.0-beta3).
Therefore, our wrapper supports only features that are also supported by the mentioned open source variant.
Unfortunately, creating arbitrary Attribute classes for properties of the service specification is not a supported feature as of now.

Swagger generating code from YAML spec without annotations

I am generating Java 8 code from yaml file specifying my REST API. Models generated with some swagger annotations that I want to get rid of. Is it possible somehow? And maybe it will be possible in the nearest future ?
Rest models will be traveling through Camle routes, so I would like to use jaxrs annotations if any..
I am using openapi 3.0.0 version, so I have to use newest swagger maven codegen plugin (which I find 3.0.0-rc1 in maven repository)
I just don't want to have swagger specific annotations in classes. I used:
<generateModelDocumentation>false</generateModelDocumentation>
The generated model:
import io.swagger.annotations.ApiModel; //THIS IS NOT COMPILING and i dont need annotated models, just simple pojo classes or maybe some jaxb annotations instead swagger specific..
import io.swagger.annotations.ApiModelProperty;
/**
* The requested data to the service.
*/#ApiModel(description = "The requested data to the service.")
#javax.annotation.Generated(value = "io.swagger.codegen.languages.java.JavaClientCodegen", date = "*****")
public class MyCustomRequest {
........
}
The pom.xml plugin:
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>3.0.0-rc1</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/swagger/MyCustomSpecification.yaml</inputSpec>
<language>java</language>
<configOptions>
<dateLibrary>java8</dateLibrary>
<java8>true</java8>
<interfaceOnly>true</interfaceOnly>
<useJaxbAnnotations>false</useJaxbAnnotations>
</configOptions>
<generateApis>false</generateApis>
<generateApiTests>false</generateApiTests>
<generateModelTests>false</generateModelTests>
<generateModelDocumentation>false</generateModelDocumentation>
<generateSupportingFiles>false</generateSupportingFiles>
<generateApiDocumentation>false</generateApiDocumentation>
<modelPackage>${project.groupId}.swagger.model</modelPackage>
<apiPackage>${project.groupId}.swagger.api</apiPackage>
<invokerPackage>${project.groupId}.swagger.invoker</invokerPackage>
<library>resttemplate</library>
</configuration>
</execution>
</executions>
</plugin>

Generating JAXB components for WSDL using org.jvnet.jaxb2.maven2:maven-jaxb2-plugin

I am trying to follow the example given at http://spring.io/guides/gs/consuming-web-service, ofcourse, with the WSDL of my own. However, I am unable to see any JAXB classes being generated. There are no errors or useful debug information either.
What are the limitations or WSDL constructs that above example would not work?
Let me know if you need any further information.
Thank You
check your pom, there should be something along these line:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.8.1</version> <!-- I used version 0.8.1 since 0.8.2 is bugged and it throws the Exception
"Illegal pattern character 'g' "when using italian locale -->
<executions>
<execution>
<id>wsdl-generation</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources/wsdl</schemaDirectory>
<schemaIncludes>
<include>*.xsd</include>
</schemaIncludes>
<extension>true</extension>
<!-- Specify binding directory where we put customization for the
generated classes -->
<bindingDirectory>src/main/resources/binding</bindingDirectory>
<bindingIncludes>
<include>*.xjb</include>
</bindingIncludes>
</configuration>
</execution>
</executions>
</plugin>
with slight difference to match with your wsdl location/binding (if any)/etc..
Classes are generated under target, so ensure that you add them to the classpath (simply after you run the generate sources, do a maven -->update project and it should take care of it if i recall correctly)..
You might want to do a right click --> run as --> maven generate sources in case it seems it's not working properly.

Exclude Setters and Getters in JaCoCo Code Coverage

With the cobertura-maven-plugin setters and getters can be excluded from code coverage using the ignoreTrivial option. Is there also such a possibility with the jacoco-maven-plugin?
This is my current configuration:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.1.201405082137</version>
<configuration>
<excludes>
<exclude>com/welovecoding/web/blog/test/**/*.class</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>amend-unit-test-java-agent-option</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
From JaCoCo 0.8.0, it is possible to exclude the getters / setters (and also toString(), equals(), ...) automatically generated by Lombok from the coverage metrics thanks to filtering options :
Lombok
Methods annotated with #lombok.Generated (generated by Lombok getters, setters, equals, hashcode, toString, etc) - Done in 0.8.0
To that end, you will first need to create a lombok.config file located for example at the root folder of your projet, with the following contents :
lombok.addLombokGeneratedAnnotation = true
The #Generated annotation will be added to the setters / getters, etc. and will be skipped in the coverage analysis.
Not supported officialy, see comments in :
https://github.com/jacoco/jacoco/issues/15
mentioned solution:
It's a long time since this issue is opened. It a really interesting feature. For instance it's implemented in clover and corbetura. There are fork that implement filtering :
github.com/huangxiwei/jacoco ,
https://github.com/mchr3k/jacoco since the begining of the year. Why don't you merge those fork into master branch ? Even if all filtering is not implemented at start, main filters needed are listed in the wiki page you have written (Try with resources, sync block, enum static methods). Coverage is a very useful tool, more it's accruate more it's will be usefull. It helps alot when coverage reach a high value, it helps to focus on the right classes.
I recommend to use Cobertura that does not have such limitation and also does not have so many false positive warnings.

Resources