Skip to content

#47 #48

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 2, 2020
Merged

#47 #48

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ remote_theme: pmarsceill/just-the-docs
exclude:
- README.md
- SCRATCH.md
- api.md

##
## "just-the-docs" theme options
Expand Down
51 changes: 50 additions & 1 deletion docs/mapping/endpoint.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,53 @@ nav_order: 20

# Endpoint Mappings

todo
The global mapping variations are also available as explicit endpoint mappings. Instead of adding
the mapping in the global sections `map/types`, `map/parameters` and `map/responses` they can
be placed in the `map/paths` section as properties to an endpoint given by its path.

```yaml
map:

# path mappings, only valid for the given path
paths:

# the path
/foo:

# list of path specific mappings
types:
- from: ..
to: ..

# list of path specific parameter mappings, mapped by parameter name
parameters:
- name: ..
to: ..

# list of path specific content mappings, mapped by content type
responses:
- content: ..
to: ..

# another path
/foo2:

# list of path specific mappings
types:
- from: ..
to: ..

# list of path specific parameter mappings, mapped by parameter name
parameters:
- name: ..
to: ..

# list of path specific content mappings, mapped by content type
responses:
- content: ..
to: ..

```

The mappings defined as properties of an endpoint will be used only for this endpoint. They don't
have any effect on other endpoints.
4 changes: 3 additions & 1 deletion docs/mapping/global.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ A single global mapping can have the following properties:

**from** is the type name used in the OpenAPI description and names the type that should be replaced
by **to**. **to** is the fully qualified class name of the java type that should be used instead of
**from**. **generics** defines the list of types that should be used as generic type parameters to the
**from**.

**generics** defines the list of types that should be used as generic type parameters to the
java type given by **to**.


Expand Down
100 changes: 98 additions & 2 deletions docs/mapping/parameter.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,102 @@ parent: Type Mapping
nav_order: 13
---

# Parameter Mappings
# (global) Parameter Mappings

todo
Global parameter mapping will replace any usage of an OpenAPI type in the api description based on
the parameters **name** to the given java type.

It is defined like below and it should be added to the `map/parameters` section in the mapping.yaml
which is a list of global parameter mappings.

A single global parameter mapping can have the following properties:

```yaml
- name: ..
to: ..
generics:
- ..
- ..
```

**name** and **to** are required.

**name** is the name of an endpoint parameter used in the OpenAPI description that should be replaced
by **to**.

**to** is the fully qualified class name of the java type that should be used for all endpoint
parameters of name **name**.

**generics** defines the list of types that should be used as generic type parameters to the
java type given by **to**.

<div markdown="1">
**Important:**

Since the generatr will simply match the parameters by their name take care that all parameters of
that name should really use the same type!
</div>{: .note .important .mb-6}

## Example

Given the following (global) parameter mapping

```yaml
map:

# list of global parameter mappings, mapped by parameter name
parameters:
- name: date
to: java.time.ZonedDateTime
```

and an openapi.yaml with multiple endpoints having a parameter named "date"

```yaml
openapi: 3.0.2
info:
title: global parameter type mapping example
version: 1.0.0

paths:
/do-something:
get:
parameters:
- in: query
name: date
schema:
type: int32
responses:
'200':
description: none
content:
application/json:
schema:
type: object
properties:
prop:
type: string

/do-something-else:
get:
parameters:
- in: query
name: date
schema:
type: string
responses:
'200':
description: none
content:
application/json:
schema:
type: object
properties:
prop:
type: string
```

the generatr will use `java.time.ZonedDateTime` as java type for **all** parameters named "date" in
**all** endpoints that have a "date" parameter.

In the example both endpoints would use `java.time.ZonedDateTime` as java type for the "date" parameter.
87 changes: 85 additions & 2 deletions docs/mapping/response.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,89 @@ parent: Type Mapping
nav_order: 16
---

# Response Mappings
# (global) Response Mappings

todo
Global response mapping will replace the result type of an endpoint in the api description based on
its **content type** to the given java type.

It is defined like below and it should be added to the `map/responses` section in the mapping.yaml
which is a list of global response mappings.

A single global response mapping can have the following properties:

```yaml
- content: ..
to: ..
generics:
- ..
- ..
```

**content** and **to** are required.

**content** is the name of the content type of an endpoint response that should be replaced
by **to**.

**to** is the fully qualified class name of the java type that should be used for all endpoint
content types with name **content**.

**generics** defines the list of types that should be used as generic type parameters to the
java type given by **to**.

<div markdown="1">
**Important:**

Since the generatr will simply match the content type string take care that all responses of this
content type should really use the same type!

This is probably only useful for vendor content types. Globally mapping the content type for example
of `application/json` does not look like a good idea.
</div>{: .note .important .mb-6}


## Example

Given the following (global) response mapping

```yaml
map:

# list of global parameter mappings, mapped by parameter name
responses:
- content: application/vnd.something
to: com.github.hauner.openapi.Something
```

and an openapi.yaml with multiple endpoints returning their result as content type `application/vnd.something`

```yaml
openapi: 3.0.2
info:
title: global response content type mapping example
version: 1.0.0

paths:
/do-something:
get:
responses:
'200':
description: none ```
content:
application/vnd.something:
schema:
type: string

/do-something-else:
get:
responses:
'200':
description: none ```
content:
application/vnd.something:
schema:
type: string
```


the generatr will use `com.github.hauner.openapi.Something` as java type for **all** responses with
the content type `application/vnd.something`.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 the original authors
* Copyright 2019-2020 the original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,6 +16,7 @@

package com.github.hauner.openapi.spring.writer

import com.github.hauner.openapi.spring.model.datatypes.DataType
import com.github.hauner.openapi.spring.model.datatypes.StringEnumDataType
import com.github.hauner.openapi.support.Identifier

Expand All @@ -32,6 +33,14 @@ class StringEnumWriter {
headerWriter.write (target)
target.write ("package ${dataType.packageName};\n\n")

List<String> imports = collectImports (dataType.packageName, dataType)
imports.each {
target.write ("import ${it};\n")
}
if (!imports.isEmpty ()) {
target.write ("\n")
}

target.write ("public enum ${dataType.type} {\n\n")

def values = []
Expand Down Expand Up @@ -72,4 +81,14 @@ class StringEnumWriter {
target.write ("}\n")
}

List<String> collectImports(String packageName, DataType dataType) {
Set<String> imports = []
imports.add ('com.fasterxml.jackson.annotation.JsonCreator')
imports.add ('com.fasterxml.jackson.annotation.JsonValue')
imports.addAll (dataType.referencedImports)

new ImportFilter ().filter (packageName, imports)
.sort ()
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019 the original authors
* Copyright 2019-2020 the original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -152,6 +152,21 @@ public enum Foo {
throw new IllegalArgumentException(value);
}

""")
}

void "writes jackson imports" () {
def pkg = 'com.github.hauner.openapi'
def dataType = new StringEnumDataType(type: 'Foo', values: [], pkg: pkg)

when:
writer.write (target, dataType)

then:
target.toString ().contains ("""\
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;

""")
}

Expand Down
3 changes: 3 additions & 0 deletions src/testInt/resources/params-enum/generated/model/Bar.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

package generated.model;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;

public enum Bar {

BAR("bar"),
Expand Down
3 changes: 3 additions & 0 deletions src/testInt/resources/params-enum/generated/model/Foo.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

package generated.model;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;

public enum Foo {

FOO("foo"),
Expand Down