Cannot add element to Map - Unsupported Operation Exception - java

I am having trouble inserting element to this mutable Map and i cannot figure out why?
I can see it returns Map so it should not an issue to put element in.
Can you help me with that?
myClient.authentications.put("basicAuthentication", httpBasicAuth)
Authentications look like this:
public Map<String, Authentication> getAuthentications() {
return authentications;
}
private Map<String, Authentication> authentications;
Is there something that i am missing here?
Edit 1:
Adding some more code for clearance
HttpBasicAuth is just a basic class that implements Authentication
public class HttpBasicAuth implements Authentication {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Override
public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams) {
if (username == null && password == null) {
return;
}
headerParams.put("Authorization", Credentials.basic(
username == null ? "" : username,
password == null ? "" : password));
}
val httpBasicAuth = HttpBasicAuth()
httpBasicAuth.username = "user"
httpBasicAuth.password = "pass"
myClient.authentications.put("basicAuthentication", httpBasicAuth)

Currently, by default this field has null value so you CAN NOT call any method on it. So when you call:
myClient.authentications.put("basicAuthentication", httpBasicAuth)
you are trying call method put() on null.
To solve it, you can change your initialization from:
private Map<String, Authentication> authentications;
To (in Java):
private Map<String, String> authentications = new HashMap<>();
or in to (in Kotlin):
private val authentications: Map<String, Authentication> = mapOf();
After those changes this field will be initialized with empty array instead of null. Remember that this change it's very important when you have some logic based on it (e.g. you are checking authentications == null).

Related

How do I get variables of an object from a vector?

My code
package crypto;
import java.util.Vector;
public class Wallet {
public void main() {}
public String username;
public String password;
public int coins;
Vector<Object> wallets = new Vector<Object>();
public Wallet(String username, String password) {
this.username = username;
this.password = password;
this.coins = 0;
}
public void createWallet(String username, String password) {
wallets.add(new Wallet(username, password));
}
public Object findWallet(String username, String password) {
Object wallet;
for (int i = 0; i < wallets.size(); i++) {
wallet = wallets.get(i);
if (wallet.username == username && wallet.password == password) {
return wallet;
}
}
return 0;
}
public void addCoins(String username, String password, int coins) {
Object wallet = findWallet(username, password);
wallet.coins += coins;
}
}
Any help would be appreciated.
This is a test program for a cryptocurrency (just a personal project)
FYI this is just filler text because apparently you have to do that.
Your question is not very clear but let me guess what you need.
You can use generics:
Vector<Wallet> wallets = new Vector<Wallet>();
Anyway why didn't you consider using a simple ArrayList?
List<Wallet> wallets = new ArrayList<>();
Now you have an access to your Wallet methods when looking it up within a vector.
And change Object type to Wallet everywhere.
I would recommend you to rewrite search logic to something like that:
public Wallet findWallet(String userName, String password) {
return wallets.stream()
.filter(e -> e.getUserName().equals(userName))
.filter(e -> e.getPassword().equals(password))
.findAny()
.orElse(null);
}
You can google what getters and setters are.
I would also like to mention that you might want to use separate classes for your Wallet itself and a service that tends to perform operations over it.
I assume you can find more useful info here
I think you need method get(int index). It returns the element at the specified position in your Vector.

Firebase Database - Unable to retrieve nested data

