Search in sources :

Example 11 with AnnotatedElement

use of org.glassfish.hk2.classmodel.reflect.AnnotatedElement in project Payara by payara.

the class ApplicationProcessor method visitParameters.

@Override
public void visitParameters(AnnotationModel annotation, AnnotatedElement element, ApiContext context) {
    List<AnnotationModel> parameters = annotation.getValue("value", List.class);
    if (parameters != null) {
        for (AnnotationModel paramAnnotation : parameters) {
            final Parameter parameter = ParameterImpl.createInstance(paramAnnotation, context);
            final Operation workingOperation = context.getWorkingOperation();
            if (workingOperation != null) {
                workingOperation.addParameter(parameter);
            }
        }
    }
}
Also used : AnnotationModel(org.glassfish.hk2.classmodel.reflect.AnnotationModel) Parameter(org.eclipse.microprofile.openapi.models.parameters.Parameter) Operation(org.eclipse.microprofile.openapi.models.Operation)

Example 12 with AnnotatedElement

use of org.glassfish.hk2.classmodel.reflect.AnnotatedElement in project Payara by payara.

the class ModelUtils method getSchemaName.

@SuppressWarnings("unchecked")
public static String getSchemaName(ApiContext context, AnnotatedElement type) {
    assert type != null;
    // context and annotation can be null
    final Class<? extends Annotation>[] ANNOTATION_TYPES = new Class[] { org.eclipse.microprofile.openapi.annotations.media.Schema.class, javax.xml.bind.annotation.XmlRootElement.class, javax.xml.bind.annotation.XmlElement.class };
    for (Class<? extends Annotation> annotationType : ANNOTATION_TYPES) {
        AnnotationModel annotationModel;
        // Fetch the element annotations
        if (context != null && type instanceof ExtensibleType) {
            // Fetch the annotation from the cache
            ExtensibleType<?> implementationType = (ExtensibleType<?>) type;
            AnnotationInfo annotationInfo = context.getAnnotationInfo(implementationType);
            annotationModel = annotationInfo.getAnnotation(annotationType);
        } else {
            // Fetch the annotation manually
            annotationModel = type.getAnnotation(annotationType.getName());
        }
        // Fields can be named by their accessors
        if (annotationModel == null) {
            if (type instanceof FieldModel) {
                final FieldModel field = (FieldModel) type;
                final String accessorName = getAccessorName(field.getName());
                for (MethodModel method : field.getDeclaringType().getMethods()) {
                    // Check if it's the accessor
                    if (accessorName.equals(method.getName())) {
                        annotationModel = type.getAnnotation(annotationType.getName());
                        break;
                    }
                }
            }
        }
        // Get the schema name if the annotation exists
        if (annotationModel != null) {
            final String name = annotationModel.getValue("name", String.class);
            if (name != null && !name.isEmpty() && !name.equals("##default")) {
                return name;
            }
        }
    }
    return getSimpleName(type.getName());
}
Also used : MethodModel(org.glassfish.hk2.classmodel.reflect.MethodModel) ExtensibleType(org.glassfish.hk2.classmodel.reflect.ExtensibleType) Annotation(java.lang.annotation.Annotation) AnnotationModel(org.glassfish.hk2.classmodel.reflect.AnnotationModel) FieldModel(org.glassfish.hk2.classmodel.reflect.FieldModel) AnnotationInfo(fish.payara.microprofile.openapi.impl.visitor.AnnotationInfo)

Example 13 with AnnotatedElement

use of org.glassfish.hk2.classmodel.reflect.AnnotatedElement in project Payara by payara.

the class ApplicationProcessor method visitParameter.

