Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
java: ['17', '21', '25']
java: ['21', '25']
name: Build on Java ${{ matrix.java }}
steps:
- name: Checkout
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- name: Setup java
uses: actions/setup-java@v5
with:
java-version: 17
java-version: 21
distribution: 'temurin'
cache: 'maven'
server-id: central
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Setup java
uses: actions/setup-java@v5
with:
java-version: 17
java-version: 21
distribution: 'temurin'
cache: 'maven'
- name: Get latest fixed open api definition
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]
- Update to okhttp `5.3.2`
- Requiring Java 21

## [4.3.2]
- Remove `followers` property from `PlaylistUser` object
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
</developers>

<properties>
<java.version>17</java.version>
<java.version>21</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static void splitEndpoints(SpotifyWebApi spotifyWebApi) {
endpoint.getScopes(),
false
);
reorderEndpoint.addPathParameter(endpoint.getRequiredPathParameters().get(0), true);
reorderEndpoint.addPathParameter(endpoint.getRequiredPathParameters().getFirst(), true);
endpoint.getOptionalBodyParameters().stream()
.filter(param -> List.of("range_start", "insert_before", "range_length", "snapshot_id").contains(param.getName()))
.forEach(param -> reorderEndpoint.addBodyParameter(param, List.of("range_start", "insert_before").contains(param.getName())));
Expand All @@ -42,7 +42,7 @@ public static void splitEndpoints(SpotifyWebApi spotifyWebApi) {
endpoint.getScopes(),
false
);
replaceEndpoint.addPathParameter(endpoint.getRequiredPathParameters().get(0), true);
replaceEndpoint.addPathParameter(endpoint.getRequiredPathParameters().getFirst(), true);
endpoint.getOptionalQueryParameters().stream()
.filter(param -> "uris".equals(param.getName()))
.forEach(param -> replaceEndpoint.addQueryParameter(param, false));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,25 +94,24 @@ private String generateApiObject(String openApiName, Schema schema) {
if (composedSchema.getAllOf() != null) {
var allOf = composedSchema.getAllOf();
if (allOf.size() == 1) {
if (allOf.get(0).get$ref().equals("#/components/schemas/PagingObject")) {
var ref = allOf.getFirst().get$ref();
if (ref.equals("#/components/schemas/PagingObject")) {
var itemsSchema = (ArraySchema) composedSchema.getProperties().get("items");
var itemsSchemaName = OpenApiUtils.getSchemaName(itemsSchema.getItems().get$ref());
var itemsObjectName = getObjectNameOrGenerate(itemsSchemaName, itemsSchema.getItems());
return "Paging<" + itemsObjectName + ">";
}

if (allOf.get(0).get$ref() != null) {
var referencedSchemaName = OpenApiUtils.getSchemaName(allOf.get(0).get$ref());
var referencedObjectName = getObjectNameOrGenerate(referencedSchemaName, allOf.get(0));
var apiObject = ApiObject.builder()
.name(objectName)
.openApiName(openApiName)
.superClassName(referencedObjectName)
.description(composedSchema.getDescription())
.build();
this.schemaObjects.put(objectName, apiObject);
return objectName;
}
var referencedSchemaName = OpenApiUtils.getSchemaName(ref);
var referencedObjectName = getObjectNameOrGenerate(referencedSchemaName, allOf.getFirst());
var apiObject = ApiObject.builder()
.name(objectName)
.openApiName(openApiName)
.superClassName(referencedObjectName)
.description(composedSchema.getDescription())
.build();
this.schemaObjects.put(objectName, apiObject);
return objectName;
}
if (allOf.size() == 2) {
if (allOf.get(0).get$ref().equals("#/components/schemas/PagingObject")) {
Expand All @@ -128,7 +127,7 @@ private String generateApiObject(String openApiName, Schema schema) {
return "CursorPaging<" + itemsObjectName + ">";
}

if (allOf.get(0).get$ref() != null && allOf.get(1) instanceof ObjectSchema objectSchema) {
if (allOf.get(1) instanceof ObjectSchema objectSchema) {
var referencedSchemaName = OpenApiUtils.getSchemaName(allOf.get(0).get$ref());
var referencedObjectName = getObjectNameOrGenerate(referencedSchemaName, allOf.get(0));

Expand Down Expand Up @@ -169,8 +168,8 @@ private ApiObject.Property generateApiObjectProperty(String objectName, String n

var resolvedSchema = generationContext.resolveSchema(schema);
if (resolvedSchema instanceof ComposedSchema composedSchema && composedSchema.getAllOf() != null && composedSchema.getAllOf().size() == 1 && composedSchema.getProperties() == null) {
var innerSchemaName = OpenApiUtils.getSchemaName(composedSchema.getAllOf().get(0).get$ref());
var innerSchema = generationContext.resolveSchema(composedSchema.getAllOf().get(0).get$ref());
var innerSchemaName = OpenApiUtils.getSchemaName(composedSchema.getAllOf().getFirst().get$ref());
var innerSchema = generationContext.resolveSchema(composedSchema.getAllOf().getFirst().get$ref());
var innerType = JavaUtils.getPrimitiveTypeOfSchema(innerSchema)
.orElse(innerSchemaName.replace("Object", ""));

Expand Down Expand Up @@ -253,7 +252,7 @@ private void fixContextForPaging(Map<String, Object> context) {
context.put("className", context.get("className") + "<T>");
@SuppressWarnings("unchecked")
var properties = (List<Map<String, Object>>)context.get("properties");
properties.add(0, Map.of(
properties.addFirst(Map.of(
"fieldName", "items",
"hasDescription", true,
"description", List.of("<p>The requested data.</p>"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public void generate() {
private Map<String, Object> createContext(OpenAPI openAPI, JavaPackage javaPackage) {
var context = new HashMap<String, Object>();
context.put("package", javaPackage.getName());
context.put("endpointUrl", openAPI.getServers().get(0).getUrl());
context.put("endpointUrl", openAPI.getServers().getFirst().getUrl());

var apis = openAPI.getPaths().values().stream()
.flatMap(pathItem -> pathItem.readOperationsMap().values().stream())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ public static JavaPackage fromNames(String... packageNames) {
public static JavaPackage fromPackage(String packageName) {
Preconditions.checkArgument(packageName != null);
var packageNames = packageName.split("\\.");
Preconditions.checkArgument(isValidJavaPackageName(packageNames), "Invalid java package");
return new JavaPackage(packageNames);
return fromNames(packageNames);
}

private static boolean isValidJavaPackageName(String[] packageNames) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,52 +97,57 @@ public static Optional<String> getTypeOfSchema(Schema<?> schema) {
// if no format is present, use single precision floating point number, for compatability reasons
return Optional.of("Float");
}
if (schema instanceof ArraySchema arraySchema) {
return getTypeOfSchema(arraySchema.getItems())
switch (schema) {
case ArraySchema arraySchema -> {
return getTypeOfSchema(arraySchema.getItems())
.map(itemsType -> "java.util.List<" + itemsType + ">")
.or(() -> Optional.of("java.util.List<java.util.Map<String, Object>>"));
}
if (schema instanceof ComposedSchema composedSchema) {
var allOf = composedSchema.getAllOf();
if (allOf != null) {
if (allOf.size() == 1) {
if (allOf.get(0).get$ref().equals("#/components/schemas/PagingObject")) {
var itemsSchema = (ArraySchema) schema.getProperties().get("items");
return getTypeOfSchema(itemsSchema.getItems())
}
case ComposedSchema composedSchema -> {
var allOf = composedSchema.getAllOf();
if (allOf != null) {
if (allOf.size() == 1) {
if (allOf.getFirst().get$ref().equals("#/components/schemas/PagingObject")) {
var itemsSchema = (ArraySchema) schema.getProperties().get("items");
return getTypeOfSchema(itemsSchema.getItems())
.map(itemsType -> "Paging<" + itemsType + ">");
}
}
}
if (allOf.size() == 2) {
if (allOf.get(0).get$ref().equals("#/components/schemas/PagingObject")) {
var itemsSchema = (ArraySchema) allOf.get(1).getProperties().get("items");
return getTypeOfSchema(itemsSchema.getItems())
if (allOf.size() == 2) {
if (allOf.get(0).get$ref().equals("#/components/schemas/PagingObject")) {
var itemsSchema = (ArraySchema) allOf.get(1).getProperties().get("items");
return getTypeOfSchema(itemsSchema.getItems())
.map(itemsType -> "Paging<" + itemsType + ">");
}
if (allOf.get(0).get$ref().equals("#/components/schemas/CursorPagingObject")) {
var itemsSchema = (ArraySchema) allOf.get(1).getProperties().get("items");
return getTypeOfSchema(itemsSchema.getItems())
}
if (allOf.get(0).get$ref().equals("#/components/schemas/CursorPagingObject")) {
var itemsSchema = (ArraySchema) allOf.get(1).getProperties().get("items");
return getTypeOfSchema(itemsSchema.getItems())
.map(itemsType -> "CursorPaging<" + itemsType + ">");
}
}
}
}

var oneOf = composedSchema.getOneOf();
if (oneOf != null) {
var allBaseObjects = oneOf.stream().map(JavaUtils::getTypeOfSchema)
var oneOf = composedSchema.getOneOf();
if (oneOf != null) {
var allBaseObjects = oneOf.stream().map(JavaUtils::getTypeOfSchema)
.filter(Optional::isPresent)
.map(Optional::get)
.allMatch(BaseObjectGenerator.BASE_OBJECT_NAMES::contains);
if (allBaseObjects) {
return Optional.of("BaseObject");
if (allBaseObjects) {
return Optional.of("BaseObject");
}
}
}

// Resolve type of other composed schema via reference name
return Optional.empty();
}
// Resolve type of other composed schema via reference name
return Optional.empty();

if (schema instanceof MapSchema) {
return Optional.of("java.util.Map<String, Object>");
// Resolve type of other composed schema via reference name
}
case MapSchema mapSchema -> {
return Optional.of("java.util.Map<String, Object>");
}
default -> {
}
}

// Type can not be resolved just by schema
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public SpotifyWebApi build() {
private ObjectMapper createDefaultObjectMapper() {
return new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
.setDefaultPropertyInclusion(JsonInclude.Include.NON_NULL)
.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
.registerModule(new JavaTimeModule());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,12 @@ private RequestBody createRequestBody(ObjectMapper objectMapper) throws IOExcept
return rawBody.get();
}

if (getBodyParameters().size() > 0 && getFormParameters().size() > 0) {
if (!getBodyParameters().isEmpty() && !getFormParameters().isEmpty()) {
throw new IllegalArgumentException("Can not use body parameters and form fields in one request");
} else if (getBodyParameters().size() > 0) {
} else if (!getBodyParameters().isEmpty()) {
byte[] bytes = objectMapper.writeValueAsBytes(getBodyParameters());
return RequestBody.create(bytes, JSON_MEDIA_TYPE);
} else if (getFormParameters().size() > 0) {
} else if (!getFormParameters().isEmpty()) {
var formBuilder = new FormBody.Builder();
getFormParameters().forEach(formBuilder::add);
return formBuilder.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public String toString() {
}

public static SpotifyUri parseUri(String string) throws SpotifyUriException {
if (string == null || string.length() == 0) {
if (string == null || string.isEmpty()) {
throw new SpotifyUriException("Can not parse empty spotifyUri");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ public final class TextUtil {
private TextUtil() {}

public static boolean hasText(String str) {
return str != null && str.length() > 0;
return str != null && !str.isEmpty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ void setup() throws IOException {
}

@AfterEach
void teardown() throws IOException{
void teardown() {
webServer.close();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ void setup() throws IOException {
}

@AfterEach
void teardown() throws IOException{
void teardown() {
webServer.close();
}

Expand Down Expand Up @@ -110,30 +110,31 @@ void handlesUnauthorizedResponseWithFailure() throws Exception {

private final MockResponse mockResponseArtist = new MockResponse.Builder()
.code(200)
.body("{\n" +
" \"external_urls\" : {\n" +
" \"spotify\" : \"https://open.spotify.com/artist/0OdUWJ0sBjDrqHygGUXeCF\"\n" +
" },\n" +
" \"followers\" : {\n" +
" \"href\" : null,\n" +
" \"total\" : 306565\n" +
" },\n" +
" \"genres\" : [ \"indie folk\", \"indie pop\" ],\n" +
" \"href\" : \"https://api.spotify.com/v1/artists/0OdUWJ0sBjDrqHygGUXeCF\",\n" +
" \"id\" : \"0OdUWJ0sBjDrqHygGUXeCF\",\n" +
" \"images\" : [ {\n" +
" \"height\" : 816,\n" +
" \"url\" : \"https://i.scdn.co/image/eb266625dab075341e8c4378a177a27370f91903\",\n" +
" \"width\" : 1000\n" +
" }, {\n" +
" \"height\" : 52,\n" +
" \"url\" : \"https://i.scdn.co/image/4f25297750dfa4051195c36809a9049f6b841a23\",\n" +
" \"width\" : 64\n" +
" } ],\n" +
" \"name\" : \"Band of Horses\",\n" +
" \"popularity\" : 59,\n" +
" \"type\" : \"artist\",\n" +
" \"uri\" : \"spotify:artist:0OdUWJ0sBjDrqHygGUXeCF\"\n" +
"}")
.body("""
{
"external_urls" : {
"spotify" : "https://open.spotify.com/artist/0OdUWJ0sBjDrqHygGUXeCF"
},
"followers" : {
"href" : null,
"total" : 306565
},
"genres" : [ "indie folk", "indie pop" ],
"href" : "https://api.spotify.com/v1/artists/0OdUWJ0sBjDrqHygGUXeCF",
"id" : "0OdUWJ0sBjDrqHygGUXeCF",
"images" : [ {
"height" : 816,
"url" : "https://i.scdn.co/image/eb266625dab075341e8c4378a177a27370f91903",
"width" : 1000
}, {
"height" : 52,
"url" : "https://i.scdn.co/image/4f25297750dfa4051195c36809a9049f6b841a23",
"width" : 64
} ],
"name" : "Band of Horses",
"popularity" : 59,
"type" : "artist",
"uri" : "spotify:artist:0OdUWJ0sBjDrqHygGUXeCF"
}""")
.build();
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class AuthorizationRedirectResponseTest {

private final Function<HttpUrl, String> contentExtractor = httpUrl -> {
var code = httpUrl.queryParameter("code");
if (code != null && code.length() > 0) {
if (code != null && !code.isEmpty()) {
return code;
}
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ void setup() throws IOException {
}

@AfterEach
void teardown() throws IOException{
void teardown() {
webServer.close();
}

Expand Down Expand Up @@ -186,12 +186,13 @@ private void assertStoreAuthTokensFromResponse() {

private final MockResponse mockResponseAuthTokens = new MockResponse.Builder()
.code(200)
.body("{\n" +
" \"access_token\": \"NgA6ZcYIixn8bU\",\n" +
" \"token_type\": \"Bearer\",\n" +
" \"scope\": \"user-read-private user-read-email\",\n" +
" \"expires_in\": 3600\n" +
"}")
.body("""
{
"access_token": "NgA6ZcYIixn8bU",
"token_type": "Bearer",
"scope": "user-read-private user-read-email",
"expires_in": 3600
}""")
.build();

private final MockResponse mockResponseBadRequestAuthTokens = new MockResponse.Builder()
Expand Down
Loading