org.apache.wicket.validation.ValidationError.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.wicket.validation.ValidationError.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.wicket.validation;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.wicket.markup.html.form.ValidationErrorFeedback;
import org.apache.wicket.util.lang.Args;
import org.apache.wicket.util.lang.Classes;
import org.apache.wicket.util.string.Strings;

/**
 * A versatile implementation of {@link IValidationError} that supports message resolution from
 * {@link IErrorMessageSource}, default message (if none of the keys matched), and variable
 * substitution.
 * 
 * The final error message is constructed via the following process:
 * <ol>
 * <li>Try all keys added by calls to {@link #addKey(String)} via the provided
 * <code>IErrorMessageSource</code>.</li>
 * <li>If none of the keys yielded a message, use the message set by {@link #setMessage(String)}, if
 * any.</li>
 * <li>Perform variable substitution on the message, if any.</li>
 * </ol>
 * 
 * @author Igor Vaynberg (ivaynberg)
 * @since 1.2.6
 */
public final class ValidationError implements IValidationError {
    private static final long serialVersionUID = 1L;

    /** list of message keys to try against the <code>IErrorMessageSource</code> */
    private List<String> keys;

    /** variables map to use in variable substitution */
    private Map<String, Object> vars;

    /** default message used when all keys yield no message */
    private String message;

    /**
     * Constructs an empty error
     */
    public ValidationError() {

    }

    /**
     * Constructs a validation error with the validator's standard key. Equivalent to calling
     * {@link #addKey(IValidator)}
     * 
     * @param validator
     *            validator
     */
    public ValidationError(IValidator<?> validator) {
        addKey(validator);
    }

    /**
     * Constructs a validation error with a variation of validator's standard key. Equivalent to
     * calling {@link #addKey(IValidator, String)}
     * 
     * @param validator
     *            validator
     * @param variation
     *            key variation
     * 
     * 
     */
    public ValidationError(IValidator<?> validator, String variation) {
        addKey(validator, variation);
    }

    /**
     * Constructs a validation error with the specified message. Equivalent to calling
     * {@link #setMessage(String)}
     * 
     * @param message
     *            message
     */
    public ValidationError(String message) {
        setMessage(message);
    }

    /**
     * Adds a key to the list of keys that will be tried against <code>IErrorMessageSource</code> to
     * locate the error message string.
     * 
     * @param key
     *            a message key to be added
     * @return this <code>ValidationError</code> for chaining purposes
     */
    public ValidationError addKey(String key) {
        Args.notEmpty(key, "key");

        if (keys == null) {
            keys = new ArrayList<>(1);
        }
        keys.add(key);
        return this;
    }

    /**
     * Shortcut for adding a standard message key which is the simple name of the validator' class
     * 
     * @param validator
     *            validator
     * @return {@code this}
     */
    public ValidationError addKey(IValidator<?> validator) {
        Args.notNull(validator, "validator");
        addKey(Classes.simpleName(validator.getClass()));
        return this;
    }

    /**
     * Shortcut for adding a standard message key variation which is the simple name of the
     * validator class followed by a dot and the {@literal variation}
     * <p>
     * If the variation is empty only the validator's simple class name is used
     * </p>
     * 
     * @param validator
     *            validator
     * @param variation
     *            key variation
     * @return {@code this}
     */
    public ValidationError addKey(IValidator<?> validator, String variation) {
        Args.notNull(validator, "validator");
        String key = Classes.simpleName(validator.getClass());
        if (!Strings.isEmpty(variation)) {
            key = key + "." + variation.trim();
        }
        addKey(key);
        return this;
    }

    /**
     * Sets a key and value in the variables map for use in substitution.
     * 
     * @param name
     *            a variable name
     * @param value
     *            a variable value
     * @return this <code>ValidationError</code> for chaining purposes
     */
    public ValidationError setVariable(String name, Object value) {
        Args.notEmpty(name, "name");

        getVariables().put(name, value);

        return this;
    }

    /**
     * Retrieves the variables map for this error. The caller is free to modify the contents.
     * 
     * @return a <code>Map</code> of variables for this error
     */
    public final Map<String, Object> getVariables() {
        if (vars == null) {
            vars = new HashMap<>(2);
        }
        return vars;
    }

    /**
     * Sets the variables map for this error.
     * 
     * @param vars
     *            a variables map
     * @return this <code>ValidationError</code> for chaining purposes
     */
    public final ValidationError setVariables(Map<String, Object> vars) {
        Args.notNull(vars, "vars");

        this.vars = vars;
        return this;
    }

    /**
     * @see IValidationError#getErrorMessage(IErrorMessageSource)
     */
    @Override
    public final Serializable getErrorMessage(IErrorMessageSource messageSource) {
        String errorMessage = null;

        if (keys != null) {
            // try any message keys ...
            for (String key : keys) {
                errorMessage = messageSource.getMessage(key, vars);
                if (errorMessage != null) {
                    break;
                }
            }
        }

        // ... if no keys matched try the default
        if (errorMessage == null && message != null) {
            errorMessage = message;
        }

        return new ValidationErrorFeedback(this, errorMessage);
    }

    /**
     * Gets the default message that will be used when no message could be located via message keys.
     * 
     * @return message the default message used when all keys yield no message
     */
    public final String getMessage() {
        return message;
    }

    /**
     * Sets message that will be used when no message could be located via message keys.
     * <p>
     * Note: No variable substitution is performed on the given message!
     * 
     * @param message
     *            a default message to be used when all keys yield no message
     * 
     * @return this <code>ValidationError</code> for chaining purposes
     */
    public final ValidationError setMessage(String message) {
        Args.notNull(message, "message");

        this.message = message;
        return this;
    }

    /**
     * Gets error keys
     * 
     * @return keys
     */
    public List<String> getKeys() {
        if (keys == null) {
            keys = new ArrayList<>();
        }
        return keys;
    }

    /**
     * Sets error keys
     * 
     * @param keys
     */
    public void setKeys(List<String> keys) {
        this.keys = keys;
    }

    /**
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        StringBuilder tostring = new StringBuilder();
        tostring.append('[').append(Classes.simpleName(getClass()));

        tostring.append(" message=[").append(message);

        tostring.append("], keys=[");
        if (keys != null) {
            Iterator<String> i = keys.iterator();
            while (i.hasNext()) {
                tostring.append(i.next());
                if (i.hasNext()) {
                    tostring.append(", ");
                }
            }
        } else {
            tostring.append("null");
        }
        tostring.append("], variables=[");

        if (vars != null) {
            Iterator<Entry<String, Object>> i = vars.entrySet().iterator();
            while (i.hasNext()) {
                final Entry<String, Object> e = i.next();
                tostring.append('[').append(e.getKey()).append('=').append(e.getValue()).append(']');
                if (i.hasNext()) {
                    tostring.append(',');
                }
            }
        } else {
            tostring.append("null");
        }
        tostring.append(']');

        tostring.append(']');

        return tostring.toString();
    }

}