make java custom annotation to mark bean properties for html cleansing - java

Can I use a Java custom annotation to add some code to a set or get method on a bean property to cleanse the property from bad html being input by my users? I've been looking for examples but I've not seen something that I feel I can extend.

You could define a custom annotation to add a validator to your setter, but is there a reason why you don't want to just embed validation into your bean without an annotation? The annotation mechanism might be difficult for others to understand if they ever need to work with your code.
I would do it this way: Rather than have your property be a String, define your own HtmlString (assuming an equivalent class doesn't already exist in a standard library) which can only be instantiated with valid HTML. Then, have your bean property be of that type. This would solve the validation problem in your component.
Define validation methods in the HtmlString to fit your requirements, so that every HtmlString instance is valid HTML; then, simply define a toString method. This method would likely be much easier for others to follow.

Related

How to prevent Spring from performing variable replacement

I have a configuration property that needs to be sent to another system as part of a post body.
lets say for example if have an application.properties file with
my.property.raw=${parameter:some-identifier}
I also have a #ConfigurationProperties annotated class that might look like this
#ConfigurationProperties(prefix = "my.property")
public class Properties {
private String raw;
// getters and such
}
The problem i have is that Spring will see ${parameter:some-identifier} and immediately assumes i want it to be injected with a property names "parameter" and if its not there, put "some-identifier". i have tried to set the property to ${parameter:${parameter:some-identifier}} but Spring seems to have accounted for recursive property injection and it still comes out as "some-identifier".
I know i can write some code around that and replace the ":" with something else and change it back after the fact but i'm trying to make this work without any code change.
So in summation, Spring boot sees this as a configuration property ${parameter:some-identifier} upon injection into the ConfigurationProperties annotated class, the value ends up being some-identifier. What i want to happen is the value in the Properties class after Spring does its variable replacement process is ${parameter:some-identifier} as this injectable format of a value is intended for a down stream system that is expecting that format. Preferably, without changing any code. Maybe there is some special formatting i can use to tell spring to ignore this specific property.
Thanks for your time! and yes i realize this is probably the opposite of what people normally want from Spring.
As stated by #Kayaman this is indeed a duplicate of
Escape property reference in Spring property file
The solution i pulled from there, with some modification, was this:
${dollar:$}{parameter:some-identifier}
https://stackoverflow.com/a/48897422/4621716
I did this because i also don't have control over the process that is generating that application.properties beyond changing existing values.
I hope this helps and i wish i could give #Kayaman credit for pointing me in the right direction but i guess i'll accept my own answer. Thanks.

When is expression used in mapStruct?

I am getting started with MapStruct. I am unable to understand when do we use "expression" tag in MapStruct? Why do we have certain mappings where we use "target" tag and "expression" tag? Does it mean that expressions are used when you want to map two or more fields within a bean to a single property/field in the target as mentioned in the documentation "http://mapstruct.org/documentation/stable/reference/html/#expressions"
Expressions are used when you can't map a source - to a target property or when a constant does not apply. MapStruct envisioned that several language could be used to address expressions. However, only plain java is implemented (hence "java(... )" ). EL was envisioned but not yet realised.
A typical use case that I use is generating a UUID. But even there you could try the new #Context to achieve that goal.
Remember, the stuff within the brackets is put directly in the generated code. The IDE can't check its correctness, and you will only spot problems during compilation.
Expressions are IMHO a fallback means / gap filler for stuff that is not yet implemented in MapStruct.
Note: Mapping target-to-source by means of a custom method as suggested in the other answers can be done automatically. MapStruct will recognised the signature (return type, source type) and call your custom method. You can do this in the same interface (default method) or in a used mapper.
In general, MapStruct expressions are used when you simple cannot write a MapStruct mapper. They should be used as a fallback approach when the library doesn't apply to your use-case.
For example, -- as the documentation says -- when a mapping requires more than one source variable, an expression can be used to "inject" them to a mapper method.
Another use case is when the source variable you need to use -- say bar -- is not a part of the source class but a member of one of its variables (here, classVar). You would map it to the target field foo using a custom myCustomMethod method with #Mapping(target="foo", expression="java(myCustomMethod(source.classVar.bar)))".

Is there a pattern to force the setting of a property in an injected component?

I am wondering if there is a pattern that forces the user of my component to set a property after it is autowired. For example i have this:
#SpringComponent
#PrototypeScope
public class MyAutowiredClass {
private String myVariabeThatTheUserShouldSet;
public MyAutowiredClass(someOtherStuff ...(not my StringVariable)){
}
}
In this example how to i force myVariabeThatTheUserShouldSet to be set from the user of this component?
Well it's a bit complicated. If it wasn't in spring context you could just add that variable to the constructor and make it "required" like that. So to achieve that in a Spring context I would advise the following:
If possible pass that value as part of the dependency injection instead of trying to work around it. I understand it is something dynamic but still usually it would have business meaning and there is a way to do it. For example if you want the current user email you can add some Service that retrieves that value and pass that service to your component and extract that value from there. Or if you want some company configuration you can add a Service that gives you that value etc. It is the "Spring" way and I would lean towards that.
A simpler solution would be to add that required field to the methods signature of the methods that actually need it. It will overload the signatures by one field but it would force the users to pass a value. If you need that field for a couple of methods and not for the correct work of the component then it would be the easiest to implement/understand solution.
Add a setter for that value and throw exception if it is not set. That would be the worse though because will require try/catches if the exception is checked and if it is not people will forget to set the field so I would avoid that solution.

Dynamically setting and getting bean properties in XPages

Just another Java problem (I'm a noob, I know): is it possible to use dynamic property binding in a Custom Control with a dynamic property getter in a Java bean?
I'll explain. I use this feature extensively in my Custom Controls:
<xp:inputTextarea id="DF_TiersM">
<xp:this.value><![CDATA[#{compositeData.dataSource[compositeData.fieldName]}]]></xp:this.value>
This is used in a control where both datasource and the name of the field are passed as parameters. This works, so far so good.
Now, in some cases, the datasource is a managed bean. When the above lines are interpreted, apparently code is generated to get or set the value of ... something. But what exactly?
I get this error: Error getting property 'SomeField' from bean of type com.sjef.AnyRecord which I guess is correct for there is no public getSomeField() in my bean. All properties are defined dynamically in the bean.
So how can I make XPages read the properties? Is there a universal getter (and setter) that allows me to use the name of a property as a parameter instead of the inclusion in a fixed method name? If XPages doesn't find getSomeField(), will it try something else instead, e.g. just get(String name) or so?
As always: I really appreciate your help and answers!
The way the binding works depends on whether or not your Java object implements a supported interface. If it doesn't (if it's just some random Java object), then any properties are treated as "bean-style" names, so that, if you want to call ".getSomeField()", then the binding would be like "#{obj.someField}" (or "#{obj['someField']}", or so forth).
If you want it to fall back to a common method, that's a job for either the DataObject or Map interfaces - Map is larger to implement, but is more standard (and you could inherit from AbstractMap if applicable), while DataObject is basically an XPages-ism but one I'm a big fan of (for reference, document data sources are DataObjects). Be warned, though: if you implement one of those, EL will only bind to the get or getValue method and will ignore normal setters and getters. If you want to use those when present, you'll have to write reflection code to do that (I recommend using Apache BeanUtils).
I have a post describing this in more detail on my blog: https://frostillic.us/f.nsf/posts/expanding-your-use-of-el-%28part-1%29

Can I somehow create 1 annotation to replace another with default values?

I fear title is bad, but could not formulate it better. So, I have this code:
#javax.interceptor.Interceptors({EjbSecurityServerInterceptor.class,PermissionInterceptor.class})
Is there a way to create annotation like #SecuredAsHell, that will be an equivalent to aforementioned annotation? Smth like macros, I suppose.
Thanks
No. Sorry, but the fact is that whatever reflection that is used to locate annotations of type javax.interceptor.Interceptors will only locate annotations of that type. There is not way to indicate that another annotation is somehow equivalent.

Categories