generics with interfaces and validators - java

I have:
Generic interface with method isValid (T obj).
Driver class with parameters such as age, experience, license etc. VaLidator for
Driver Class which checks if Driver is Valid.
So I need a validator for the Driver class.
public class Driver <T>{
private String name;
private String surname;
private String secondname;
private int dateofbirth;
private T pass;
private T dateofissue;
public int getDateofbirth() {
return dateofbirth;
}
public T getPass() {
return pass;
}
public T getDateofissue() {
return dateofissue;
}
}
public interface Validator <T> {
boolean isValid (T obj);
}
class DriverValidator<T> implements Validator {
I do not know how I should do it. For any explanation will be very grateful

As mentioned in comments above it's not easy to help in this case, because the kind of validation is not known, also it's a little bit odd when seeing generic type is used 2 times by different getters. Also the dateOfBirth variable should be a long, a Date or a LocalDate.
But anyway, here is an example of an implementation of a validator to explain the technical concept (of course you have to add more checks, but the idea should be clear) :
public class DriverValidator<T> implements Validator<Driver<T>> {
#Override
public boolean isValid(Driver<T> driver) {
if (driver==null) {
return false;
}
if (driver.getPass() == null) {
/* e.g. when this field may not be null...*/
return false;
}
// ... do more checks - e.g. check old enough etc.
return true;
}
}

Related

Is it bad practice to return Enums in Java?

Lets say I have a class to model an item in a game like so:
public class Item {
private final EnumItem type;
public Item(EnumItem type) {
this.type = type;
}
public Item(String name) {
this.type = EnumItem.fromName(name);
}
}
public enum EnumItem {
MACHINE_GUN("machine_gun"),
SWORD("sword"),
BAT("bat"),
DEFAULT("default");
private final String name;
public EnumItem(name) {
this.name = name;
}
public String getName() { return name; }
public static EnumItem fromName(String name) {
for(EnumItem i: EnumItem.values()) {
if(i.name.equals(name)) {
return i;
} else {
return EnumItem.DEFAULT;
}
}
}
}
Assume that .equals() and .hashCode() of Item are overridden correctly to compare the internal Enum.
Now I want a way to distinguish these items with a getter in Item: should I return an Enum or the String name? Is it good practice to return an Enum in general? Or is there a better way to distinguish these Items? Because returning the enum kind of looks like exposing the rep to me and I don't want my colleagues to use EnumItem directly to compare Items.
The approaches I thought of are the following:
string getName() to do something like item1.getName().equals("machine_gun");
EnumItem getEnum() to do item1.getEnum().equals(EnumItem.MACHINE_GUN);
item1.equals(new Item("machine_gun"));
static name(String name) { new Item(name) } to do item1.equals(Item.name("machine_gun"));
I don't know what should I do, I'd appreciate some insight from experienced programmers.
I know they look like they would from context, but in my use case these items have no special functionality that would justify extending from the base Item class.
Is this good practice? Sure, you're using aggregation since Item doesn't depend on EnumItem, which is fine. That being said, could it be done better? Sure. Is the alternative I provide the only solution? No.
Alternative
If you want this to be extensible, consider using an interface to represent an item. Then allow the interface to extend this interface to provide some standard types. Alternatively you could use composition or aggregation to define a type inside EnumItem that implements the Item interface to ensure that equals/hashcode for the Item are always override and adhere to some contract.
interface Item {
String key();
}
enum EnumItem implement Item {
private final String key;
EnumItem(String key) {
this.key = key;
}
#Override
public String key() {
return key;
}
}
class AbstractItem implements Item {
// constructor, override name()
}
Item item = EnumItem.FOO_BAR;
Item item2 = new AbstractItem("FooBar");
Item item3 = () -> "FooBar";

Custom Scalar Type in graphql-spqr

I graphql-spqr, java.util.Date is defined as Scalar. Is it possible to overwrite the serialization/deserialization of java.util.Date to get a different String representation of the date?
The ScalarStrategy mentioned in this answer was removed with the latest release.
public class Order {
private String id;
private Date orderDate; //GraphQLScalarType "Date"
public Order() {
}
public Order(String id, String bookId, Date orderDate) {
this.id = id;
this.orderDate = orderDate;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Date getOrderDate() {
return orderDate;
}
public void setOrderDate(Date orderDate) {
this.orderDate = orderDate;
}
}
GraphQL Response:
{
"data": {
"createOrder": {
"id": "74e4816c-f850-4d63-9855-e4601fa125f4",
"orderDate": "2019-05-26T08:25:01.349Z", // --> 2019-05-26
}
}
}
ScalarStrategy isn't the proper way to achieve what you want. When you want to change how a Java type gets mapped to GraphQL, you normally provide a new (or customize an existing) TypeMapper.
Take a look at the existing Date scalar implementation and implement your own in a similar way. Then implement a custom TypeMapper that simply always returns a static instance of that scalar from both toGraphQLType and toGraphQLInputType methods.
public class CustomTypeMapper implements TypeMapper {
private static final GraphQLScalarType GraphQLCustomDate = ...;
#Override
public GraphQLOutputType toGraphQLType(...) {
return GraphQLCustomDate;
}
#Override
public GraphQLInputType toGraphQLInputType(...) {
return GraphQLCustomDate;
}
#Override
public boolean supports(AnnotatedType type) {
return type.getType() == Date.class; // This mapper only deals with Date
}
}
To register it, call generator.withTypeMappers(new CustomTypeMapper().
That said, since you're only trying to cut off the time part, you'd ideally use LocalDate here. You can make SPQR do that transparently by registering a TypeAdapter (which is nothing but a mapper + converter) but a simple mapper as explained above is a more efficient solution in your case. If you still decide to go the adapter way, you can inherit AbstractTypeAdapter<Date, LocalDate> and implement the conversion logic (should be trivial). Register via generator.withTypeAdapters or by registering it as a mapper and converters separately.

Field validation from options on condition from other field javax.validation

I need to perform a field validation (it can be one of values) if another field is present.
import javax.validation.*;
class Person {
#NotBlank
private String name;
private Long groupId;
#Valid // if group id is not null, select one from available.
private String specialization;
// getters, setters.
}
class PersonValidaionLogic {
#Autowired
private SpecializationService specializationService;
public void validatePerson(final Person person) {
Long groupId = person.getGroupId();
if (groupId != null) {
Set<String> availableSpecializations = specializationService.getByGroupId(groupId);
if (!availableSpecializations.contains(specialization)) {
addValidationError("specialization is not valid");
}
}
}
}
There is a nice answer on how to validate multiple fields in a class with conditions on each other.
How do I pass specializationService and groupId to the validator.
Feel free to share your solution or ideas! This is how I solved this problem.
I used the idea from the link in my question, but in much easier way.
First, I solved a problem how to pass a Spring component or service into validator. I used a component which holds a static reference to the service.
Second, I validated the whole object as described in the link.
Here is the code!
1) Create annotation #PersonConstraint and put in on Person class.
This may help https://www.baeldung.com/javax-validation-method-constraints
#Target({ TYPE })
#Retention(RUNTIME)
#Constraint(validatedBy = PersonValidator.class)
public #interface PersonConstraint {
String message() default "Specialization is not valid";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
CaseMode value();
}
2) Component which holds static reference to the service.
#Component // Spring component.
class ServiceHolderComponent {
private static SpecializationService SPECIALIZATION_SERVICE;
#Autowired
public ServiceHolderComponent(final SpecializationService specializationService) {
GROUP_SERVICE = Validate.notNull(groupService); //apache lib
}
public static SpecializationService getSpecializationService() {
return SPECIALIZATION_SERVICE;
}
}
3) And person validator
public class PersonValidator implements ConstraintValidator<PersonConstraint, Person> {
private final SpecializationService specializationService;
public UserDynamicEnumValidator() {
this(ServiceHolderComponent.getSpecializationService());
}
public UserDynamicEnumValidator(final SpecializationService specializationService) {
this.specializationService = specializationService;
}
#Override
public boolean isValid(final Person person, final ConstraintValidatorContext context) {
final Long groupId = person.getGroupId();
if (groupId == null) {
return true; // We consider it valid.
}
final String specialization = person.getSpecializat();
if (StringUtils.isEmpty(specialization)) {
return true; // We consider it valid.
}
// I changed the code of the service, so it returns a set of strings - projection query and collectors to set.
final Set<String> availableSpecializationValuesByGroup = specializationService.findByValue(groupId);
if (!availableSpecializationValuesByGroup.contains(specialization)) {
// To display custom message
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate("Specialization is not valid").addConstraintViolation();
return false;
}
return true;
}
}
To display a custom message in validator check this

