Redefine ConstraintViolation from hibernate validator - java

We are using the java EE 7 with Wildfly 10.0. In the last few days I am learning a lot of Bean validation feature that is included in Java EE 7 specification. It sounds promising, as I see many advantages in using annotations for validations including reusabilty and cleaner code.
However the javax.validation.Validator returns a Set of ConstraintViolations.
Now, the ConstraintViolation has a message attached to it which you can get from it with getMesssage(). The type of the message is a String.
However, for our error handling we use a custom type that we created called a Pair<int, String>, to return message to the client including error code and a message.
Here is an example of how our pairs look like:
public static final Pair<Integer, String> NAME_VALIDATION_ERROR = new Pair<Integer, String>(
201, "Name must contain only letters");
Now, this is all in a class called ErrorStrings and it's easy to use because that class contains static methods and when you start typing ErrorStrings. the autocomplete gives you the names of the error pairs you can use. For example NAME_VALIDATION_ERROR.
So, what would be the easiest way to add Pair<int, String> to the ConstraintViolation, so that it can be used to return the response to the client without adding complexity to the code.
I thougth of adding a Hashmap<String, Pair<int, String>> to the ErrorStrings class, and using a message defined in ConstraintViolation as a key, but that would add much complexity to that class as you would have to change a pair and a hashmap when you would like to change or add some error.
I am using a hibernate validator, which is a default implementation for Jave EE, but I am willing to use any other implementation. I would like to know the easiest way, to redefine ConstraintViolation so it has Pair<int, String> in it.

The "easiest" way I know is that you should create your own custom contraints, which would throw custom ConstraintViolation implementations, which could also have a public Pair<Integer, String> getMessagePair() method. But this would be even more complex, as it would require you to reimplement every single validation you do.
Personally I would do the translation from String to Pair<Integer, String> in a new ErrorStringTranslator class. This is a bit cleaner solution than the one you mentioned, but doesn't save you from the complexity of the task.

Related

How to place a Map into another Map in Java

I'm doing a personal project.
After a lot of maps, I came to the point where I want to enter a map inside another map... Let me explain better.
I have this Map atPropostas which have information about a person, but at some time of the program, I want to add to that person a boss email.
private Map<String, Long> atPropostas;
private Map<String,Map<String,Long>> atOrientadores;
To add that boss email, I've done this:
for (Map.Entry<String, Long> atprop : atPropostas.entrySet()) {
for (Map.Entry<String, Proposta> prop : propostas.entrySet()) {
if (prop.getValue().getTipo().equals("T2") && propostas.containsKey(atprop.getKey())) {
atOrientadores.put(prop.getValue().getEmailDocente(), atprop);
}
}
}
But, atprop value, inside atOrientadores.put() it produces an error:
java: incompatible types:
java.util.Map.Entry<java.lang.String,java.lang.Long> cannot be
converted to java.util.Map<java.lang.String,java.lang.Long>
I have tried to cast the atprop:
atOrientadores.put(prop.getValue().getEmailDocente(), (Map<String, Long>) atprop);
And the compiler error disappears, but the App itself, doesn't working.
You can't convert Map.Entry in to a Map with casting.
Map and entry represent inherently different notions. Map consists of entries, it isn't an entry.
You can create a single entry map by using static method Map.ofEntries() available with Java 9
atOrientadores.put(prop.getValue().getEmailDocente(), Map.ofEntries(atprop));
Sidenote: it's highly advisable to use English while giving names to variables, classes, etc. in your application. It makes it easier to reason about your code.
I don't know for sure what atprop is meant to represent, but you've mentioned a person and an email. I advise you to consider creating classes that would correspond to a person and an email instead of complicating your code and dealing with nested maps.

Mockito anyListOf, anyMapOf, anyCollectionOf deprecated replacement

I am working on a Java 8 to Java 17 update and the project includes a very old version of Mockito.
When I update the library to Mockito 4.4.0 I found out that there many libraries which has been completely removed, most of them are related with validation of objects that you can set the variable type at compilation time, for instance:
If you have the following object:
Map<String,Object> map
Then you can validate with Mokito if the map is of type String, Object by using:
anyMapOf(String.class,Object.class)
The thing in here is that I thought that one of this both could be a good approach:
//Create the map first
Map<String,Object> map = new HashMap<>();
//Then use the method "any" calling the getClass method
any(map.getClass())
But now I'm pretty sure that it is not the same.
On the other hand, I found the following forum:
java generics: getting class of a class with generic parameters
From which I get this code:
(Class<Map<String,Object>>)(Class)Map.class
This also seems to work if you use it with any, like so:
any((Class<Map<String,Object>>)(Class)Map.class)
But obviously, it triggers a warning message and it doesn't seem to be the best solution.
Finally, I read in the Mockito documentation that this clases were only used for generic friendliness to avoid casting before Java 8, so that means that if I use anyMap in Java 8 and upwards it will work the same as anyMapOf?
I have been searching for hours for which could be the best replacement for this deprecated method but I just can't find the right answer.
Try this:
ArgumentMatchers.<String,Object>anyMap()
or this:
Map<String,Object> mapToGoIntoTheMock = anyMap()

Calling Java method that uses hash map as a parameter

