Skip to content
Permalink
Browse files
some workaround for yaml until we fully support it and mapping
  • Loading branch information
rmannibucau committed Jun 24, 2018
1 parent dca7412 commit 06a25cc0995ba03595004703748e6df45d4fa712
Show file tree
Hide file tree
Showing 22 changed files with 838 additions and 150 deletions.
28 pom.xml
@@ -44,6 +44,7 @@
<spec.version>1.0.1</spec.version>
<arquillian.version>1.1.14.Final</arquillian.version>
<testng.version>6.9.9</testng.version>
<jackson.version>2.9.4</jackson.version>
</properties>

<dependencies>
@@ -102,6 +103,18 @@
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-json_1.1_spec</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>9.0.8</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.apache.cxf</groupId>
@@ -110,6 +123,21 @@
<scope>provided</scope>
<optional>true</optional>
</dependency>
<!-- not that consistent with microprofile so don't enforce it -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>${jackson.version}</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.testng</groupId>
@@ -18,31 +18,31 @@

import static java.util.Optional.ofNullable;

import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Array;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Stream;

import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.CDI;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessBean;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;

import org.apache.geronimo.microprofile.openapi.config.GeronimoOpenAPIConfig;
import org.apache.geronimo.microprofile.openapi.impl.model.OpenAPIImpl;
import org.apache.geronimo.microprofile.openapi.impl.loader.DefaultLoader;
import org.apache.geronimo.microprofile.openapi.impl.processor.AnnotatedMethodElement;
import org.apache.geronimo.microprofile.openapi.impl.processor.AnnotatedTypeElement;
import org.apache.geronimo.microprofile.openapi.impl.processor.AnnotationProcessor;
import org.eclipse.microprofile.openapi.OASFilter;
import org.eclipse.microprofile.openapi.OASModelReader;
@@ -78,10 +78,10 @@ private OpenAPI createOpenApi(final Class<?> application, final Stream<Class<?>>
final OpenAPI api = ofNullable(config.read("mp.openapi.model.reader", null)).map(value -> newInstance(current, value))
.map(it -> OASModelReader.class.cast(it).buildModel()).orElseGet(() -> {
final BeanManager beanManager = current.getBeanManager();
final OpenAPI impl = loadDefaultApi();
final OpenAPI impl = current.select(DefaultLoader.class).get().loadDefaultApi();
processor.processApplication(impl, new ElementImpl(beanManager.createAnnotatedType(application)));
beans.map(beanManager::createAnnotatedType).forEach(at -> processor.processClass(impl, new ElementImpl(at),
at.getMethods().stream().map(ElementImpl::new)));
at.getMethods().stream().map(MethodElementImpl::new)));
return impl;
});

@@ -94,23 +94,6 @@ private OpenAPI createOpenApi(final Class<?> application, final Stream<Class<?>>
.orElse(api);
}

private OpenAPI loadDefaultApi() {
// todo: yaml handling + json mapping correctly (interface to impl)
return Stream.of("", "/")
.map(prefix -> prefix + "openapi.json")
.map(it -> Thread.currentThread().getContextClassLoader().getResourceAsStream(it))
.filter(Objects::nonNull)
.findFirst()
.map(r -> {
try (final Jsonb jsonb = JsonbBuilder.create()) {
return jsonb.fromJson(r, OpenAPIImpl.class);
} catch (final Exception e) {
throw new IllegalStateException(e);
}
})
.orElseGet(OpenAPIImpl::new);
}

private Object newInstance(final CDI<Object> current, final String value) {
try {
final Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(value.trim());
@@ -128,6 +111,46 @@ private Object newInstance(final CDI<Object> current, final String value) {
}
}

private static class MethodElementImpl extends ElementImpl implements AnnotatedMethodElement {

private final AnnotatedMethod<?> delegate;

private MethodElementImpl(final AnnotatedMethod<?> delegate) {
super(delegate);
this.delegate = delegate;
}

@Override
public Type getReturnType() {
return delegate.getJavaMember().getGenericReturnType();
}

@Override
public Class<?> getDeclaringClass() {
return delegate.getDeclaringType().getJavaClass();
}

@Override
public AnnotatedTypeElement[] getParameters() {
return delegate.getParameters().stream().map(p -> new TypeElementImpl(p.getBaseType(), p)).toArray(TypeElementImpl[]::new);
}
}

private static class TypeElementImpl extends ElementImpl implements AnnotatedTypeElement {

private final Type type;

private TypeElementImpl(final Type type, final Annotated delegate) {
super(delegate);
this.type = type;
}

@Override
public Type getType() {
return type;
}
}

private static class ElementImpl implements AnnotatedElement {

private final Annotated delegate;
@@ -0,0 +1,57 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.geronimo.microprofile.openapi.impl.loader;

import static java.util.Optional.ofNullable;

import java.io.InputStream;
import java.util.Objects;
import java.util.stream.Stream;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import javax.servlet.ServletContext;

import org.apache.geronimo.microprofile.openapi.impl.loader.yaml.Yaml;
import org.apache.geronimo.microprofile.openapi.impl.model.OpenAPIImpl;
import org.eclipse.microprofile.openapi.models.OpenAPI;

@ApplicationScoped
public class DefaultLoader {
@Inject
private ServletContext context;

// todo: finish binding
public OpenAPI loadDefaultApi() {
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
return Stream.of("", "/").map(prefix -> prefix + "META-INF/openapi.json")
.map(it -> ofNullable(loader.getResourceAsStream(it)).orElseGet(() -> context.getResourceAsStream(it)))
.filter(Objects::nonNull).findFirst().map(r -> {
try (final Jsonb jsonb = JsonbBuilder.create(); final InputStream stream = r) {
return jsonb.fromJson(stream, OpenAPIImpl.class);
} catch (final Exception e) {
throw new IllegalStateException(e);
}
}).map(OpenAPI.class::cast)
.orElseGet(() -> Stream.of("", "/").map(prefix -> prefix + "META-INF/openapi.")
.flatMap(p -> Stream.of(p + "yaml", p + "yml"))
.map(it -> ofNullable(loader.getResourceAsStream(it)).orElseGet(() -> context.getResourceAsStream(it)))
.filter(Objects::nonNull).findFirst().map(Yaml::loadAPI).orElseGet(OpenAPIImpl::new));
}
}

0 comments on commit 06a25cc

Please sign in to comment.