@Override
public void visitParameter(AnnotationModel annotation, AnnotatedElement element, ApiContext context) {
    Parameter matchedParam = null;
    Boolean hidden = annotation.getValue("hidden", Boolean.class);
    if (hidden != null && hidden) {
        return;
    }
    Parameter parameter = ParameterImpl.createInstance(annotation, context);
    if (element instanceof org.glassfish.hk2.classmodel.reflect.Parameter) {
        matchedParam = findOperationParameterFor((org.glassfish.hk2.classmodel.reflect.Parameter) element, context);
    }
    if (element instanceof MethodModel) {
        matchedParam = findOperationParameterFor(parameter, (MethodModel) element, context);
    }
    if (matchedParam != null) {
        ParameterImpl.merge(parameter, matchedParam, true, context);
        // If a content was added, and a schema type exists, reconfigure the schema type
        if (matchedParam.getContent() != null && !matchedParam.getContent().getMediaTypes().isEmpty() && matchedParam.getSchema() != null && matchedParam.getSchema().getType() != null) {
            SchemaType type = matchedParam.getSchema().getType();
            matchedParam.setSchema(null);
            for (MediaType mediaType : matchedParam.getContent().getMediaTypes().values()) {
                if (mediaType.getSchema() == null) {
                    mediaType.setSchema(new SchemaImpl());
                }
                mediaType.getSchema().setType(ModelUtils.mergeProperty(mediaType.getSchema().getType(), type, false));
            }
        }
    }
}
Also used : MethodModel(org.glassfish.hk2.classmodel.reflect.MethodModel) SchemaImpl(fish.payara.microprofile.openapi.impl.model.media.SchemaImpl) Parameter(org.eclipse.microprofile.openapi.models.parameters.Parameter) MediaType(org.eclipse.microprofile.openapi.models.media.MediaType) SchemaType(org.eclipse.microprofile.openapi.models.media.Schema.SchemaType)

Example 14 with AnnotatedElement

use of org.glassfish.hk2.classmodel.reflect.AnnotatedElement in project Payara by payara.

the class ApplicationProcessor method visitProduces.

@Override
public void visitProduces(AnnotationModel produces, AnnotatedElement element, ApiContext context) {
    if (element instanceof MethodModel && context.getWorkingOperation() != null) {
        for (APIResponse response : context.getWorkingOperation().getResponses().getAPIResponses().values()) {
            if (response != null) {
                // Find the wildcard return type
                if (response.getContent() != null && response.getContent().getMediaType(javax.ws.rs.core.MediaType.WILDCARD) != null) {
                    MediaType wildcardMedia = response.getContent().getMediaType(javax.ws.rs.core.MediaType.WILDCARD);
                    // Merge the wildcard return type with the valid response types
                    // This keeps the specific details of a reponse type that has a schema
                    List<String> mediaTypes = produces.getValue("value", List.class);
                    for (String mediaType : mediaTypes) {
                        MediaType held = response.getContent().getMediaType(getContentType(mediaType));
                        if (held == null) {
                            response.getContent().addMediaType(getContentType(mediaType), wildcardMedia);
                        } else {
                            MediaTypeImpl.merge(held, wildcardMedia, true);
                        }
                    }
                    // If there is an @Produces, remove the wildcard
                    response.getContent().removeMediaType(javax.ws.rs.core.MediaType.WILDCARD);
                }
            }
        }
    }
}
Also used : MethodModel(org.glassfish.hk2.classmodel.reflect.MethodModel) APIResponse(org.eclipse.microprofile.openapi.models.responses.APIResponse) MediaType(org.eclipse.microprofile.openapi.models.media.MediaType)

Example 15 with AnnotatedElement

use of org.glassfish.hk2.classmodel.reflect.AnnotatedElement in project Payara by payara.

the class GenericCrudCommand method getInjectionResolver.

