How to migrate scr annotations of AdaptorFactory class to OSGI R6 annotations? - osgi

We are migrating from AEM 6.0 to 6.3 and in process moving from Felix to OSGI scr annotations.
I have a code like this
#Component
#Service(AdapterFactory.class)
#Properties({
#Property(name = "CustomManagerAdapter", value = "adapter/factory"),
#Property(name = SlingConstants.PROPERTY_ADAPTABLE_CLASSES, value = {
"org.apache.sling.api.resource.ResourceResolver",
"org.apache.sling.api.SlingHttpServletRequest",
"org.apache.sling.api.resource.Resource"
}),
#Property(name = SlingConstants.PROPERTY_ADAPTER_CLASSES, value = "com.myapp.util.user.CustomUser")
})
public class CustomUserAdapter implements AdapterFactor
How to multi valued properties like SlingConstants.PROPERTY_ADAPTABLE_CLASSES into R6 annotation?
I tried like:
#Component(service = AdapterFactory.class, property={
SlingConstants.PROPERTY_ADAPTER_CLASSES + "=com.myapp.util.user.CustomUser",
SlingConstants.PROPERTY_ADAPTABLE_CLASSES+"={\"org.apache.sling.api.resource.ResourceResolver\"}",
"CustomManagerAdapter=adapter/factory"
})
This didnt work. Please share an example of migrating multivalued prperties.

To register multivalued properties, repeat the declaration for the property multiple times. The key, i.e property name remains same while the property value changes.
Ex:
#Component(
service = AdapterFactory.class,
immediate = true,
property = {
"adaptables=org.apache.sling.api.resource.Resource",
"adaptables=org.apache.sling.api.SlingHttpServletRequest",
"adapters=<Myclass>"
}
)

Related

How to use a custom annotation

With the JSweet toot, I want to generate an annotation in the typescript code, once I encounter a Java annotation on a class. Concretely, I want to accomplish the following:
#com.fasterxml.jackson.annotation.JsonSubTypes(
{
#com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = Person.class, name = "Person"),
#com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = Department.class, name = "Department")
})
// #JsonSubTypes({ types: [{class: () => Person, name: 'Person'}, {class: () => Department, name: 'Department'}]})
public abstract class Root {
should be translated into
#JsonSubTypes({ types: [{class: () => Person, name: 'Person'}, {class: () => Department, name: 'Department'}]})
abstract class Root {
I have made a custom annotation using the example here,
and I tried to process the annotation using the example here.
However, the AnnotationManager of JSweet only uses the jsweet.lang annotations part of the Jsweet framework, and not the added annotation by meself.
In other4 words: how to add my custom annotation to the Jsweet annotation manager?
Thanks,
-- Jaap

Hidden parameter in springdoc-openapi doesn't work

I have Spring Boot application with version 2.3.0.
and springdoc-openapi-webflux-ui in version 1.4.1.
I have annotated parameter in operation like this.
parameters = {
#Parameter(
hidden = true, schema = #Schema(implementation = Boolean.class),
in = ParameterIn.QUERY, name = DO_NOT_FORWARD
)
With hidden = true I expected that this parameter will not be visible in swagger-ui. But it is.
Did I misunderstood this parameter or is it not doing what it was supposed to do?
I want this parameter to be in api-docs, to have generated client able to use this parameter, but I want it invisible in swagger-ui
Try
#Parameter(name = "paramName", hidden = true)
#GetMapping("/example")
public Object example(String paramName) {
return null;
}
instead of
#Operation(
parameters = {
#Parameter(name = "paramName", hidden = true)
}
)
#GetMapping("/example")
public Object example(String paramName) {
return null;
}
You just make sure that the name of in the #Parameter annotation, is the exact name of the operation parameter you want to hide.
You can have a look at the documentation as well:
https://springdoc.org/faq.html#how-can-i-hide-a-parameter-from-the-documentation-
If you are still having coniguration issue, you can add the code of sample HelloController that reproduces your problem, or you can add the link to a minimal, reproducible sample in github.
As per the doc
#GetMapping("/example")
fun someCall: Response (
#Parameter(hidden = true) String paramName
) {
return response;
}

Automatically adding #ImplicitParams with specific type of method argument of Spring Controller

Previously, I had Spring controller as below.
#RequestMapping(method = GET)
public List<TheResponse> getResponses(
#RequestParam(defaultValue = "1") int offset,
#RequestParam(defaultValue = "10") int limit) {
Pagination pagination = new Pagination(offset, limit);
...
return someResponse;
}
Swagger was generating document of this method with correct parameters information.
Later I created PaginationArgResolver by implementing HandlerMethodArgumentResolver. After that, I have to update the method as below, and apply #ApiImplicitParams to make it work with Swagger.
#ApiImplicitParams({
#ApiImplicitParam(name = "offset", dataType = "int", defaultValue = "1"),
#ApiImplicitParam(name = "limit", dataType = "int", defaultValue = "10")
})
#RequestMapping(method = GET)
public List<TheResponse> getResponses(#ApiIgnore Pagination pagination) {
...
}
Is there anyway #ImplicitParams is applied automatically whenever Pagination type argument is found?
OR
If I expose #PaginationSupported annotation, can I process it to achieve same results?
I am currently using springfox v2.4.0.
PS. I can edit source of Pagination class, in case some swagger annotation is needed there.
Why adding #ApiIgnore springfox will resolve these attributes inside the class automatically. When you want to add default values and other stuff you can add the #ApiParam annotation to the class attributes as well.
class Pagination {
#ApiParam(defaultValue = "1")
private int offset;
// [..]
}