I have a method in an android application:
public void changeImageView (HashMap<String,String> Detail)
I have been trying to call this method in the onCreate method in the same class.
I have tried:
changeImageView();
and
changeImageView(HashMap<String,String> Detail);
Both of which give me errors. The first gives me an error stating that the parameters are missing - understandable. But when I try the second version, I get an error saying "expression expected" with HashMap<String,String>.
I am probably missing something very obvious and have been unable to find anything online that can answer my question.
First, create an instance of HashMap<String, String>.
Map<String, String> map = new HashMap<>();
After its filling or other operations on the map, pass it as a parameter to your method.
changeImageView(map);
I would suggest you reading about methods on Oracle Tutorials.
HashMap is a collection class available in java.util package.
A method changeImageView() here has a definition which takes a HashMap object of type [Generic Type : Google it to know more about it].
You need to create a HashMap object :
Map<String,String> map=new HashMap<String,String>();
You can add values to the above hashmap as given below :
map.add("key1","value1");
map.add("key2","value3");
depending upon your requirements.
Now you can pass this map object to the changeImageView() method as given below:
changeImageView(map)
Seems like you are a newbie to Java and OOP , please refer any Java basic tutorials . This will help you to build up your basic concepts.

Is there a possibility to keep a single map store and use for multiple maps in hazelcast

Currently am using Hazelcast and persistence database as Hbase,
So far I have 10 maps, for each map am using a map store, So Am using 10 mapstore classes (i.e) In all the 10 classes am implementing the MapStore. It creates a complexity in maintenance.
So What I did is, I kept a generic map store and implemented the same class for all the maps, It has the ability to accept it, To make it clear, I did something like
Map1 - com.test.GenericMapStore
Map2 - com.test.GenericMapStore
Map3 - com.test.GenericMapStore
...
Map10 - com.test.GenericMapStore
It gets mapped as above,
But for the methods in store, storeAll, loadAllKeys, loadAll am able to check the instance of object and find the mapName ---- Not a good way
But for methods like delete, deleteAll, load - I dont have any clue to find the mapName,
Pls tell me like any way to use a singleMapStore for all the maps???
So I need a map store implementation where, for all methods in mapstore, I need the PARAM called mapName to be passed, So In case, If I have common Implementation, I can make use of it just by using MAP NAME param in all the methods,
Example :
Store(String key, Object object, String mapName),
StoreAll(Map, String mapName),
delete(String key, String mapName)
delete(Collections keys, String mapName) ...
If there is a way already available, Pls do let me know...
Thanks hazelcast team,,, You ppl are doing the great job... Much Apprecaiated...
Thanks and Regards,
Harry
You should be able to achieve this with a MapStoreFactory (docs).
The MapStoreFactory is called with the name of the map and you can pass that name into the GenericMapStore.
In you MapStoreFactory :
public MapLoader newMapStore(mapName, props) {
return new GenericMapStore(mapName);
}
then in GenericMapStore you will have the mapName for each operation.

Passing information between Java LoginModules (Generic Map Problem)

I am currently trying to write some LoginModules to enable users to log into a Java application. Here is my .java.login.config file:
"Java Application" {
path.to.login.module.PamLoginModule sufficient;
path.to.login.module.OtherLoginModule sufficient;
};
So if the PamLoginModule fails, I want to pass information to the OtherLoginModule. This way, the OtherLoginModule doesn't have to ask for the user name and password again. So I am guessing that this is what the sharedState Map is for in the initialize() function:
initialize(Subject subject, CallbackHandler callbackHandler,
Map<String,?> sharedState, Map<String,?> options)
The problem is that you can't put things into the sharedState map. If I do something like:
sharedState.put("key", value); // Value is a string
The compiler complains:
path/to/login/module/PamLoginModule.java:48: put(java.lang.String,capture#833 of ?) in java.util.Map<java.lang.String,capture#833 of ?> cannot be applied to (java.lang.String,java.lang.String)
this.sharedState.put("key", value);
I have found a way to get around this, but I want to know what the correct way is.
First, I can use the java 1.4.2 version of initialize which is:
initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
This way I just receive generic maps and I can just cast the Map object to a Map
Map<String,Object> this.sharedState = (Map<String,Object>)sharedState;
The problem is that I still get unchecked cast exceptions. Now, I know the people who made the LoginModule interface aren't stupid, so I am wondering why they made the sharedState map a Map<String,?> as opposed to a Map<String,Object>. Also, is there a better way to put things into the sharedState map?
Thanks!
If you look at the LoginModule implementations in the Java SDK, they save those maps into local fields without the generics info, that is plain Maps. And in the code they do put objects there (at least when the user is authenticated). So the use of the question mark in the LoginModule interface has to be a design mistake.
I am wondering why they made the
sharedState map a Map<String,?> as
opposed to a Map<String,Object>.
This is exactly what I'm wondering.
I guess the purpose of using ? is to accept anything (I don't really see another explanation), so using Object would be completely right and standard.
If you're posting here I guess you cannot ask who coded it this way (using ?) to know why.
Therefore you should investigate a bit the related classes/methods to discover if there is really a meaningful and specific use for ?. Otherwise you should make it a <String, Object>.
I've personnally never seen that current use, except when ? is specified as <? implements MyInterface> or <T extends MySuperClass> for example. In the first case, you should be able to do Map<String, MyInterface> anyway with the same result.
Sorry if I don't have a specific answer but I hope this helps you!

Categories

Resources