public InjectionResolver<Param> getInjectionResolver() {
    final InjectionResolver<Param> delegate = injector;
    return new InjectionResolver<Param>(Param.class) {

        @Override
        public <V> V getValue(Object component, AnnotatedElement annotated, Type genericType, Class<V> type) throws MultiException {
            if (type.isAssignableFrom(List.class)) {
                final List<ConfigBeanProxy> values;
                try {
                    if (annotated instanceof Method) {
                        values = (List<ConfigBeanProxy>) ((Method) annotated).invoke(component);
                    } else if (annotated instanceof Field) {
                        values = (List<ConfigBeanProxy>) ((Field) annotated).get(component);
                    } else {
                        String msg = LOCAL_STRINGS.getLocalString(GenericCrudCommand.class, "GenericCrudCommand.invalid_type", "Invalid annotated type {0} passed to InjectionResolver:getValue()", annotated.getClass().toString());
                        LOGGER.log(Level.SEVERE, ConfigApiLoggerInfo.INVALID_ANNO_TYPE, annotated.getClass().toString());
                        throw new MultiException(new IllegalArgumentException(msg));
                    }
                } catch (IllegalAccessException | InvocationTargetException e) {
                    String msg = LOCAL_STRINGS.getLocalString(GenericCrudCommand.class, "GenericCrudCommand.invocation_failure", "Failure {0} while getting List<?> values from component", e.getMessage());
                    LOGGER.log(Level.SEVERE, ConfigApiLoggerInfo.INVOKE_FAILURE);
                    throw new MultiException(new IllegalStateException(msg, e));
                }
                Object value = delegate.getValue(component, annotated, genericType, type);
                if (value == null) {
                    LOGGER.log(level, "Value of {0} is null", annotated);
                    return null;
                }
                Type genericReturnType = null;
                if (annotated instanceof Method) {
                    genericReturnType = ((Method) annotated).getGenericReturnType();
                } else if (annotated instanceof Field) {
                    genericReturnType = ((Field) annotated).getGenericType();
                }
                if (genericReturnType == null) {
                    throw new MultiException(new IllegalArgumentException("Cannot determine parametized type from " + annotated));
                }
                final Class<? extends ConfigBeanProxy> itemType = Types.erasure(Types.getTypeArgument(genericReturnType, 0));
                if (LOGGER.isLoggable(level)) {
                    LOGGER.log(level, "Found that List<?> really is a List<{0}>", itemType);
                }
                if (itemType == null) {
                    String msg = LOCAL_STRINGS.getLocalString(GenericCrudCommand.class, "GenericCrudCommand.nongeneric_type", "The List type returned by {0} must be a generic type", annotated.toString());
                    LOGGER.log(Level.SEVERE, ConfigApiLoggerInfo.LIST_NOT_GENERIC_TYPE, annotated.toString());
                    throw new MultiException(new IllegalArgumentException(msg));
                }
                if (!ConfigBeanProxy.class.isAssignableFrom(itemType)) {
                    String msg = LOCAL_STRINGS.getLocalString(GenericCrudCommand.class, "GenericCrudCommand.wrong_type", "The generic type {0} is not supported, only List<? extends ConfigBeanProxy> is", annotated.toString());
                    LOGGER.log(Level.SEVERE, ConfigApiLoggerInfo.GENERIC_TYPE_NOT_SUPPORTED, annotated.toString());
                    throw new MultiException(new IllegalArgumentException(msg));
                }
                Properties props = convertStringToProperties(value.toString(), ':');
                if (LOGGER.isLoggable(level)) {
                    for (Map.Entry<Object, Object> entry : props.entrySet()) {
                        LOGGER.log(level, "Subtype {0} key:{1} value:{2}", new Object[] { itemType, entry.getKey(), entry.getValue() });
                    }
                }
                final BeanInfo beanInfo;
                try {
                    beanInfo = Introspector.getBeanInfo(itemType);
                } catch (IntrospectionException e) {
                    String msg = LOCAL_STRINGS.getLocalString(GenericCrudCommand.class, "GenericCrudCommand.introspection_failure", "Failure {0} while instrospecting {1} to find all getters and setters", e.getMessage(), itemType.getName());
                    LogHelper.log(LOGGER, Level.SEVERE, ConfigApiLoggerInfo.INTROSPECTION_FAILED, e, itemType.getName());
                    throw new MultiException(new IllegalStateException(msg, e));
                }
                for (final Map.Entry<Object, Object> entry : props.entrySet()) {
                    ConfigBeanProxy child = (ConfigBeanProxy) component;
                    try {
                        ConfigBeanProxy cc = child.createChild(itemType);
                        new InjectionManager().inject(cc, itemType, new InjectionResolver<Attribute>(Attribute.class) {

                            @Override
                            public boolean isOptional(AnnotatedElement annotated, Attribute annotation) {
                                return true;
                            }

                            @Override
                            public Method getSetterMethod(Method annotated, Attribute annotation) {
                                // variant.
                                for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
                                    if (pd.getReadMethod().equals(annotated)) {
                                        return pd.getWriteMethod();
                                    }
                                }
                                return annotated;
                            }

                            @Override
                            public <V> V getValue(Object component, AnnotatedElement annotated, Type genericType, Class<V> type) throws MultiException {
                                String name = annotated.getAnnotation(Attribute.class).value();
                                if ((name == null || name.length() == 0) && annotated instanceof Method) {
                                    // maybe there is a better way to do this...
                                    name = ((Method) annotated).getName().substring(3);
                                    if (name.equalsIgnoreCase("name") || name.equalsIgnoreCase("key")) {
                                        return type.cast(entry.getKey());
                                    }
                                    if (name.equalsIgnoreCase("value")) {
                                        return type.cast(entry.getValue());
                                    }
                                }
                                return null;
                            }
                        });
                        values.add(cc);
                    } catch (TransactionFailure transactionFailure) {
                        String msg = LOCAL_STRINGS.getLocalString(GenericCrudCommand.class, "GenericCrudCommand.transactionException", "Transaction exception {0} while injecting {1}", transactionFailure.getMessage(), itemType);
                        LogHelper.log(LOGGER, Level.SEVERE, ConfigApiLoggerInfo.TX_FAILED, transactionFailure, itemType);
                        throw new MultiException(new IllegalStateException(msg, transactionFailure));
                    }
                }
                return null;
            }
            return delegate.getValue(component, annotated, genericType, type);
        }

        @Override
        public boolean isOptional(AnnotatedElement annotated, Param annotation) {
            return annotation.optional();
        }
    };
}
Also used : TransactionFailure(org.jvnet.hk2.config.TransactionFailure) Attribute(org.jvnet.hk2.config.Attribute) BeanInfo(java.beans.BeanInfo) AnnotatedElement(java.lang.reflect.AnnotatedElement) IntrospectionException(java.beans.IntrospectionException) Properties(java.util.Properties) Field(java.lang.reflect.Field) ConfigBeanProxy(org.jvnet.hk2.config.ConfigBeanProxy) List(java.util.List) PropertyDescriptor(java.beans.PropertyDescriptor) GenerateServiceFromMethod(org.jvnet.hk2.config.GenerateServiceFromMethod) Method(java.lang.reflect.Method) InjectionResolver(org.jvnet.hk2.config.InjectionResolver) InvocationTargetException(java.lang.reflect.InvocationTargetException) Type(java.lang.reflect.Type) Param(org.glassfish.api.Param) MultiException(org.glassfish.hk2.api.MultiException) Map(java.util.Map) InjectionManager(org.jvnet.hk2.config.InjectionManager)