get() methods in Java enum type

I have an enum type (say for arguments sake CarModel), used throughout an application (numerous classes).
public enum CarModel {
DIABLO,
P911,
DB7;
}
I have various methods that use this CarModel enum type in different ways, and each has a switch statement to set some String variable depending on the enum type, before going on to do other stuff. (e.g. set the Manufacturer of some model, or set the country of origin etc. These results are static at runtime)
The issue is, if I want to add a new model to the enum, I'd need to go to each method, and extend/modify the switch statement to handle its existence. This could easily lead to human error, and/or code duplication (if various methods use the same switch statements).
Rather than using switch statements all-over, I would like to have static methods, that could be edited in a single location, and would allow for behaviour similar to the following:
String country = CarModel.DIABLO.getCountry() // returns Italy
String manufacturer = CarModel.P911.getManufacturer() // returns Porsche
Is this possible with an enum, (and is an enum even the 'correct' way to do this?
You can do something like this.
public enum CarModel {
DIABLO("Lamborghini", "Italy"),
P911("Porsche", "Germany");
private String manufacturer;
private String country;
private CarModel(String manufacturer, String country) {
this.manufacturer = manufacturer;
this.country = country;
}
public String getManufacturer() {
return manufacturer;
}
public String getCountry() {
return country;
}
}
Yes, absolutely. Enums can have their own methods, and those methods can be value-specific. It looks like this:
enum CarModel {
P911 {
public String getManufacturer() { return "Porsche"; }
},
DB7 {
public String getManufacturer() { return "Aston Martin"; }
},
...
public abstract String getManufacturer();
}
You can add more methods, of course.
If you're going to use enums, I would suggest an abstract method declared in the enum, and then a provided implementation for each enum instance.
That way you don't have switch statements everywhere (from which you can easily omit cases) and you have a more reliable and OO-styled polymorphic approach.
abstract public int getEngineSize();
DIABLO {
public int getEngineSize() {
return 6.3; // whatever it really is...
}
}
See here for more examples/discussions etc.
I would suggest adding this information directly into your enum.
Like this:
public enum CarModel {
DIABLO("Lambo"),
P911 ("Porsche");
private String manufacturer;
private CarModel(String manufacturer) {
this.manufacturer = manufacturer;
}
public String getManufacturer() {
return manufacturer;
}
}
and in the class you'd only have to use the getManufacturer method
Moreover enums can implement an interface. You can add some get() methods like getMaxSpeed() or getWeight().
Interface can look like
interface car{
public int getMaxSpeed();
public int getWeight();
}
Yes, this is quite easy to do:
public enum CarModel {
DIABLO("rod"),
P911("jane"),
DB7("freddy");
private String name;
CarModel(String name){
this.name = name;
}
public String getName() {
return name;
}
}
Haha, I recommend you to use "Factory" Design Pattern.
you can make a CarFactory(), to produce new model car.
http://en.wikipedia.org/wiki/Factory_method_pattern

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