Reputation: 5217
Is it somehow possible to annotate a Java Method in that way that i later can give another Method a Field Identifier or something like that, so that this Method can call the right one?
I know that normally you would do this with interfaces, but in my case this would be a immense count of interfaces... I need to use this in Entity Classes for my Database (and i'm not allowed to use a ORM Mapper)
For example: I have the Entity
public class Account{
private String username;
private String password;
private String name;
private String mail;
public void setUserName(String username){
this.username = username;
}
public String getUserName(){
return username;
}
[all other getter/Setter...]
}
Now i want to tell a Method that it need to validate a Field, for example the username
field.
The Method that does should look like this:
public void validateField(XXX Field, Entity entity) throws ValidationFailedException, EmptyFieldException;
where XXX
is somehow the FieldIdentifier.
Is that in any way possible in Java?
My only guess it that i Use public static final ìnt
stuff in there to give every field a Method or so...
Upvotes: 1
Views: 123
Reputation: 10216
What do you use? I don't see any annotations from which I can guess your framework. If you use Hibernate, you can use something like @NotNull or something else, or even do your custom validation: This is how you would go with your example:
public class Account{
@NotNull(message="This field should not be null")
private String username;
@NotBlank(message="This string should not be empty or null")
private String password;
private String name;
private String mail;
public void setUserName(String username){
this.username = username;
}
public String getUserName(){
return username;
}
[all other getter/Setter...]
}
http://silentwalker.wordpress.com/2009/04/07/custom-validation-in-hibernate/
You can also create your own annotations without using any framework and use them @prepersist or whatever. Basically the sky is the limit.
P.S Since you don't want to use any non internal code, here is how you can approach:
First, you can define an annotation
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface NotNull{
public String message() default "";
}
Then, before persisting the class, you would inspect its fields:
So, you have something like this:
Field[] classFields = yourObjectPrePersist.getClass().getDeclaredFields();
for (int i = 0; i < classFields.length; i++) {
classFields[i].setAccessible(true);//take notice that if you use a SecurityManager, you should work around it
if (classFields[i].getAnnotation(NotNull.class) != null) {
Object value = classFields[i].get(yourObjectPrePersist);
//here check if value is null or not and then return the message
if (value == null) {
throw new SomeException(((NotNull) classFields[i].getAnnotation(NotNull.class)).message());
}
}
}
Upvotes: 3
Reputation: 21
You could use a generic interface
public interface Field { public String getValue(); }and call your validate method with anonymouse classes
validator.validate(new Field() { return account.getUsername() });(or with old java)
validator.validate(new Field() { public String getValue() { return account.getUsername(); } });
Otherwise what about using java.lang.Methode
directly?
P.S.: Sorry for the quote, stackoverflow did not let me post my text directly, said it was not formatted correctly :-/
Upvotes: 0
Reputation: 183280
You can use reflection for this; see the documentation for java.lang.reflect.Field
. The caller can pass in the field-name as a string, and validateField
can use something like Field f = entity.getClass().getField(fieldName)
.
But this is not usually a great idea . . . reflection is awesome, but it requires a lot of boilerplate code, and you pay a high price in maintainability. (You also pay a performance penalty, though in my experience the maintainability penalty is much worse than the performance penalty.) Personally I use reflection a lot in test code (it can help in writing extremely comprehensive tests), and I make use of frameworks like Spring and Hibernate that depend on reflection, but I avoid it in my own production code.
Upvotes: 0
Reputation: 2115
Annotations don't seem like the right solution to the problem you describe.
One possibility would be to pass in the name of the field that needs to be validated, then used the java.beans.BeanInfo
class to access the field values of the Entity. This will allow you to access arbitrary attributes of an object without having to deal with all of the complexity of reflection.
Upvotes: 0