Define own feedback messages in Wicket - wicket

How do I define my own feedback messages in Wicket?
For example: if I give an incorrect username, I want to get an error message like "The user name in incorrect, try to login again." instead of using the default error message.
What would an example be like?

You can display your own error messages using error() and warn() and info(). If you want to show errors dependent on validators or the required flag you can define a properties file with the same name as the class which contains a mapping of field -> message. For example:
Index.java
Form form = new Form("myform");
form.add(new TextField("name").setRequired(true));
form.add(new PasswordTextField("password").setRequired(true));
form.add(new TextField("phonenumber").setRequired(true));
Index.properties
Required=Provide a ${label} or else...
All required fields
myform.name.Required=You have to provide a name
The field name in the form myform when it is required.
password.Required=You have to provide a password
Any field with the name password when it is required.
phonenumber.Required=A telephone number is obligatory.
Any field with the name phonenumber when it is required.
This shows a variety of ways of setting a feedback message for specific components.
You can also put the properties files next to the following component level (in order of importance, top highest):
Page Class
Component Class
Your Application Class
Wickets Application Class
Hope that helps

#user1090145: I've used overloaded Component's error() method in Validator's class:
private void error(IValidatable<String> validatable, String errorKey) {
ValidationError error = new ValidationError();
error.addMessageKey(errorKey);
validatable.error(error);
}
and invoked it in validate() by
error(validatable, "your-form.field.text-id");
Properties your-form.field.text-id must be defined in YourPage.properties
Sources:
Create custom validator in Wicket and
Form validation messages

you should set Feed back message to Session
message = "message";
Session.get().getFeedbackMessages().success(null, message);

You can use an anonymous IValidationError class and the messageSource.getMessage method to get a custom message from your property file:
error(new IValidationError() {
#Override
public Serializable getErrorMessage(IErrorMessageSource messageSource) {
//create a list of the arguments that you will use in your message string
Map<String, Object> vars = new HashMap<String, Object>();
vars.put("invalidUsername", getInvalidUsernameInput());
//get the message string from the property file
return messageSource.getMessage("mysettings.invalid_username", vars);
}
});
Sample property file:
mysettings.invalid_username=The user name "${invalidUsername}" is incorrect.

Related

How to add Realm name in custom email template Subject

