diff --git a/README.md b/README.md index 5f74d5f..f76e440 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,8 @@ As it is, documentation is pretty barren - but I wanted to make the module avail ## Using the Module ## +NOTE: The module is compiled against Enunciate 2.12.1. It fails building against the latest version (at present 2.13.1). + From Gradle you would do something like this: apply plugin: "com.webcohesion.enunciate" diff --git a/build.gradle b/build.gradle index 30e41b2..154687c 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ defaultTasks 'dist' // Setup to use Jyske Bank Nexus if present, otherwise use Maven Central ext { - enunciateVersion = "2.12.0" + enunciateVersion = "2.12.1" jacksonVersion = "2.10.1" diff --git a/src/main/java/dk/jyskebank/tools/enunciate/modules/openapi/ObjectTypeRenderer.java b/src/main/java/dk/jyskebank/tools/enunciate/modules/openapi/ObjectTypeRenderer.java index ee746ba..7830bad 100644 --- a/src/main/java/dk/jyskebank/tools/enunciate/modules/openapi/ObjectTypeRenderer.java +++ b/src/main/java/dk/jyskebank/tools/enunciate/modules/openapi/ObjectTypeRenderer.java @@ -57,14 +57,16 @@ public class ObjectTypeRenderer { private final EnunciateLogger logger; private final DataTypeReferenceRenderer datatypeRefRenderer; private final Set passThroughAnnotations; + private final Map namespacePrefixMap; private final boolean removeObjectPrefix; private final boolean disableExamples; - public ObjectTypeRenderer(EnunciateLogger enunciateLogger, DataTypeReferenceRenderer datatypeRefRenderer, Set passThroughAnnotations, boolean removeObjectPrefix, boolean disableExamples) { + public ObjectTypeRenderer(EnunciateLogger enunciateLogger, DataTypeReferenceRenderer datatypeRefRenderer, Set passThroughAnnotations, Map namespacePrefixMap, boolean removeObjectPrefix, boolean disableExamples) { this.logger = enunciateLogger; this.datatypeRefRenderer = datatypeRefRenderer; this.passThroughAnnotations = passThroughAnnotations; + this.namespacePrefixMap = namespacePrefixMap; this.removeObjectPrefix = removeObjectPrefix; this.disableExamples = disableExamples; } @@ -365,7 +367,12 @@ private void addOptionalXml(IndentationPrinter ip, DataType datatype) { Namespace namespace = datatype.getNamespace(); String xmlNamespace = getNonNullAndNonEmpty(namespace != null ? namespace.getUri() : null); - logger.debug("optionalXml for " + datatype.getLabel() + " : " + xmlName + " / " + xmlNamespace); + String namespacePrefix = null; + if (xmlNamespace != null && this.namespacePrefixMap != null && !this.namespacePrefixMap.isEmpty()) { + namespacePrefix = getNonNullAndNonEmpty(this.namespacePrefixMap.get(xmlNamespace)); + } + + logger.debug("optionalXml for " + datatype.getLabel() + " : " + xmlName + " / " + xmlNamespace + " / "+ namespacePrefix); if (xmlName != null || xmlNamespace != null) { ip.add("xml:"); @@ -376,6 +383,9 @@ private void addOptionalXml(IndentationPrinter ip, DataType datatype) { if (xmlNamespace != null) { ip.add("namespace: ", xmlNamespace); } + if (namespacePrefix != null) { + ip.add("prefix: ", namespacePrefix); + } ip.prevLevel(); } } diff --git a/src/main/java/dk/jyskebank/tools/enunciate/modules/openapi/OpenApiModule.java b/src/main/java/dk/jyskebank/tools/enunciate/modules/openapi/OpenApiModule.java index 329e057..c5f3a87 100644 --- a/src/main/java/dk/jyskebank/tools/enunciate/modules/openapi/OpenApiModule.java +++ b/src/main/java/dk/jyskebank/tools/enunciate/modules/openapi/OpenApiModule.java @@ -163,7 +163,7 @@ public void writeTo(File srcDir) throws IOException { protected void writeToFolder(File dir) throws IOException { EnunciateLogger logger = enunciate.getLogger(); DataTypeReferenceRenderer dataTypeReferenceRenderer = new DataTypeReferenceRenderer(logger, doRemoveObjectPrefix()); - ObjectTypeRenderer objectTypeRenderer = new ObjectTypeRenderer(logger, dataTypeReferenceRenderer, getPassThroughAnnotations(), doRemoveObjectPrefix(), disableExamples()); + ObjectTypeRenderer objectTypeRenderer = new ObjectTypeRenderer(logger, dataTypeReferenceRenderer, getPassThroughAnnotations(), getNamespacePrefixMap(), doRemoveObjectPrefix(), disableExamples()); OperationIds operationIds = new OperationIds(logger, enunciateModel); @@ -198,6 +198,17 @@ private boolean disableExamples() { private boolean doRemoveObjectPrefix() { return Boolean.parseBoolean(config.getString("[@removeObjectPrefix]")); } + + /** + * Get namespace prefix map from enunciate configuration, return empty map if configuration is invalid. + * @return namespacePrefixMap + */ + private Map getNamespacePrefixMap(){ + if(enunciate.getConfiguration() == null){ + return Collections.emptyMap(); + } + return enunciate.getConfiguration().getNamespaces(); + } } protected String getHost() { diff --git a/src/test/java/dk/jyskebank/tools/enunciate/modules/openapi/ObjectTypeRendererTest.java b/src/test/java/dk/jyskebank/tools/enunciate/modules/openapi/ObjectTypeRendererTest.java index 6159109..3e13d80 100644 --- a/src/test/java/dk/jyskebank/tools/enunciate/modules/openapi/ObjectTypeRendererTest.java +++ b/src/test/java/dk/jyskebank/tools/enunciate/modules/openapi/ObjectTypeRendererTest.java @@ -1,8 +1,11 @@ package dk.jyskebank.tools.enunciate.modules.openapi; +import com.webcohesion.enunciate.api.InterfaceDescriptionFile; import com.webcohesion.enunciate.api.datatype.BaseType; import com.webcohesion.enunciate.api.datatype.DataType; import com.webcohesion.enunciate.api.datatype.DataTypeReference; +import com.webcohesion.enunciate.api.datatype.Namespace; +import com.webcohesion.enunciate.modules.jaxb.api.impl.ComplexDataTypeImpl; import dk.jyskebank.tools.enunciate.modules.openapi.yaml.IndentationPrinter; import org.junit.jupiter.api.Test; @@ -19,12 +22,15 @@ class ObjectTypeRendererTest { public static final String CONCRETE_TYPE_LABEL = "ConcreteX"; + public static final String CONCRETE_TYPE_XML_NAME = "xml_xmlns_concreteX"; + public static final String CONCRETE_TYPE_XML_URI = "http://www.w3.org/2000/xmlns/"; + public static final String CONCRETE_TYPE_XML_PREFIX = "xmlns"; @Test void verifyRenderAbstractType() { ObjectTypeRenderer objectTypeRenderer = new ObjectTypeRenderer(new OutputLogger(), null - , null, false, false); + , null, null, false, false); IndentationPrinter ip = TestHelper.getIndentationPrinter(); DataType abstractType = getAbstractTypeWithTwoSubtypes(); @@ -39,7 +45,7 @@ void verifyRenderAbstractType() { @Test void verifyRenderConcreteType() { ObjectTypeRenderer objectTypeRenderer = new ObjectTypeRenderer(new OutputLogger(), null - , null, false, false); + , null, null, false, false); IndentationPrinter ip = TestHelper.getIndentationPrinter(); DataType concreteType = getConcreteType(); @@ -51,6 +57,82 @@ void verifyRenderConcreteType() { } + @Test + void verifyRenderConcreteTypeNamespacePrefix(){ + ObjectTypeRenderer objectTypeRenderer = new ObjectTypeRenderer(new OutputLogger(), null + , null, Collections.singletonMap(CONCRETE_TYPE_XML_URI,CONCRETE_TYPE_XML_PREFIX), false, false); + + IndentationPrinter ip = TestHelper.getIndentationPrinter(); + DataType concreteType = getConcreteTypeWithNamespace(); + + objectTypeRenderer.render(ip, concreteType, false); + + final String expected = createExpectedResultForConcreteTypeWithNamespacePrefix(); + assertEquals(expected, ip.toString()); + } + + @Test + void verifyRenderConcreteTypeWithoutNamespacePrefix(){ + ObjectTypeRenderer objectTypeRenderer = new ObjectTypeRenderer(new OutputLogger(), null + , null, null, false, false); + + IndentationPrinter ip = TestHelper.getIndentationPrinter(); + DataType concreteType = getConcreteTypeWithNamespace(); + + objectTypeRenderer.render(ip, concreteType, false); + + final String expected = createExpectedResultForConcreteTypeWithoutNamespacePrefix(); + assertEquals(expected, ip.toString()); + } + + private ComplexDataTypeImpl getConcreteTypeWithNamespace() { + ComplexDataTypeImpl mockedDataType = mock(ComplexDataTypeImpl.class); + when(mockedDataType.isAbstract()).thenReturn(Boolean.FALSE); + + when(mockedDataType.getLabel()).thenReturn(CONCRETE_TYPE_LABEL); + when(mockedDataType.getXmlName()).thenReturn(CONCRETE_TYPE_XML_NAME); + when(mockedDataType.getBaseType()).thenReturn(BaseType.string); + + Namespace customNamespace = new Namespace() { + @Override + public String getUri() { + return CONCRETE_TYPE_XML_URI; + } + @Override + public InterfaceDescriptionFile getSchemaFile() { + return null; + } + @Override + public List getTypes() { + return null; + } + }; + when(mockedDataType.getNamespace()).thenReturn(customNamespace); + + return mockedDataType; + } + + private String createExpectedResultForConcreteTypeWithNamespacePrefix() { + String DOS_NEWLINE = "\r\n"; + return String.format("title: \"%s\"%s%s type: string%s%s xml:%s%s name: %s%s%s namespace: %s%s%s prefix: %s", + CONCRETE_TYPE_LABEL, DOS_NEWLINE, TestHelper.INITIAL_INDENTATION, + DOS_NEWLINE, TestHelper.INITIAL_INDENTATION, + DOS_NEWLINE, TestHelper.INITIAL_INDENTATION, + CONCRETE_TYPE_XML_NAME, DOS_NEWLINE, TestHelper.INITIAL_INDENTATION, + CONCRETE_TYPE_XML_URI, DOS_NEWLINE, TestHelper.INITIAL_INDENTATION, + CONCRETE_TYPE_XML_PREFIX, DOS_NEWLINE, TestHelper.INITIAL_INDENTATION); + } + + private String createExpectedResultForConcreteTypeWithoutNamespacePrefix() { + String DOS_NEWLINE = "\r\n"; + return String.format("title: \"%s\"%s%s type: string%s%s xml:%s%s name: %s%s%s namespace: %s", + CONCRETE_TYPE_LABEL, DOS_NEWLINE, TestHelper.INITIAL_INDENTATION, + DOS_NEWLINE, TestHelper.INITIAL_INDENTATION, + DOS_NEWLINE, TestHelper.INITIAL_INDENTATION, + CONCRETE_TYPE_XML_NAME, DOS_NEWLINE, TestHelper.INITIAL_INDENTATION, + CONCRETE_TYPE_XML_URI, DOS_NEWLINE, TestHelper.INITIAL_INDENTATION); + } + private String createExpectedResultForConcreteType() { String DOS_NEWLINE = "\r\n"; return String.format("title: \"%s\"%s%s type: string",