Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* #%L
* JAXX :: Validator
* %%
* Copyright (C) 2008 - 2014 Code Lutin, Tony Chemit
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
package jaxx.runtime.validator.swing;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import jaxx.runtime.JAXXObject;
import jaxx.runtime.JAXXValidator;
import jaxx.runtime.SwingUtil;
import jaxx.runtime.validator.swing.meta.Validator;
import jaxx.runtime.validator.swing.meta.ValidatorField;
import jaxx.runtime.validator.swing.unified.UnifiedValidatorMessage;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.decorator.ColorHighlighter;
import org.nuiton.util.ReflectUtil;
import org.nuiton.validator.NuitonValidatorScope;
import org.nuiton.validator.bean.list.BeanListValidator;
import org.nuiton.validator.bean.simple.SimpleBeanValidatorMessage;
import org.nuiton.validator.bean.simple.SimpleBeanValidators;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import java.awt.Color;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import static org.nuiton.i18n.I18n.n;
/**
* The helper class for swing validation module.
*
* @author Tony Chemit - [email protected]
*/
public class SwingValidatorUtil extends SimpleBeanValidators {
/** Logger */
static private final Log log = LogFactory.getLog(SwingValidatorUtil.class);
protected static EnumMap icons;
protected static EnumMap colors;
public static EnumMap getIcons() {
if (icons == null) {
icons = new EnumMap(NuitonValidatorScope.class);
icons.put(NuitonValidatorScope.FATAL, SwingUtil.createImageIcon("fatal.png"));
icons.put(NuitonValidatorScope.ERROR, SwingUtil.createImageIcon("error.png"));
icons.put(NuitonValidatorScope.WARNING, SwingUtil.createImageIcon("warning.png"));
icons.put(NuitonValidatorScope.INFO, SwingUtil.createImageIcon("info.png"));
}
return icons;
}
public static EnumMap getColors() {
if (colors == null) {
colors = new EnumMap(NuitonValidatorScope.class);
colors.put(NuitonValidatorScope.FATAL, Color.MAGENTA);
colors.put(NuitonValidatorScope.ERROR, Color.RED);
colors.put(NuitonValidatorScope.WARNING, Color.YELLOW);
colors.put(NuitonValidatorScope.INFO, Color.GREEN);
}
return colors;
}
public static Color getColor(NuitonValidatorScope scope) {
return scope == null ? null : getColors().get(scope);
}
public static ImageIcon getIcon(NuitonValidatorScope scope) {
return scope == null ? null : getIcons().get(scope);
}
public static ImageIcon getFatalIcon() {
return getIcons().get(NuitonValidatorScope.FATAL);
}
public static ImageIcon getErrorIcon() {
return getIcons().get(NuitonValidatorScope.ERROR);
}
public static ImageIcon getWarningIcon() {
return getIcons().get(NuitonValidatorScope.WARNING);
}
public static ImageIcon getInfoIcon() {
return getIcons().get(NuitonValidatorScope.INFO);
}
protected SwingValidatorUtil() {
// no instance
}
public static SwingValidator newValidator(Class type,
String context) {
// if (BeanValidatorFactory.isDefaultCreator()) {
//
// // set the swing bean validator creator
// BeanValidatorFactory.setCreator(new DefaultSwingValidatorCreator());
// }
return SwingValidator.newValidator(type, context);
}
/**
* To install all the stuff for validation on a {@link JAXXValidator} ui.
*
* This method is called after validators has beeen detected in the ui (via
* the method {@link #detectValidators(JAXXValidator)})..
*
* It will first find and register all validator field via the method
* {@link JAXXValidator#registerValidatorFields()}, then for each
* validators it will install ui for it (says connect validator to ui via layers)
* and will reload attached bean to make visible bean validation state on ui.
*
* This method is always inovked by a generated jaxx-validator file at the
* end of the {@code $completeSetup} method.
*
* @param ui the validator ui to init.
*/
public static void installUI(JAXXValidator ui) {
// first install fields with validation
ui.registerValidatorFields();
// detectValidatorFields(ui);
// for each validator install uis + reload bean
List validatorIds = ui.getValidatorIds();
for (String validatorId : validatorIds) {
SwingValidator> validator = ui.getValidator(validatorId);
// install uis
validator.installUIs();
// reload attached bean (to see validation on uis)
validator.reloadBean();
}
}
/**
* Given a {@link JAXXValidator} ui, detects on it all the validators it
* contains.
*
* A validator is detected from the annotation {@link Validator} placed on
* his field.
*
* This method is always inovked by a generated jaxx-validator file at the
* end of the {@code $completeSetup} method.
*
* @param ui the ui where to seek for validators.
* @return the list of ids of validators found on the given ui
*/
public static List detectValidators(JAXXValidator ui) {
List validatorIds = new ArrayList();
Map validators = ReflectUtil.getFieldAnnotation(
ui.getClass(),
Validator.class,
true
);
for (Map.Entry entry : validators.entrySet()) {
Field field = entry.getKey();
Validator annotation = entry.getValue();
String validatorId = annotation.validatorId();
validatorIds.add(validatorId);
if (log.isInfoEnabled()) {
log.info("Detect validator [" + annotation.validatorId() +
"] on field " + field.getName());
}
}
return Collections.unmodifiableList(validatorIds);
}
/**
* Detects on a {@link JAXXValidator} ui all the validator fields it
* contains.
*
* A validator field is detected via the annotation placed on his field or
* his getter (in cas of inheritance).
*
* Each field found will be registred to his corresponding validator via
* the method {@link SwingValidator#setFieldRepresentation(String, JComponent)}.
*
* By default, this method is invoked in the generated method
* {@link JAXXValidator#registerValidatorFields()} by a generated
* jaxx-validator file.
*
* @param ui the ui to seek
*/
public static void detectValidatorFields(JAXXValidator ui) {
Multimap editors = getValidatorEditors(ui);
try {
for (String validatorId : ui.getValidatorIds()) {
SwingValidator> validator = ui.getValidator(validatorId);
for (Map.Entry entry :
editors.entries()) {
ValidatorField fieldAnnotation = entry.getValue();
JComponent editor = entry.getKey();
if (!validatorId.equals(fieldAnnotation.validatorId())) {
// not good validator, skip this field
continue;
}
String[] propertyNames = fieldAnnotation.propertyName();
for (String propertyName : propertyNames) {
if (log.isInfoEnabled()) {
log.info("Detects for validator [" + validatorId +
"] property " + propertyName +
" for editor " + fieldAnnotation.editorName());
}
validator.setFieldRepresentation(propertyName, editor);
}
}
}
} finally {
editors.clear();
}
}
/**
* Prepare the ui where to display the validators messages.
*
* @param errorTable the table where to display validators messages
* @param render renderer to use
*/
public static void installUI(JTable errorTable,
SwingValidatorMessageTableRenderer render) {
errorTable.setDefaultRenderer(Object.class, render);
errorTable.getRowSorter().setSortKeys(
Arrays.asList(new RowSorter.SortKey(0, SortOrder.ASCENDING)));
SwingUtil.setI18nTableHeaderRenderer(
errorTable,
n("validator.scope.header"),
n("validator.scope.header.tip"),
n("validator.field.header"),
n("validator.field.header.tip"),
n("validator.message.header"),
n("validator.message.header.tip"));
// register a single 'goto widget error' mouse listener on errorTable
registerErrorTableMouseListener(errorTable);
SwingUtil.fixTableColumnWidth(errorTable, 0, 25);
}
/**
* Prepare the ui where to display the validators messages.
*
* @param errorTable the table where to display simpleBean validators messages
* @param render renderer to use
* @since 2.6.23
*/
public static void installUI(JTable errorTable,
SimpleBeanValidatorMessageTableRenderer render) {
errorTable.setDefaultRenderer(Object.class, render);
errorTable.getRowSorter().setSortKeys(
Arrays.asList(new RowSorter.SortKey(0, SortOrder.ASCENDING)));
SwingUtil.setI18nTableHeaderRenderer(
errorTable,
n("validator.scope.header"),
n("validator.scope.header.tip"),
n("validator.field.header"),
n("validator.field.header.tip"),
n("validator.message.header"),
n("validator.message.header.tip"));
SwingUtil.fixTableColumnWidth(errorTable, 0, 25);
}
/**
* Prepare the ui where to display the validators messages.
*
* @param errorTable the table where to display validators messages
* @param render renderer to use
* @since 2.5.3
*/
public static void installUI(JTable errorTable,
SwingListValidatorMessageTableRenderer render) {
errorTable.setDefaultRenderer(Object.class, render);
errorTable.getRowSorter().setSortKeys(
Arrays.asList(new RowSorter.SortKey(0, SortOrder.ASCENDING)));
SwingUtil.setI18nTableHeaderRenderer(
errorTable,
n("validator.scope.header"),
n("validator.scope.header.tip"),
n("validator.bean.header"),
n("validator.bean.header.tip"),
n("validator.field.header"),
n("validator.field.header.tip"),
n("validator.message.header"),
n("validator.message.header.tip"));
SwingUtil.fixTableColumnWidth(errorTable, 0, 25);
}
/**
* Prepare the ui where to display the validators messages.
*
* @param errorTableModel
* @param errorTable the table where to display validators messages
* @since 2.5.3
*/
public static void registerListValidator(BeanListValidator validator,
SwingListValidatorMessageTableModel errorTableModel,
JTable dataTable,
JTable errorTable,
SwingListValidatorDataLocator dataLocator) {
// register the validator to the error table model
errorTableModel.registerValidator(validator);
// add click listener to go to cell
errorTable.addMouseListener(new SwingListValidatorMessageTableMouseListener(
dataTable,
dataLocator
));
// listen on editor model to add / remove bean into validator
dataTable.getModel().addTableModelListener(
new SwingListValidatorTableEditorModelListener(validator, dataLocator));
}
/**
* Add hightlighters on the editor of beans.
*
* @param validator the validator where to find bean states
* @param editor the editor of beans
* @param dataLocator the data locator
* @param scopes scopes to hightlight
* @param type of bean to validate
* @since 2.5.3
*/
public static void addHightLighterOnEditor(BeanListValidator validator,
JXTable editor,
SwingListValidatorDataLocator dataLocator,
NuitonValidatorScope... scopes) {
for (NuitonValidatorScope scope : scopes) {
SwingListValidatorHighlightPredicate predicate = SwingListValidatorHighlightPredicate.newPredicate(
scope,
validator, dataLocator
);
ColorHighlighter highlighter = new ColorHighlighter(predicate);
highlighter.setBackground(SwingValidatorUtil.getColor(scope));
editor.addHighlighter(highlighter);
}
}
/**
* Register for a given validator list ui a validator mouse listener.
*
* Note: there is only one listener registred for a given list model, so
* invoking this method tiwce or more will have no effect.
*
* @param list the validation ui list
* @return the listener instanciate or found
* @see SwingValidatorMessageListMouseListener
*/
public static SwingValidatorMessageListMouseListener registerErrorListMouseListener(JList list) {
SwingValidatorMessageListMouseListener listener =
getErrorListMouseListener(list);
if (listener != null) {
return listener;
}
listener = new SwingValidatorMessageListMouseListener();
if (log.isDebugEnabled()) {
log.debug(listener.toString());
}
list.addMouseListener(listener);
return listener;
}
/**
* Register for a given validator table ui a validator mouse listener
*
* Note: there is onlt one listener registred for a givne table model, so
* invokin this method twice or more will have no effect.
*
* @param table the validator table ui
* @return the listener instanciate or found
* @see SwingValidatorMessageTableMouseListener
*/
public static SwingValidatorMessageTableMouseListener registerErrorTableMouseListener(JTable table) {
SwingValidatorMessageTableMouseListener listener =
getErrorTableMouseListener(table);
if (listener != null) {
return listener;
}
listener = new SwingValidatorMessageTableMouseListener();
if (log.isDebugEnabled()) {
log.debug(listener.toString());
}
table.addMouseListener(listener);
return listener;
}
/**
* @param list the validator list ui
* @return the validator list mouse listener, or null if not
* found
* @see SwingValidatorMessageListMouseListener
*/
public static SwingValidatorMessageListMouseListener getErrorListMouseListener(JList list) {
if (list != null) {
for (MouseListener listener : list.getMouseListeners()) {
if (listener instanceof SwingValidatorMessageListMouseListener) {
return (SwingValidatorMessageListMouseListener) listener;
}
}
}
return null;
}
/**
* @param table the validator table ui
* @return the validator table mouse listener, or null if not
* found
* @see SwingValidatorMessageTableMouseListener
*/
public static SwingValidatorMessageTableMouseListener getErrorTableMouseListener(JTable table) {
if (table != null) {
for (MouseListener listener : table.getMouseListeners()) {
if (listener instanceof SwingValidatorMessageTableMouseListener) {
return (SwingValidatorMessageTableMouseListener) listener;
}
}
}
return null;
}
/**
* @param table the validator table ui
* @return the validator table mouse listener, or null if not
* found
* @see SwingValidatorMessageTableMouseListener
*/
public static SwingValidatorMessageTableMouseListener getListErrorTableMouseListener(JTable table) {
if (table != null) {
for (MouseListener listener : table.getMouseListeners()) {
if (listener instanceof SwingValidatorMessageTableMouseListener) {
return (SwingValidatorMessageTableMouseListener) listener;
}
}
}
return null;
}
public static String getMessage(SwingValidatorMessage model) {
String text = model.getMessage();
if (model.getField() != null) {
text = model.getI18nError(text);
}
return text;
}
public static String getMessage(SimpleBeanValidatorMessage model) {
String text = model.getMessage();
if (model.getField() != null) {
text = model.getI18nError(text);
}
return text;
}
public static String getMessage(SwingListValidatorMessage model) {
String text = model.getMessage();
if (model.getField() != null) {
text = model.getI18nError(text);
}
return text;
}
public static String getMessage(UnifiedValidatorMessage model) {
String text = model.getMessage();
if (model.getField() != null) {
text = model.getI18nError(text);
}
return text;
}
public static String getFieldName(SwingValidatorMessage model, String value) {
String text = null;
JComponent editor = model.getEditor();
if (editor != null) {
text = (String) editor.getClientProperty("validatorLabel");
/*if (l != null) {
text = I18n.t(l);
} else {
// TODO should try the text
}*/
}
if (text == null) {
text = value;
}
return text;
}
public static String getFieldName(SwingListValidatorMessage model, String value) {
String text = null;
JComponent editor = model.getEditor();
if (editor != null) {
text = (String) editor.getClientProperty("validatorLabel");
/*if (l != null) {
text = I18n.t(l);
} else {
// TODO should try the text
}*/
}
if (text == null) {
text = value;
}
return text;
}
public static String getFieldName(UnifiedValidatorMessage model, String value) {
return getFieldName(model, value, null);
}
public static String getFieldName(UnifiedValidatorMessage model, String value, String valueFallBack) {
String text = null;
JComponent editor = model.getEditor();
Object validatorLabel = null;
if (editor != null) {
validatorLabel = editor.getClientProperty("validatorLabel");
}
if (validatorLabel != null) {
if (model.isSimpleValidator()) {
text = (String) validatorLabel;
} else {
Map validatorLabelMap = (Map) validatorLabel;
String field = model.getField();
text = validatorLabelMap.get(field);
}
}
if (text == null && valueFallBack != null) {
text = valueFallBack;
}
if (text == null) {
text = value;
}
return text;
}
/**
* Method to listen the modification of the context name and at each time
* reload fields of the ui.
*
* @param validator validator to listen
* @param ui ui to refresh when context name has changed
* @since 2.2.1
*/
public static void listenValidatorContextNameAndRefreshFields(
SwingValidator> validator,
final JAXXValidator ui) {
PropertyChangeListener listener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
SwingValidator> validator = (SwingValidator>) evt.getSource();
if (log.isInfoEnabled()) {
log.info("Context name changed to [" + evt.getNewValue() +
"] for validator " + validator.getType());
}
ui.registerValidatorFields();
}
};
validator.addPropertyChangeListener(
SwingValidator.CONTEXT_PROPERTY,
listener
);
}
// /**
// * Default bean validator creator to use in the {@link BeanValidatorFactory}.
// *
// * @author Tony Chemit - [email protected]
// * @since 2.1
// */
// public static class DefaultSwingValidatorCreator implements BeanValidatorFactory.BeanValidatorCreator {
//
// @Override
// public BeanValidator newBeanValidator(NuitonValidatorProvider provider, Class type, String context, NuitonValidatorScope... scopes) {
// BeanValidator beanValidator = new SwingValidator(provider,
// type,
// context,
// scopes
// );
// return beanValidator;
// }
// }
/**
* Convinient method to attach a bean to all validators of an JAXXObject.
*
* It is possible to exclude some validator to be treated.
*
* @param ui the ui containing the validatros to treate
* @param bean the bean to attach in validators (can be null)
* @param excludeIds the list of validator id to exclude
*/
@SuppressWarnings({"unchecked"})
public static void setValidatorBean(JAXXObject ui,
Object bean,
String... excludeIds) {
if (!JAXXValidator.class.isAssignableFrom(ui.getClass())) {
return;
}
JAXXValidator jaxxValidator = (JAXXValidator) ui;
List validatorIds = jaxxValidator.getValidatorIds();
if (excludeIds.length > 0) {
validatorIds = new ArrayList(validatorIds);
for (String excludeId : excludeIds) {
validatorIds.remove(excludeId);
}
}
for (String validatorId : validatorIds) {
SwingValidator beanValidator =
jaxxValidator.getValidator(validatorId);
if (bean == null || beanValidator.getType().isAssignableFrom(
bean.getClass())) {
// touch validator, only if fits the bean type (or bean is null)
beanValidator.setBean(bean);
}
}
}
/**
* Convinient method to set the changed property to all validators of an
* JAXXObject.
*
* It is possible to exclude some validator to be treated.
*
* @param ui the ui containing the validatros to treate
* @param newValue the new value to set in changed validator property
* @param excludeIds the list of validator id to exclude
*/
@SuppressWarnings({"unchecked"})
public static void setValidatorChanged(JAXXObject ui,
boolean newValue,
String... excludeIds) {
if (!JAXXValidator.class.isAssignableFrom(ui.getClass())) {
return;
}
JAXXValidator jaxxValidator = (JAXXValidator) ui;
List validatorIds = jaxxValidator.getValidatorIds();
if (excludeIds.length > 0) {
validatorIds = new ArrayList(validatorIds);
for (String excludeId : excludeIds) {
validatorIds.remove(excludeId);
}
}
for (String validatorId : validatorIds) {
SwingValidator> beanValidator =
jaxxValidator.getValidator(validatorId);
beanValidator.setChanged(newValue);
}
}
protected static Multimap getValidatorEditors(JAXXValidator ui) {
Multimap editors = ArrayListMultimap.create();
Map validatorFields = null;
Map validatorMethods = null;
try {
validatorFields = ReflectUtil.getFieldAnnotation(
ui.getClass(),
ValidatorField.class,
true
);
validatorMethods = ReflectUtil.getMethodAnnotation(
ui.getClass(),
ValidatorField.class,
true
);
for (Map.Entry fieldEntry : validatorFields.entrySet()) {
Field field = fieldEntry.getKey();
field.setAccessible(true);
ValidatorField fieldAnnotation = fieldEntry.getValue();
JComponent editor = (JComponent) field.get(ui);
editors.put(editor, fieldAnnotation);
}
for (Map.Entry fieldEntry : validatorMethods.entrySet()) {
Method method = fieldEntry.getKey();
method.setAccessible(true);
ValidatorField fieldAnnotation = fieldEntry.getValue();
JComponent editor = (JComponent) method.invoke(ui);
editors.put(editor, fieldAnnotation);
}
} catch (Exception e) {
throw new IllegalStateException("Could not init validators on ui " + ui, e);
} finally {
if (validatorFields != null) {
validatorFields.clear();
}
if (validatorMethods != null) {
validatorMethods.clear();
}
}
return editors;
}
}