I have created a custom Theme for Keycloak email.
I know how to add the realm name in email body, but I didn't find how to add the realm name in the subject.
Is there any possibility to add this without the need of a custom Provider ?
Thank's !
Had the same question.
So did some research(went through code), and find out that as of writing this answer, the default Freemarker-based Email Implementation doesn't even supply the subject attributes(call them variables or arguments), and the final subject string formatting is done based on an empty list of attributes.
https://github.com/keycloak/keycloak/blob/bfce612641a70e106b20b136431f0e4046b5c37f/services/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailTemplateProvider.java#L162
#Override
public void sendExecuteActions(String link, long expirationInMinutes) throws EmailException {
Map<String, Object> attributes = new HashMap<>(this.attributes);
attributes.put("user", new ProfileBean(user));
addLinkInfoIntoAttributes(link, expirationInMinutes, attributes);
attributes.put("realmName", getRealmName());
send("executeActionsSubject", "executeActions.ftl", attributes);
}
Which in return calls
#Override
public void send(String subjectFormatKey, String bodyTemplate, Map<String, Object> bodyAttributes) throws EmailException {
send(subjectFormatKey, Collections.emptyList(), bodyTemplate, bodyAttributes);
}
Finally, this function gets executed
protected EmailTemplate processTemplate(String subjectKey, List<Object> subjectAttributes, String template, Map<String, Object> attributes) throws EmailException {
try {
........
String subject = new MessageFormat(rb.getProperty(subjectKey, subjectKey), locale).format(subjectAttributes.toArray());
........
Throughout the code trail for executeAction I nowhere found any logic which allows adding dynamic-values/variables in the subject line.
To solve this I am raising an issue. I will link it once done.
Update 1
Issue opened: https://github.com/keycloak/keycloak/issues/11883
Update 2
PR raised: https://github.com/keycloak/keycloak/pull/11885

Getting method name related to a rest service

I wanted to know if there exist a way of retrieving the actual method name associated to a rest service provided. Lets suppose my url is http://localhost:8080/v1/mytesturl now i want to retrieve the actual method name that is associated with this url.
Actually we are maintaining some key/value pair specific to the method that we have created and i need to make some checks based on the method name that gets executed using these values.
Plz let me know if there exist some way to do that..
Simply get the method name from the Object class.
#RestController
#RequestMapping("")
public class HomeController {
#RequestMapping("/mytesturl")
#ResponseBody
public String getMethodName() {
return new Object(){}.getClass().getEnclosingMethod().getName();
}
}
i got the solution by using this
Map<RequestMappingInfo, HandlerMethod> handlerMethods = RequestMappingHandlerMapping.getHandlerMethods();
HandlerExecutionChain handler = RequestMappingHandlerMapping.getHandler(requestr);
HandlerMethod handler1 = null;
if(Objects.nonNull(handler)){
handler1 = (HandlerMethod) handler.getHandler();
handler1.getMethod().getName()
}
this provide me with what i wanted..

Wicket: How to add substring to every error message?

We are using wicket 6.
Both Session and Component classes have error() method to display an error. However in both cases these methods are final.
Is there any other universal way to add postfix to any error message? (we are looking to add error id)
Edit:
We have hundreds of files of code which already uses error() method from both Session and Component, so massive refactoring is not an option.
You can add arbitrary message objects to a Wicket component:
component.error(new ErrorCode(code));
With a custom FeedbackPanel you can then display the error code as needed:
protected Component newMessageDisplayComponent(String id, FeedbackMessage message)
{
Serializable rawMessage = message.getMessage();
if (rawMessage instanceof ErrorCode) {
// create custom component to display a text and/or code
...
} else {
return super.newMessageDisplayComponent(id, message);
}
}

Parse HL7 v2.3 REF message with local customizations in HAPI

I am trying parse a HL7 REF I12 message with local customization(NZ).
When I tried using the GenericParser, I keep getting Validation exceptions.
For example for the segment below, I keep get the output
ca.uhn.hl7v2.validation.ValidationException: Validation failed:
Primitive value '(08)569-7555' requires to be empty or a US phone
number
PRD|PP|See T Tan^""^""^^""|""^^^^""^New Zealand||(08)569-7555||14134^NZMC
My question is:
Is there a way to avoid the validation by using the conformance class
generator
Is it possible to create own validation classes using
CustomModelClasses?
In either case, is there any example code for that or tutorial example documentation?
If disabling validation altogether is an option for your application, then you can set the validation context to use NoValidation.
See this thread in the hapi developers mailing list: http://sourceforge.net/p/hl7api/mailman/message/31244500/
Here is an example of how to disable validation:
HapiContext context = new DefaultHapiContext();
context.setValidationContext(new NoValidation());
GenericParser parser = context.getGenericParser();
String message = ...
try {
parser.parse(message);
} catch (Exception e) {
e.printStackTrace();
}
If you still require validation, but just want to change the validator for specific rules, then you'll have to create your own implementation of ValidationContext. This would be done by sub classing ca.uhn.hl7v2.validation.builder.support.NoValidationBuilder and overriding the configure method and use this to instantiate an instance of ValidationContextImpl.
For an example of how to implement the configure method in your subclass of NoValidationBuilder, see the source code for ca.uhn.hl7v2.validation.builder.support.DefaultValidationBuilder. This is the default validation context that is generating the error message you're seeing. To make it easier for you, I'm including the class listing here:
public class DefaultValidationBuilder extends DefaultValidationWithoutTNBuilder {
#Override
protected void configure() {
super.configure();
forAllVersions()
.primitive("TN")
.refersToSection("Version 2.4 Section 2.9.45")
.is(emptyOr(usPhoneNumber()));
}
}
Notice this is the implementation of the usPhoneNumber method defined in BuilderSupport:
public Predicate usPhoneNumber() {
return matches("(\\d{1,2} )?(\\(\\d{3}\\))?\\d{3}-\\d{4}(X\\d{1,5})?(B\\d{1,5})?(C.*)?",
"a US phone number");
}

How to change ErrorMessage property of the DataAnnotation validation in MVC2.0

My task is to change the ErrorMessage property of the DataAnnotation validation attribute in MVC2.0. For example I should be able to pass an ID instead of the actual error message for the Model property and use that ID to retrieve some content(error message) from a another service e.g database, and display that error message in the View instead of the ID. In order to do this I need to set the DataAnnotation validation attribute’s ErrorMessage property.
[StringLength(2, ErrorMessage = "EmailContentID.")]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
It seems like an easy task by just overriding the DataAnnotationsModelValidatorProvider ‘s
protected override IEnumerable GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable attributes)
However it seems to be a complicated enough.
a. MVC DatannotationsModelValidator’s ErrorMessage property is read only. So I cannot set anything here
b. System.ComponentModel.DataAnnotationErrorMessage property(get and set) which is already set in MVC DatannotationsModelValidator so we cannot set again. If you try to set you get “The property cannot set more than once…” error message appears.
public class CustomDataAnnotationProvider : DataAnnotationsModelValidatorProvider
{
protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
{
IEnumerable<ModelValidator> validators = base.GetValidators(metadata, context, attributes);
foreach (ValidationAttribute validator in validators.OfType<ValidationAttribute>())
{
messageId = validator.ErrorMessage;
validator.ErrorMessage = "Error string from DB And" + messageId ;
}
//......
}
}
Can anyone please help me on this?
Here is the question: What is your motivation to changing the error message property?
Think this through very carefully, as you are heading down a path where you are obfuscating what is actually happening in the application. Certainly the database informatino is useful, but it is not really part of the validation, nor should it be.
When you head in this direction, you are essentially saying that the validation can only be invalid if there is a database problem. I see two issues with this:
It breaks the separation of concerns. You are reporting a persistance error in the model, which is not where it occurred.
The solution is not unit testable, as you must engage the database.
I don't like either of the two above.
Can you solve this? Possibly if you will create your own custom validation attribute. I would have to check and ensure that is correct. Another option is to aim for custom validation:
http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx
This article can also help you head in the direction you desire:
http://ryanrivest.com/blog/archive/2010/01/15/reusable-validation-error-message-resource-strings-for-dataannotations.aspx
Do you want to solve this? Not really if you are attempting to keep a proper separation of concerns in your application. I would not polute my validation error message (this is not valid) with a database error (I am not valid, but the database also blew up). Just my two cents.
There are built in ways to get the error message via a resource. Instead of a database lookup to get a resource at runtime, generate resources from your database and use that for your error messages.
You can then use the ErrorMessageResourceName and ErrorMessageResourceType to allow the DataAnnotation to perform a resource lookup instead of hard-coding a specific string.
public sealed class MyModel
{
[Required(
ErrorMessageResourceName="MyDescriptionResource",
ErrorMessageResourceType=typeof(MyCustomResource))]
public string Description { get; set; }
}
Also you may want to have a look at ValidationAttribute.FormatErrorMessage Method on msdn.
This method formats an error message
by using the ErrorMessageString
property. This method appends the name
of the data field that triggered the
error to the formatted error message.
You can customize how the error
message is formatted by creating a
derived class that overrides this
method.
A quick sample (and not meant to be a definitive example)
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false,
Inherited = true)]
public sealed class PostCodeValidationAttribute
: ValidationAttribute
{
public override bool IsValid(object value)
{
if( value == null )
return true;
string postCode = value as string;
if( string.IsNullOrEmpty(postCode) )
return true;
if ( !PostCode.IsValidPostCode(postCode, this.PostCodeStyle) )
return false;
return true;
}
public PostCodeStyle PostCodeStyle { get; set; }
public override string FormatErrorMessage(string name)
{
return string.Format(
"{0} is not a valid postcode for {1}", name, PostCodeStyle);
}
}
* I've omitted the PostCodeStyle enumeration as well as the PostCode class for validating a postcode.