Declaring object type via String - java

Here is my function:
private boolean CheckPassword(String type, String login, String passwordHash) {
EntityManagerFactory entityManagerFactory
= Persistence.createEntityManagerFactory("kwestionariuszFor" + type);
EntityManager entityManager
= entityManagerFactory.createEntityManager();
type = type.substring(0, 1).toUpperCase() + type.substring(1, type.length());
List<Object> entities
= entityManager.createNamedQuery(type + ".findByLogin").setParameter("login", login).getResultList();
if (passwordHash.equals(entities.get(0).Password)) {
return true;
}
else {
return false;
}
}
The Java doesn't "know" that there IS Password column in any of the tables. I was thinking that the way to tell it so may look like this:
List<type.toClass()>
or something... is there any way to achieve what I want? I don't want to create if, after if, after if... -_-'

You must create a common type for all of your classes that represent database tables.
Like this:
public abstract class PasswordObject {
private String password;
public PasswordObject(String password) {
this.password = password;
}
public String getPassword() {
return password;
}
}
I don't know if the method createNamedQuery would be able to return a List<PassowrdObject>, but if not, you can just cast it like this (as long as it's safe to do so, which you can only tell by the way you use it):
PasswordObject po = (PasswordObject) entities.get(0);
String password = po.getPassword();

Related

Problem with Either and errors types incompatibility

I have a problem with Either errors types incompatibility.
A method to create Account entity:
static Either<AccountError,Account> create(
String userNameCandidate,
UserNameUniquenessValidator userNameUniquenessValidator,
String passwordCandidate,
PasswordEncoder passwordEncoder) {
return UserName
.create(userNameCandidate,userNameUniquenessValidator)
.flatMap(correctUserName -> Password
.create(passwordCandidate,passwordEncoder)
.map(correctPassword -> new Account(correctUserName,correctPassword)));
}
UserName and Password value objects:
#Embeddable
final class UserName implements Serializable {
public static final Integer MIN_USER_NAME_LENGTH = 3;
public static final Integer MAX_USER_NAME_LENGTH = 15;
#Column
private final String userName;
UserName(String userNam) {
this.userName = userNam;
}
//For JPA only.Don't use!
public UserName() {
this.userName = "default";
}
static Either<WrongUserNameFormatError,UserName> create(
String userNameCandidate,
UserNameUniquenessValidator userNameUniquenessValidator) {
if (userNameCandidate.isEmpty()) {
return Either.left(new WrongUserNameFormatError("Empty user name."));
}
var isUserNameCandidateLengthWrong =
userNameCandidate.length() < MIN_USER_NAME_LENGTH &&
userNameCandidate.length() > MAX_USER_NAME_LENGTH;
if (isUserNameCandidateLengthWrong) {
return Either.left(new WrongUserNameFormatError(
"Wrong user name length: " + userNameCandidate.length() +
".Min: " + MIN_USER_NAME_LENGTH +
".Max: " + MAX_USER_NAME_LENGTH));
}
if (!userNameUniquenessValidator.isUnique(userNameCandidate)) {
return Either.left(new WrongUserNameFormatError("Not unique user name: " +
userNameCandidate));
}
return Either.right(new UserName(userNameCandidate));
}
public String getUserName() {
return userName;
}
}
#Embeddable
final class Password implements Serializable {
public static final Integer MIN_PASSWORD_LENGTH = 5;
#Column
private final String password;
private Password(String password) {
this.password = password;
}
//For JPA only.Don't use!
public Password() {
this.password = "default";
}
static Either<WrongPasswordFormatError,Password> create(String passwordCandidate, PasswordEncoder passwordEncoder) {
if (passwordCandidate.length() >= MIN_PASSWORD_LENGTH) {
var encodedPassword= passwordEncoder.encode(passwordCandidate);
return Either.right(new Password(encodedPassword));
}
else {
return Either.left(new WrongPasswordFormatError(
"Wrong password length: " + passwordCandidate.length() +
". Min: " + MIN_PASSWORD_LENGTH));
}
}
public String getPassword() {
return password;
}
}
I get error: Required Either<AccountError,Account>, provided Either<WrongUserNameFormat, Object>, incompatible constraint: AccountError and WrongUserNameFormatError even though all errors extends AccountError.
I'd use Validation here since there you can collect (validation) errors. :
Since I don't have the object types of your example I came up with this:
Validation<Seq<? extends Number>, String> c = Validation.invalid(io.vavr.collection.List.of(1L));
Validation<Seq<? extends Number>, String> d = Validation.valid("x");
final Validation<Seq<? extends Number>, String> result = c.flatMap(s -> d);
Validation is basically a special case of Either (there is also a .toEither on the Validation object).
c is the result of UserName.create and d Password.create
The 'trick' is to use a Seq here instead of the Object type directly. I can't explain why (so I realize this might sound like bad advice).
In our project we use this construction extensively since we often can have multiple validation errors in our flows and then the left side is always the same and easy to carry over to other flows.
The issue is that Either<WrongUserNameFormat, ...> does not extend Either<AccountError, ...> even though WrongUserNameFormat may extend AccountError. This is because Java does not have good support for type parameter variance. VAVr recognizes this issue, so it provides the narrow method for many of it's types including Either. So you can wrap the return value of Account.create with Either.<AccountError, Account>narrow(...).

