/** * Read a string annotation value, treating empty strings as <code>null</code> values * @param annotationValue Annotation string value * @return String value, or <code>null</code> if <code>annotationValue</code> is an empty string */ public static String getStringValue(String annotationValue) { return getStringValue(annotationValue, null); }
/** * Get the API context id. * @param configuration The API configuration * @return the API context id */ protected String getApiEndpointContextId(C configuration) { return AnnotationUtils.getAnnotation(configuration.getClass(), ApiConfiguration.class) .map(a -> AnnotationUtils.getStringValue(a.contextId())).orElse(ApiDefaults.DEFAULT_CONTEXT_ID); }
/** * Check whether the {@link PropertySetRef} annotation is present in given annotations list. * @param annotations Annotations to scan * @return If the {@link PropertySetRef} annotation is present in given annotations list, returns it */ private static PropertySetRef hasApiPropertySet(List<Annotation> annotations) { List<PropertySetRef> as = AnnotationUtils.getAnnotations(annotations, PropertySetRef.class); if (!as.isEmpty()) { return as.get(0); } return null; }
/** * Find the annotations of given <code>annotationType</code> on given element and stores them in given * <code>accumulator</code>. * @param accumulator Accumulator * @param element Annotated element * @param annotationType Annotation type to lookup * @param repeatableContainerType Optional repeteable annotation type */ private static <A extends Annotation> void findAnnotations(List<A> accumulator, AnnotatedElement element, Class<A> annotationType, Class<? extends Annotation> repeatableContainerType) { // direct lookup A[] as = element.getAnnotationsByType(annotationType); if (as.length > 0) { for (A a : as) { accumulator.add(a); } } // check meta-annotations Annotation[] all = element.getAnnotations(); if (all.length > 0) { for (Annotation annotation : all) { if (!isInJavaLangAnnotationPackage(annotation) && !annotation.annotationType().equals(annotationType) && (repeatableContainerType == null || !annotation.annotationType().equals(repeatableContainerType))) { findAnnotations(accumulator, annotation.annotationType(), annotationType, repeatableContainerType); } } } }
/** * Get the API endpoint type. * @param configuration The API configuration * @return the API endpoint type */ private ApiEndpointType getApiEndpointType(C configuration) { return AnnotationUtils.getAnnotation(configuration.getClass(), ApiConfiguration.class) .map(a -> a.endpointType()).orElse(ApiEndpointType.getDefault()); }
/** * Get the class which is annotated with given <code>annotation</code>, checking any superclass and implemented * interface. * @param cls Class to inspect (not null) * @param annotation Annotation to look for (not null) * @return The class (or implemented interface) on which the annotation is present, <code>null</code> if not found */ public static Class<?> getClassWithAnnotation(Class<?> cls, Class<? extends Annotation> annotation) { ObjectUtils.argumentNotNull(cls, "Class must be not null"); ObjectUtils.argumentNotNull(annotation, "Annotation must be not null"); if (cls.isAnnotationPresent(annotation)) { return cls; } for (Class<?> intf : cls.getInterfaces()) { if (intf.isAnnotationPresent(annotation)) { return intf; } } Class<?> superClass = cls.getSuperclass(); if (superClass != null && superClass != Object.class) { return getClassWithAnnotation(superClass, annotation); } return null; }
/** * Get all the annotations of given <code>annotationType</code> present in given <code>element</code>, including any * meta-annotation and supporting repeatable annotations. * @param <A> Annotation type * @param element Annotated element to inspect (not null) * @param annotationType Annotation type to lookup (not null) * @return List of detected annotation of given <code>annotationType</code>, an empty List if none found */ public static <A extends Annotation> List<A> getAnnotations(AnnotatedElement element, Class<A> annotationType) { ObjectUtils.argumentNotNull(element, "AnnotatedElement must be not null"); ObjectUtils.argumentNotNull(annotationType, "Annotation type must be not null"); Class<? extends Annotation> repeatableContainerType = null; if (annotationType.isAnnotationPresent(Repeatable.class)) { repeatableContainerType = annotationType.getAnnotation(Repeatable.class).value(); } List<A> annotations = new LinkedList<>(); findAnnotations(annotations, element, annotationType, repeatableContainerType); return annotations; }
/** * Get the scanner type. * @param configuration The API configuration * @return the API resources scanner type */ private JaxrsScannerType getScannerType(C configuration) { JaxrsScannerType type = AnnotationUtils.getAnnotation(configuration.getClass(), ApiConfiguration.class) .map(a -> a.scannerType()).orElseGet(() -> getDefaultScannerType()); if (JaxrsScannerType.DEFAULT == type) { return getDefaultScannerType(); } return type; }
ans.add((A) annotation); if (!isInJavaLangAnnotationPackage(annotation) && !annotation.annotationType().equals(annotationType) && (repeatableContainerType == null || !annotation.annotationType().equals(repeatableContainerType))) { findAnnotations(ans, annotation.annotationType(), annotationType, repeatableContainerType);
/** * Get the context id to use for this endpoint, if available. * <p> * By default, the {@link ApiEndpoint} annotation is used, if found on the endpoint class. * </p> * @return Optional context id */ protected Optional<String> getContextId() { if (getClass().isAnnotationPresent(ApiEndpoint.class)) { return Optional .ofNullable(AnnotationUtils.getStringValue(getClass().getAnnotation(ApiEndpoint.class).value())); } return Optional.empty(); }
/** * Get the API endpoint path. * @param configuration The API configuration * @param contextId The API context id * @return the API endpoint path */ private String getApiEndpointPath(C configuration, String contextId) { return AnnotationUtils.getAnnotation(configuration.getClass(), ApiConfiguration.class) .map(a -> AnnotationUtils.getStringValue(a.path())) .orElseGet(() -> getDefaultApiEndpointPath(contextId, false)); }
/** * Check whether the {@link ApiPropertySetModel} annotation is present in given annotations list. * @param annotations Annotations to scan * @return If the {@link ApiPropertySetModel} annotation is present in given annotations list, returns it */ private static Optional<ApiPropertySetModel> hasApiPropertySetModel(List<Annotation> annotations) { List<ApiPropertySetModel> as = AnnotationUtils.getAnnotations(annotations, ApiPropertySetModel.class); if (!as.isEmpty()) { return Optional.of(as.get(0)); } return Optional.empty(); }
@Override public void beforeEnter(BeforeEnterEvent event) { final Class<?> navigationTarget = event.getNavigationTarget(); if (navigationTarget != null) { String[] roles = AnnotationUtils.getAnnotation(navigationTarget, Secured.class) .map(s -> (s.value() != null) ? s.value() : new String[0]).orElse(null); if (roles != null) { if (!isAccessGranted(roles)) { // redirect to error event.rerouteToError(ForbiddenNavigationException.class, LocalizationProvider.localize(ForbiddenNavigationException.DEFAULT_MESSAGE, ForbiddenNavigationException.DEFAULT_MESSAGE_CODE)); } } } }
/** * Get the config location to use for this endpoint, if available. * <p> * By default, the {@link ApiEndpoint} annotation is used, if found on the endpoint class. * </p> * @return Optional config location */ protected Optional<String> getConfigLocation() { if (getClass().isAnnotationPresent(ApiEndpoint.class)) { return Optional.ofNullable( AnnotationUtils.getStringValue(getClass().getAnnotation(ApiEndpoint.class).configLocation())); } return Optional.empty(); }
/** * Get the class context id declaration using the {@link ApiContextId} annotation, if available. * @param cls The class * @return Optional class context id */ private static Optional<String> getResourceContextId(Class<?> cls) { Optional<String> clsContextId = AnnotationUtils.getAnnotation(cls, ApiContextId.class) .map(a -> AnnotationUtils.getStringValue(a.value())); if (clsContextId.isPresent()) { return clsContextId; } // check package Package pkg = cls.getPackage(); if (pkg != null && pkg.isAnnotationPresent(ApiContextId.class)) { return Optional.ofNullable(AnnotationUtils.getStringValue(pkg.getAnnotation(ApiContextId.class).value())); } return Optional.empty(); }
/** * Check whether the {@link PropertySetRef} annotation is present in given annotations list, checking * meta-annotations too. * @param annotations Annotations to scan * @return The {@link PropertySetRef} annotation if present in given annotations list, an empty Optional otherwise */ static Optional<PropertySetRef> getPropertySetRef(List<Annotation> annotations) { if (annotations != null && !annotations.isEmpty()) { List<PropertySetRef> as = AnnotationUtils.getAnnotations(annotations, PropertySetRef.class); if (!as.isEmpty()) { return Optional.ofNullable(as.get(0)); } } return Optional.empty(); }
@Override public void processBeanPropertySet(com.holonplatform.core.beans.BeanPropertySet.Builder<?, ?> propertySet, Class<?> beanClass) { if (beanClass.isAnnotationPresent(DataPath.class)) { final String path = AnnotationUtils.getStringValue(beanClass.getAnnotation(DataPath.class).value()); if (path != null) { propertySet.configuration(DataMappable.PATH, path); LOGGER.debug(() -> "BeanPropertySetPathPostProcessor: setted bean [" + beanClass + "] property set data path to [" + path + "]"); } } }
/** * Checks whether the given class matches the context id. * @param cls The class * @param contextId The context id * @return <code>true</code> if the class should be included in given context id classes */ @SuppressWarnings("deprecation") private static boolean matches(Class<?> cls, String contextId) { // check legacy ApiDefinition Optional<String> legacyContextId = AnnotationUtils .getAnnotation(cls, com.holonplatform.jaxrs.swagger.annotations.ApiDefinition.class).map(a -> { if (!"".equals(a.docsPath())) { return AnnotationUtils.getStringValue(a.docsPath()); } return AnnotationUtils.getStringValue(a.value()); }).flatMap(path -> AbstractSwaggerV2AutoConfiguration.getContextIdByPath(cls.getClassLoader(), path)); if (legacyContextId.isPresent()) { return legacyContextId.get().equals(contextId); } // use ApiContextId return getResourceContextId(cls).map(ctxId -> ctxId.equals(contextId)).orElse(Boolean.TRUE); }
/** * Check whether the given <code>type</code> is annotated with the {@link PropertySetRef} annotation. * @param type The type to inspect * @return Optional {@link PropertySetRef} annotation, if available */ private static Optional<PropertySetRef> getPropertySet(Type type) { if (type instanceof AnnotatedElement) { // check meta-annotations List<PropertySetRef> annotations = AnnotationUtils.getAnnotations((AnnotatedElement) type, PropertySetRef.class); if (!annotations.isEmpty()) { return Optional.ofNullable(annotations.get(0)); } } return Optional.empty(); }
/** * Get given enum localizable caption value, using the {@link Caption} annotation if available. * @param value The enum value * @return The enum localizable caption, using the {@link Caption} annotation if available or the enum value name if * not */ private static Localizable getEnumCaptionLocalizable(Enum<?> value) { try { final java.lang.reflect.Field field = value.getClass().getField(value.name()); if (field.isAnnotationPresent(Caption.class)) { String captionMessage = AnnotationUtils.getStringValue(field.getAnnotation(Caption.class).value()); return Localizable.builder().message((captionMessage != null) ? captionMessage : value.name()) .messageCode(AnnotationUtils.getStringValue(field.getAnnotation(Caption.class).messageCode())) .build(); } } catch (@SuppressWarnings("unused") NoSuchFieldException | SecurityException e) { return Localizable.of(value.name()); } return Localizable.of(value.name()); }