I'm unable to retrieve the data which is nested inside "Leagues" and "Season".
In the database below, I cannot retrieve Season 2016/2017 points and results.
I am able to access the data that is not nested, such as Email and Username without problems
"Users" :
"User1" : {
"Email" : "dfs#sdf.com",
"Last_login" : "5:15pm",
"Username" : "Test",
"Leagues" : {
"FootballLeague" : true,
"CricketLeague" : true
},
"Season" : {
"2017" : {
"Points" : 5,
"Results" : 2
"newdata" : {
"randomdata1: data1",
"randomdata2: data2"
},
}
"2018" : {
"Points" : 7,
"Results" : 2
}
}
The following class is what I'm using to store data as objects:
public class Users {
private String Username;
private String Email;
private String Last_login;
private Map<String, Boolean> Leagues;
private Map<String, thisSeason> Season;
public Users() {
}
//All getters and setters for the strings.
public Map<String, Boolean> get_joined_Leagues() {
return Leagues;
}
public void set_joined_Leagues(Map<String, Boolean> leagues) {
Leagues = leagues;
}
public Map<String, thisSeason> getSeason() {
return Season;
}
public void set_thisSeason(Map<String, thisSeason> season) {
Season = season;
}
public static class thisSeason {
private int Points;
private int Results;
private Map <String, thisNewData> newdata;
public thisSeason() {
}
public int getthisSeason_results() {
return Results;
}
public void setthisSeason_results(int resultsin) {
Results = resultsin;
}
public int getthisSeason_points() {
return Points;
}
public void setSeason_points(int Pointsin) {
Points = Pointsin;
}
public Map<String, thisNewData> getNewData() {
return newdata;
}
public void set_thisNewData(Map<String, thisNewData> newdata_in) {
newdata= newdata_in;
}
public static class thisNewData {
private String randomdata1;
private String randomdata2;
//Getters and Setters
}
Here is part of my Java class where I access the Database:
List<Users> usersList= new ArrayList<Users>();
DatabaseReference fbDB = FirebaseDatabase.getInstance().getReference();
fbDB.child("Users").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
Users C = ds.getValue(Users.class);
usersList.add(C);
System.out.println(C.getSeason().getthisSeason_points()); //ERROR occurs here - null object reference
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
I get a null object reference error as shown in the code above.
Also, on a slight side note - I'm aware my implementation for getting Leagues is incorrect. How can I retrieve the keys instead?
The main problems that I found in your code:
First, your Leagues object:
Well, it should not be a custom object at all, if it stays in the current structure, but a Map. This is the map object - a collection which has a key, and a value, just like a child in the Realtime Database.
If a league name (=key) didn't have a true (=value) next to it - the names could have been stored in String variables, but this is not the case, because every child in the Realtime Database must have a value, and storing a "dummy" value next to a league name makes each league a part of a Map. This current "dummy" is a boolean, and that's why this will be the leagues' data type:Map<String, Boolean> leagues.
Second, your Season object:
You are confusing between one season and many seasons. Your child - "Season" actually stores a lot of seasons. Thats why this case will be similar to the one above - each season's time is the key and the season itself is the value.
Therefore, the User class's variables should be:
private String Username;
private String Email;
private String Last_login;
private Map<String,Boolean> Leagues;
private Map<String, Season> Seasons;

Jackson serialization with null

Jackson annotations are for serialization but I cannot find the solution to have two different views with different behavior. Having the following json:
{
"username": "username",
"manager": null,
"password": "pwd"
}
I'd like to have to following output in case the first view (public: no null and no sensitive information):
{
"username": "username"
}
For the second view (internal: incoming nulls are showed sensitive information is hashed):
{
"username": "username",
"manager": null,
"password": "hashedValue"
}
The problem is when the optional fields are not provided like in the following json:
{
"password": "pwd"
}
I'd like to have an empty for public and only the hashed password in the internal view:
{
"password": "hashedValue"
}
I have the following class:
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Test {
private String username;
private String manager;
private String password;
#JsonView(Views.Internal.class)
#JsonSerialize(using = Md5Serializer.class)
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getManager() {
return manager;
}
public void setManager(String manager) {
this.manager = manager;
}
}
This can do most what I'd like to have but it cannot make difference if a value is null because of the default value or because it's coming from the JSON.
An other approach was to use a Map inside the object:
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Test {
private Map<String, String> content = new HashMap<>();
#JsonView(Views.Internal.class)
#JsonSerialize(using = Md5Serializer.class)
#JsonIgnore
public String getPassword() {
return this.content.get("password");
}
#JsonSetter
public void setPassword(String password) {
this.content.put("password", password);
}
#JsonIgnore
public String getUsername() {
return this.content.get("username");
}
#JsonSetter
public void setUsername(String username) {
this.content.put("username", username);
}
#JsonIgnore
public String getManager() {
return this.content.get("manager");
}
#JsonSetter
public void setManager(String manager) {
this.content.put("manager", manager);
}
#JsonAnyGetter
public Map<String, String> getContent() {
return this.content;
}
}
In this case the problem that the password is not hashed (and the hashed value cannot be stored here).
If the getters are used and the JsonAnyGetter is removed then the incoming null cannot be serialized as the JsonInclude ignores the field. I was reading a lot that a BeanSerializerModifier can be used but that is also needed to be register in all ObjectMapper instance.
Also I'm not sure that without setting the view I'd like to have only the Public view but currently all non-null values are shown. Any idea how it can be achieved only by annotations?

Struts2 setter method for POST parameter with dash

I have mailgun.com routes to forward email POST to my Struts2 Action. The mailgun POST request content dashes in some parameter names: sender, subject (OK) but how can I map setter method in my Struts2 Action for POST parameter: body-plain (contain dash), body-html, message-headers, Content-Type ?
I have try this but not work bodyPlain=null:
public class MyAction extends ActionSupport {
private String sender;
private String subject;
private String bodyPlain;
public String execute() {
LOG.info(sender);
LOG.info(subject);
LOG.info(bodyPlain);
return SUCCESS;
}
public void setSender(String sender) {
this.sender = sender;
}
public void setSubject(String subject) {
this.subject = subject;
}
public void setBodyPlain(String bodyPlain) {
this.bodyPlain = bodyPlain;
}
}
I can`t change mailgun service code. This is my code to deal with Struts2 naming conventions. If its have more clean solution for this problem let me know.
public class MyAction extends ActionSupport implements ParameterAware {
private String sender;
private String subject;
private String bodyPlain;
public String execute() {
LOG.info(sender);
LOG.info(subject);
LOG.info(bodyPlain);
return SUCCESS;
}
public void setSender(String sender) {
this.sender = sender;
}
public void setSubject(String subject) {
this.subject = subject;
}
#Override
public void setParameters(Map<String, String[]> parameters) {
if (parameters != null) {
for (Map.Entry<String, String[]> entry : parameters.entrySet()) {
String key = entry.getKey();
String[] value = entry.getValue();
if(key.equals("body-plain") && value.length > 0) this.bodyPlain = value[0];
LOG.info("key:" + key + " value:" + Arrays.toString(value));
}
}
}
}
Then you need to rename body-plain to bodyPlain to map parameters to the action fields. Java and naming conventions use camelCased instance variables for classes. And this is an obligatory rule to map request parameters to the action class.
You can translate/rename them on any level, filter, url-rewrite rule, interceptor, etc. Any way parameters are passed to the ActionContext that is a map, then traversing the map and remove dashes from the key names would be easy if you try
Map<String, Object[]> parameters = ActionContext.getContext().getParameters();

using OVal validation framework in Java

I use OVal framework for validate business objects in my java projects.
please see validation class :
public class ObjectValidation implements ObjectValidatable {
private IValidator validator;
private Map<String, String> errorMessages;
public ObjectValidation() {
validator = new Validator();
}
public boolean isValid() {
if (validate().size() > 0)
return false;
return true;
}
public List<ConstraintViolation> validate() {
return validator.validate(this);
}
public Map<String, String> getErrorMessages()
{
if(this.isValid()) return null;
errorMessages = new HashMap<String, String>();
for(ConstraintViolation cv : this.validate())
errorMessages.put(cv.???, cv.getMessage());
return errorMessages;
}
}
AND
public class Account extends DomainObject {
#NotNull
#NotEmpty
#NotBlank
#Length(max = 5)
private String userName; // How Get This ???
private String password;
private int securityId;
private String securityAnswer;
...
}
I have getErrorMessages that return Map
I want it return like this userName-must be not null
second section "must be not null" can get with cv.getMessage()
but first section that have validation annotation is my question
How get userName or another fields that have validation annotation ???
Have a look at the ConstraintViolation.getCauses() and the ConstraintViolation.getContext() method. They should provide what you need.

Categories