Can I create a custom JUnit 5 annotation #Defect("Ticket-ID") and map that to #Tag("Ticket-ID") - annotations

I want to know how to add a parameter to an annotation, and then use that parameter to help compose an annotation.
As a simple example, suppose I want to define #Defect(<Ticket-ID>). Among other things, that annotation will add #Tag(<Ticket-Id>).
Can I do this? If so, what would the code look like?

I think you can't map #Defect() to #Tag(), don't see the point on it also. You would be only changing Tag name.
What you can do is, create an interface to map #Tag("Defect") and then add a value as a parameter to it:
#Target({TYPE, METHOD})
#Retention(RetentionPolicy.RUNTIME)
#Test
#Tag("Defect")
#interface Defect {
int value();
}
Then you could use it like:
#Defect("JiraIssue-1234");
You can also get the value you pass as parameter like:
AnnotationSupport.findAnnotation(_extensionContext.getElement(), Defect.class).get().value()

Related

how to not allow empty key in Guava Multimap?

I have this kind of situation, where i have a multimap which i add in the end to Oracle DB, which converts empty string("") to null, is there a way i can guarantee in the code that multimap will not allow adding an empty key? (for example Multimap.put("", "some value"))
Thanks.
Both the keys and values of Guava's MultiMap are #Nullable and it doesn't have out of the box functionality to add a validation. So I would just build a validation in the code that puts the values. Something like:
if (!key.isEmpty){
multiMap.put(key, value);
} else {
log("Could not add " +value) // or throw an exception or do something else
}
Updated: after OP clarified that above doesn't apply to his use case, because parsing is done through Spring.
You could look into using ForwardingMultiMap:
A multimap which forwards all its method calls to another multimap. Subclasses should override one or more methods to modify the behavior of the backing multimap as desired per the decorator pattern.
default method warning: This class does not forward calls to default methods. Instead, it inherits their default implementations. When those implementations invoke methods, they invoke methods on the ForwardingMultimap.
https://guava.dev/releases/23.0/api/docs/com/google/common/collect/ForwardingMultimap.html
I have never used this class myself, but it sounds like you can use it to forward to a subclass of your own design. Then in that subclass you could build the validation into the put method.

BeanWrapperFieldSetMapper alternative, to avoid setTargetType/setPrototypeBeanName

I need a way to get rid of fieldSetMapper.setTargetType because I do not want to add a POJO every time I have a new file to read. Is it possible?
Springbatch has a few FieldSetMapper implementations available out-of-the-box : Documentation (FieldSetMapper)
You can for example use a PassThroughFieldSetMapper to get a FieldSet object in your processor. You can do the same with an ArrayFieldSetMapper to get an array object.
But in your case, I think you need to implement your own FieldSetMapper. It could for example have a names property (with a setter) and a targetClass property (with a setter). Using Reflect, you could then cast the object to your desired class and call setters according to the names passed as arguments.
Here's what a FieldSetMapper looks like :
#Override
public Report mapFieldSet(FieldSet fieldSet) throws BindException {
T object;
object.setField(fieldSet.readString(0));
return object;
}
Here's what Reflect looks like :
Method method = object.getClass().getMethod(methodName);
method.invoke(object);

Using Eclipse's JDT, how does one get an IType from a class name?

Is there a simple, straightforward way to get an IType from a class name? I think there must be some static method somewhere. Basically, I'd like to do something like:
IType objectType = Somewhere.getType("java.lang.Object")
Does anybody know of something like this? I have been searching in vain.
Given an IProject, one can use the IJavaProject#findType methods, e.g.
IType objectType = project.findType("java.lang.Object");
Look at org.eclipse.jdt.core.search.SearchEngine. I haven't tried it myself, I'm usually using the ASTParser with the Resolve option on (that's when you parse a source), but it should do the trick.

StructureMap IoC problem getting the instance in runtime

i have 2 concrete types "CategoryFilter" & "StopWordsFilter" that implements
"IWordTokensFilter".
Below is my setup:
ForRequestedType<IWordTokensFilter>().TheDefaultIsConcreteType<CategoryFilter>()
.AddInstances(x =>
{
x.OfConcreteType<StopWordsFilter>();
}
);
The problem is the run-time when structure map auto inject it on my class, bec. i have arguments with same plugin-type:
public ClassA(IWordTokensFilter stopWordsFilter, IWordTokensFilter categoryFilter)
i'm always getting CategoryFilter in my first argument but it should be stopWordsFilter.
How can i setup this in a right way? thanks in advance
There are a number of possible solutions:
1) Does ClassA need to differentiate between the filters, or does it just need to run them both? If not, you can change the constructor to accept an array, which will cause all registered instances of IWordTokensFilter to be injected:
public ClassA(IWordTokensFilter[] filters)
You can then foreach over the filters to apply them.
2) If you do need to differentiate them, because they need to be used differently, you may consider having one implement a marker interface the better describes its purpose. ClassA could then be changed to take in an IWordTokensFilter and an ICategoryFilter (or whatever you name the marker interface). Register CategoryFilter with ICategoryFilter and then both will be injected properly.
public ClassA(IWordTokensFilter stopWordsFilter, ICategoryFilter categoryFilter)
3) You can tell StructureMap explicitly how to create ClassA:
ForRequestedType<ClassA>().TheDefault.Is.ConstructedBy(c => {
return new ClassA(c.GetInstance<StopWordsFilter>(), c.GetInstance<CategoryFilter>());
});
4) You can tell StructureMap to override one of the dependencies for ClassA:
x.ForRequestedType<ClassA>().TheDefault.Is.OfConcreteType<ClassA>()
.CtorDependency<IWordTokensFilter>("stopWordsFilter").Is<StopWordsFilter>();

Wicket: how to use the BodyTagAttributeModifier class?

i'm trying to dynamically add the class attribute to the body tag, and i came across this class. but i can't seem to understand how to use this class. i have something like this in my page class (or panel class, as i tried with that too):
add(new BodyTagAttributeModifier("class", "homepage", this));
this doesn't even compile, saying there's something wrong with the 2nd parameter. but i think String is automatically considered a Model in wicket, like the Label class. am i missing something here?
What if you just add an wicket:id to the body attribute and use the AttributeAppender class? Or, if the body attribute already has an id, can't you just use this class?
http://wicket.sourceforge.net/apidocs/wicket/behavior/AttributeAppender.html
Some Wicket Components have this String-to-model-shortcut (like Label), but it's not a general feature. You have to convert your String into a Model manually:
add(new BodyTagAttributeModifier("class", Model.of("homepage"), this));