java map values from an object

I am new to collections and looking for help. I am trying to search a map using a key, and return the values of the key which is from another object. This is my code so far.
public class Employer {
Map<String, NewHire> employee = new HashMap<>();
}
public void addEmployee(String fullName, String age, String location, String JobTitle) {
NewHire newEmployee = new NewHire(age, location, JobTitle);
this.employee.put(fullName, newEmployee);
}
The code for the other object is -
public class NewHire {
private String age;
private String location;
private String jobTitle;
}
public NewHire(String aAge, String aLocation, String aJobTitle) {
this.age = aAge;
this.location = aLocation;
this.jobTitle = aJobTitle;
}
I then create like so -
Employer CompanyA = new Employer();
CompanyA.addEmployee("JohnSmith", "23", "London", "Service Desk");
I wanted to create a method that can search the map for a key specified by the user, in this case "JohnSmith", and if found, it then shows me the age, location and jobTitle of that person but I really am not sure how I would go about this.
The best way to go about it in my opinion is the way Titulum said, using Optional.
I would just leave another way, a bit not so nice, but you may understand it better.
You can Override the toString() method in the NewHire class and use it, or create getters for the properties:
#Override
public String toString(){
return String.format("Age: %s\nLocation: %s\nJobTitle: %s", age, location, jobTitle);
}
// getters
public String getJobTitle() {
return jobTitle;
}
public String getLocation() {
return location;
}
public String getAge() {
return age;
}
On your Employer class, if you want to use the not so much nicer way of doing it (although i recommend using Optional):
public NewHire getEmployeeByName(String fullName){
return employee.get(fullName);
}
Then to use it:
Employer employer = new Employer();
employer.addEmployee("JohnSmith", "23", "London", "Service Desk");
NewHire newHire = employer.getEmployeeByName("sJohnSmith");
if(newHire != null) {
System.out.println(newHire.toString());
// using getters
System.out.println(newHire.getAge());
System.out.println(newHire.getJobTitle());
System.out.println(newHire.getLocation());
}
You can simply write the method as follows:
public Optional<NewHire> findByFullName(String fullName) {
return Optional.ofNullable(employee.get(fullName));
}
This will return you an Optional, which is an Object in Java that contains either something or nothing. To see if the Optional contains anything you can do:
Optional<NewHire> possiblyFoundNewHire = findByFullName("SomeName");
possibleFoundNewHire.ifPresent(newHire -> {
System.out.println(newHire); // Or formatted as you would like.
});

Is there any generic based alternatives for setting parameters in PrepareStatement