Aggregations

MethodModel (org.glassfish.hk2.classmodel.reflect.MethodModel)14 SchemaImpl (fish.payara.microprofile.openapi.impl.model.media.SchemaImpl)8 AnnotationModel (org.glassfish.hk2.classmodel.reflect.AnnotationModel)8 MediaType (org.eclipse.microprofile.openapi.models.media.MediaType)5 FieldModel (org.glassfish.hk2.classmodel.reflect.FieldModel)5 Schema (org.eclipse.microprofile.openapi.models.media.Schema)4 Parameter (org.eclipse.microprofile.openapi.models.parameters.Parameter)4 RequestBody (org.eclipse.microprofile.openapi.models.parameters.RequestBody)3 ExternalDocumentationImpl (fish.payara.microprofile.openapi.impl.model.ExternalDocumentationImpl)2 OperationImpl (fish.payara.microprofile.openapi.impl.model.OperationImpl)2 CallbackImpl (fish.payara.microprofile.openapi.impl.model.callbacks.CallbackImpl)2 ParameterImpl (fish.payara.microprofile.openapi.impl.model.parameters.ParameterImpl)2 APIResponseImpl (fish.payara.microprofile.openapi.impl.model.responses.APIResponseImpl)2 SecurityRequirementImpl (fish.payara.microprofile.openapi.impl.model.security.SecurityRequirementImpl)2 ServerImpl (fish.payara.microprofile.openapi.impl.model.servers.ServerImpl)2 TagImpl (fish.payara.microprofile.openapi.impl.model.tags.TagImpl)2 Field (java.lang.reflect.Field)2 Method (java.lang.reflect.Method)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2