SpEL not able to extract attribute value from Scala object

I have a simple Scala class called Case
case class Case(
#(Id#field) var id: String,
var state: CaseState = new OpenCaseState,
var notes: List[CaseNote] = new ArrayList(),
var assignedGroups:Set[String] = new HashSet(),
var aclTemplateIds: Set[String] = new HashSet()
) extends Serializable { }
I created an instance of this class called a_case, setting id as 123. I am trying to get the value of the id attribute. I tried this
var parser: ExpressionParser = new SpelExpressionParser
var context: EvaluationContext = new StandardEvaluationContext(a_case)
var extractedId = parser.parseExpression("'id'").getValue(context).asInstanceOf[String]
All I get is "id" in my extractedId variable. When I try to parse "id" without the single quotes, I get an exception saying the property id is not found in Case. Am I missing something here or is this a Scala issue?
SpEL can do that for you if your id has getter.
I'm not well with Scala, but:
BeanProperty
You can annotate vals and vars with the #BeanProperty annotation. This generates getters/setters that look like POJO getter/setter definitions. If you want the isFoo variant, use the BooleanBeanProperty annotation. The ugly foo$_eq becomes
setFoo("newfoo");
getFoo();
https://twitter.github.io/scala_school/java.html

Array of annotations as parameter to an annotation, in Scala

There are plenty of questions about passing an array as a parameter to an annotation, this is not a dupe of those.
I would like to use a Java-land annotation that takes an array of annotations as a parameter, e.g.
#ManagedOperation
#ManagedOperationParameters({
#ManagedOperationParameter(name="start"),
#ManagedOperationParameter(name="end")
})
def stuff(start: String, end: String): Unit = ???
But this is not valid syntax in Scala, nor is
#ManagedOperation
#ManagedOperationParameters(Array(
#ManagedOperationParameter(name="start"),
#ManagedOperationParameter(name="end")
))
def stuff(start: String, end: String): Unit = ???
so what is the correct way to do this, if it is even possible?
BTW, I even checked all of github to see if any Scala devs are using this (Spring JMX) annotation.
In scala the inner annotation should be used as regular type:
#JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "moduleType",
defaultImpl = classOf[PuppetModule]
)
#JsonSubTypes(Array(
new Type(value = classOf[PuppetModule], name = "puppet"),
new Type(value = classOf[PluginModule], name = "plugin")
))
trait Module {
val moduleType: String = if (this.isInstanceOf[PuppetModule]) "puppet" else "plugin"
val nodes: List[String] = List[String]()
}

Resources