I am developing a database application. Currently I am using java.sql combined with H2 embedded database. I would like to develop the Don't Repeat Yourself way.
So I set up a reuseable Database Row class and Database Property class as follows:
public class DatabaseProperty {
private String PropertyName;
private T Value;
private boolean Identifier;
public DatabaseProperty(String PropertyName, T Value, boolean identifier) {
this.PropertyName = PropertyName;
this.Value = Value;
this.Identifier = identifier;
}
public String getPropertyName() {
return PropertyName;
}
public T getValue() {
return Value;
}
public void setValue(T Value) {
this.Value = Value;
}
public boolean isIdentifier() {
return Identifier;
}
}
And...
public class DatabaseRow {
protected Connection DBConnection;
protected String TableName;
protected HashSet = new HashSet<>();
public DatabaseRow() //With all the above variables. Apologies for being lazy to type ;)
//Here's the problem part
//I'm trying to automatically generate an SQL Statement
//to check that the row specified by primary unique keys (ex:- Username and Password Combination for Log In)
public boolean existsInTable(){
try {
String SQL = "SELECT * FROM "+TableName+" WHERE ";
boolean addAND = false;
for(DatabaseProperty d:Columns) {
if(d.isIdentifier()) {
SQL+=(addAND?"AND ":"")+d.getPropertyName()+" = ? ";
addAND = true;
}
}
PreparedStatement ps = getDBConnection().prepareStatement(SQL);
And the code goes on...
The problem is that I do not have Generic based methods for setting parameters in PeparedStatement class. Instead there is setString(int index,String s), etc..
Please help me to overcome this..
Is there any object oriented wrappers available, like NotORM for PHP? Is there any trade off between performance and coding ease with such options?
Try to use this:
ps.setObject(index, object);
It should work in all cases where index is not null. I think it is not a problem for your case.
If object is null, then you need to set the type
ps.setObject(index, null, type);
The type you can get from the parameter metadata object:
ParameterMetaData meta=ps.getParameterMetaData();
int type = meta.getParameterType(index);

Different Connections to Different Database by checking Map size

I have a HashMap that look something like this-
HashMap<String, TableConnectionInfo> tableList
which means it's value is a Class TableConnectionInfo which looks something like this-
public class TableConnectionInfo {
public String url;
public String user;
public String password;
public String driver;
public String suffix;
public String sql;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public String getSuffix() {
return suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
public String getSql() {
return sql;
}
public void setSql(String sql) {
this.sql = sql;
}
}
So Suppose, If I have two values in the above HashMap. That means, I need to make two different connections to two different database. And suppose if that map has three values, then I need to make three different connections to three different database.
In the main thread, I am populating the above map by reading it from the properties file like this and after that this map won't get modified.
for (String arg : databaseNames) {
TableConnectionInfo ci = new TableConnectionInfo();
String url = prop.getProperty(arg + ".url");
String user = prop.getProperty(arg + ".user");
String password = prop.getProperty(arg + ".password");
String driver = prop.getProperty(arg + ".driver");
String suffix = prop.getProperty(arg + ".suffix");
String sql = prop.getProperty(arg + ".sql");
ci.setUrl(url);
ci.setDriver(driver);
ci.setPassword(password);
ci.setSql(sql);
ci.setSuffix(suffix);
ci.setUser(user);
tableList.put(arg, ci);
}
Now I am passing this tableList map to various threads like this and it won't be modified (by making set calls) by any thread. Each thread will be using get method to get the required method.
for (int i = 0; i< 1000; i++) {
service.submit(new Task(tableList));
}
So in the run method I need to make different conenctions basis on the tableList size. So if tableList size is two, that means I need to make two different connections, callableStatements and methods to two different database.
Question:-
So is there any better way as compared to way I am doing in my run method to create different connections to database basis on tableList size ?
Below is my Task class that impelements Runnable Interface
class Task implements Runnable {
private Connection[] dbConnection = null;
private CallableStatement[] callableStatement = null;
private ArrayList<Method> methods[] = null;
private final HashMap<String, TableConnectionInfo> tableLists;
public Task(HashMap<String, TableConnectionInfo> tableList) {
this.tableLists = tableList;
}
#Override
public void run() {
try {
int j = 0;
dbConnection = new Connection[tableLists.size()];
callableStatement = new CallableStatement[tableLists.size()];
methods = new ArrayList[tableLists.size()];
for (TableConnectionInfo ci : tableLists.values()) {
dbConnection[j] = getDBConnection(ci.getUrl(), ci.getUser(), ci.getPassword(), ci.getDriver());
callableStatement[j] = dbConnection[j].prepareCall(ci.getSql());
methods[j] = getRequiredMethods(ci.getSuffix());
j++;
}
}
}
}
Make a connection to that database-
private Connection getDBConnection(String url, String username, String password, String driver) {
Connection dbConnection = null;
try {
Class.forName(driver);
dbConnection = DriverManager.getConnection(url, username, password);
}
return dbConnection;
}
Just to add here getRequiredMethods will get all the methodNames of a particular table. So suppose if tableList size is 1 then we will be having only one connection to that database so getRequiredMethods will get all the methods for that table1 and store it in a ArrayList. But suppose if tableList size is 2 then we will be having two different connections to two different database so that is the reason I made methods as an array so that it can hold methods for table 1 and methods for table 2.
Ok, I'm still not sure how the Task is meant to use the data it's getting. But, I would move the getConnection, getCallableStatement and getMethods() functions to methods on the TableConnectionInfo. You can simply create a Collection of TableConnectionInfo (initialised as you already have, storing in an ArrayList). Then the Runnable simply iterates through the TableConnectionInfo.
public class TableConnectionInfo {
private String url;
private String user;
private String password;
private String driver;
private String suffix;
private String sql;
private Connection connection;
<snip... getters and setters for the properties>
public Connection getConnection() {
// TODO create and return a connection
if (connection == null) {
// create the connection
}
return connection;
}
public CallableStatement getCallableStatement() {
// get the callable statement
return null;
}
public Collection<Method> getMethods() {
// Get the Methods
return null;
}
}
public class TableTask implements Runnable {
private Collection<TableConnectionInfo> tables;
public TableTask(Collection<TableConnectionInfo> tables) {
this.tables = tables;
}
#Override
public void run() {
for (TableConnectionInfo table : tables) {
// do something with table.getConnection(), or table.getCallableStatement()
// and/or table.getMethods()
}
}
}

What's good practice of creating input validation method in Java?

If I want to validate my input, should I make validation code as private helper methods or create a separate static helper class? Does the validation code increase the size of the object?
More Information
Let's say I have a class
import java.util.Vector;
public class Place {
private final double longitude;
private final double latitude;
private final String id;
private String address;
private String name;
private String types;
private String icon;
private String phoneNumber;
private String websiteUrl;
private int rating;
private Vector<Integer> challenges;
public static class Builder {
// required parameter
private final double longitude;
private final double latitude;
private final String id;
// optional parameter
private String address = "n/a";
private String name = "n/a";
private String icon = "n/a";
private String phoneNumber = "n/a";
private String websiteUrl = "n/a";
private String types = "n/a";
private Vector<Integer> challenges = new Vector<Integer>();
private int rating = 0;
public Builder(double longitude, double latitude, String id) {
assert(longitude >= -180.0 && longitude <= 180.0);
assert(latitude >= -90.0 && longitude <= 90.0);
this.longitude = longitude;
this.latitude = latitude;
this.id = id;
}
public Builder address(String address) {
this.address = address;
return this;
}
public Builder types(String types) {
this.types = types;
return this;
}
public Builder name(String name) {
this.name = name;
return this;
}
public Builder icon(String icon) {
this.icon = icon;
return this;
}
public Builder phoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
return this;
}
public Builder websiteUrl(String websiteUrl) {
this.websiteUrl = websiteUrl;
return this;
}
public Builder builder(int rating) {
this.rating = rating;
return this;
}
public Place build() {
return new Place(this);
}
}
public Place(Builder builder) {
// required parameters
longitude = builder.longitude;
latitude = builder.latitude;
id = builder.id;
// optional parameters
address = builder.address;
types = builder.types;
name = builder.name;
icon = builder.icon;
phoneNumber = builder.phoneNumber;
websiteUrl = builder.websiteUrl;
rating = builder.rating;
challenges = builder.challenges;
}
public double getLongitude() {
return longitude;
}
public double getLatitude() {
return latitude;
}
public String getId() {
return id;
}
public void setAddress(String address) {
this.address = address;
}
public String getAddress() {
return address;
}
public String getTypes() {
return types;
}
public void setTypes(String types) {
this.types = types;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setIconUrl(String icon) {
this.icon = icon;
}
public String getIcon() {
return icon;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setWebsiteUrl(String websiteUrl) {
this.websiteUrl = websiteUrl;
}
public String getWebsiteUrl() {
return websiteUrl;
}
public void setRating(int rating) {
this.rating = rating;
}
public int getRating() {
return rating;
}
#Override
public String toString() {
return "(" + Double.toString(longitude) + ", " + Double.toString(latitude) + ")";
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Place other = (Place) obj;
if (id == null) {
if (other.id != null)
return false;
}
else if (!id.equals(other.id))
return false;
return true;
}
public Vector<Integer> getChallenges() {
return new Vector<Integer>(challenges);
}
public void addChallenges(Integer i) {
this.challenges.add(i);
}
public void showChallenges() {
for (Integer i : challenges) {
System.out.print(i + ", ");
}
}
}
If I have to validate address argument before setting it, where should I put the code for validating address in this case?
If you are talking just seeing if the entered String is formatted correctly or if the length is right, then you would use a private method. If you would on the other hand check if the address is correct (look it up on a map) or any more advanced stuff, it would make sense to create a AddressValidator interface and call it from that private method.
The reason for the private method being that you call this both from a constructor, setter or any other method that could suppy an address. The reason for the interface being that you might want to have e.g. an online / offline AddressValidator (MockAddressValidator, or one that calls a different class for each country etc).
As an AddressValidator could be reused in other classes, and to keep your code clean, I would create it as a top level interface + OnlineAddressValidator. This makes your class better readable as well. For full configurability, you might want to think about how you are going to supply the AddressValidator instance, e.g. through the constructor or one defined as a static final validator.
public interface AddressValidator {
static class AddressValidatorResult {
// some results, you might want to return some useful feedback (if not valid)
boolean isValid() {
throw new IllegalStateException("Method not implemented yet");
}
}
public static class AddressValidationException extends Exception {
private AddressValidationException(AddressValidatorResult result) {
// add some implementation
}
}
// don't throw ValidateException here, invalid addresses are normal for
// validators, even if they aren't for the application that uses them
AddressValidatorResult validateAddress(String address);
// don't throw ValidateException here, invalid addresses are normal for
// validators, even if they aren't for the application that uses them
}
public class DefaultAddressValidator implements AddressValidator {
public static class Params {
// some parameters for this specific validator
}
private final Params params;
public DefaultAddressValidator(Params params) {
// creates this validator
this.params = params;
}
#Override
public AddressValidatorResult validateAddress(String address) {
// perform your code here
// I don't like "return null" as it may lead to bugs
throw new IllegalStateException("Method not implemented yet");
}
}
// and use it like this
private void validateAddress(String address) throws AddressValidationException {
// e.g. field AddressValidator set in constructor
AddressValidatorResult result = addressValidator.validateAddress(address);
if (!result.isValid()) {
throw new AddressValidationException(result);
}
}
Should I make validation code as private helper methods or create a separate static helper class?
This totally depends on your context. It's impossible to say what should be the best design, without knowing what you are trying to realise.
After you edit: IMO, it is still not easy to tell you. If you only have to validate the address in one single point of your application (id: the setter method), I would validate it inside the setter method. If the input was invalid, I whould throw an IllegalArgumentException.
Does the validation code increase the size of the object?
However, the answer to your second question is No. To understand why, you have to know what Object Oriented Programming is.
Some references:
http://en.wikipedia.org/wiki/Object-oriented_programming
http://en.wikipedia.org/wiki/Class_(computer_science)
Should I make validation code as private helper methods or create a
separate static helper class?
It depends if you think that you'll need to reuse the same method also in another class for the same purpose(input validation) it is better write the method in a separate static helper class so you can reuse the method and maintain it easily.
If you write the same private helper method in several class each time that you need to make a changes you have to edit each method in each class, with a static helper class you change the code in one place only ...
Read about PropertyChangeListener and Bean Validation.
I tend to validate within the get() and set() methods wherever possible - calling external static methods for common tasks such as checking dates or cleaning input (i.e. to avoid sql injection)
If you only use (and are only ever going to use) the validation within one class, keep it as a private helper method. If in doubt, I tend to pull the functionality out into a static helper class. It makes very little difference to the amount of code, is no more effort to implement, and is much more flexible.
The short answer is: you should implement your validation code the way that your framework tells you to. Typically, this is a public method or an annotation. An interface could work too. If you add code, your class size will increase.
Data validation should be automatically called by your software's infrastructure. This helps to prevent programmers from forgetting to call the appropriate code. So, the methods should be public (an interface would work too).
Frameworks like Struts, Spring, Hibernate and have their own validation systems. Java EE leverages bean validation.
I recommend bean validation, because it performs validation regardless of the input source. When most people think of input validation, they think of data coming from the user e.g. HTTP Request, command console, Swing text field. Spring and Struts validation is often fine for those situations. But in long lived programs developed for enterprises, other data feeds often get introduced e.g. SQL database updates from another programs, database restoration after a crash, enterprise service bus, JMS.
That is why I prefer bean validation. The downside is that "safe sources" (data that you know is untainted) are validated unnecessarily. But with today's processing power, that should rarely be a significant concern.
Java EE Tutorial

Categories

Resources