r2011 - in trunk/nuiton-validator/src/main: java/org/nuiton/validator java/org/nuiton/validator/xwork2 resources resources/META-INF resources/META-INF/services
Author: tchemit Date: 2011-01-17 19:00:50 +0100 (Mon, 17 Jan 2011) New Revision: 2011 Url: http://nuiton.org/repositories/revision/nuiton-utils/2011 Log: new validation api Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/AbstractNuitonValidatorProvider.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidator.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorFactory.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorModel.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorProvider.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorResult.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorScope.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/ trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/ trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2NuitonValidator.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2NuitonValidatorProvider.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2ScopeValidator.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2ValidatorUtil.java trunk/nuiton-validator/src/main/resources/META-INF/ trunk/nuiton-validator/src/main/resources/META-INF/services/ trunk/nuiton-validator/src/main/resources/META-INF/services/org.nuiton.validator.NuitonValidatorProvider Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/AbstractNuitonValidatorProvider.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/AbstractNuitonValidatorProvider.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/AbstractNuitonValidatorProvider.java 2011-01-17 18:00:50 UTC (rev 2011) @@ -0,0 +1,120 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin + * %% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * Abstract provider of validator. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0 + */ +public abstract class AbstractNuitonValidatorProvider implements NuitonValidatorProvider { + + protected Map<ModelEntry<?>, NuitonValidatorModel<?>> models; + + protected final String name; + + public AbstractNuitonValidatorProvider(String name) { + this.name = name; + } + + @Override + public <O> NuitonValidatorModel<O> getModel(Class<O> type, String context, NuitonValidatorScope... scopes) { + ModelEntry<O> key = ModelEntry.createModelEntry(type, context, scopes); + + @SuppressWarnings({"unchecked"}) + NuitonValidatorModel<O> model = (NuitonValidatorModel<O>) getModels().get(key); + + if (model == null) { + model = newModel(type, context, scopes); + } + return model; + } + + protected Map<ModelEntry<?>, NuitonValidatorModel<?>> getModels() { + if (models == null) { + models = new HashMap<ModelEntry<?>, NuitonValidatorModel<?>>(); + } + return models; + } + + protected static class ModelEntry<O> implements Serializable { + + private static final long serialVersionUID = 1L; + + protected final Class<O> type; + + protected final String context; + + protected final NuitonValidatorScope[] scopes; + + public static <O> ModelEntry<O> createModelEntry(Class<O> type, + String context, + NuitonValidatorScope... scopes) { + return new ModelEntry<O>(type, context, scopes); + } + + protected ModelEntry(Class<O> type, + String context, + NuitonValidatorScope... scopes) { + this.type = type; + this.context = context; + this.scopes = scopes == null ? NuitonValidatorScope.values() : scopes; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ModelEntry)) return false; + + ModelEntry<?> that = (ModelEntry<?>) o; + + if (context != null ? !context.equals(that.context) : that.context != null) + return false; + if (!Arrays.equals(scopes, that.scopes)) return false; + return type.equals(that.type); + + } + + @Override + public int hashCode() { + int result = type.hashCode(); + result = 31 * result + (context != null ? context.hashCode() : 0); + result = 31 * result + Arrays.hashCode(scopes); + return result; + } + } + + @Override + public String getName() { + return name; + } + +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/AbstractNuitonValidatorProvider.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidator.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidator.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidator.java 2011-01-17 18:00:50 UTC (rev 2011) @@ -0,0 +1,52 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin + * %% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +/** + * Contract of a validator. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0 + */ +public interface NuitonValidator<O> { + + /** + * Obtain the model of a validator. + * + * @return the model of this validator + * @see NuitonValidatorModel + */ + NuitonValidatorModel<O> getModel(); + + /** + * Validates the given object and returns the result of validation. + * + * @param object the object to validate + * @return the result of validation for the given object + * @throws NullPointerException if object is {@code null}. + */ + NuitonValidatorResult validate(O object) throws NullPointerException; + +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorFactory.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorFactory.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorFactory.java 2011-01-17 18:00:50 UTC (rev 2011) @@ -0,0 +1,171 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin + * %% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.Map; +import java.util.ServiceLoader; +import java.util.TreeMap; + +/** + * Factory to obtain new validators. + * <p/> + * The factory contains a cache of {@link NuitonValidatorModel}. + * <p/> + * To obtain a new validator with no context, use this code : + * <pre> + * NuitonValidator<O> validator = NuitonValidatorFactory.newValidator(O.class); + * </pre> + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0 + */ +public class NuitonValidatorFactory { + + /** Logger. */ + static private final Log log = + LogFactory.getLog(NuitonValidatorFactory.class); + + protected static String defaultProviderName; + + protected static Map<String, NuitonValidatorProvider> providers; + + public static <O> NuitonValidator<O> newValidator(Class<O> type, + NuitonValidatorScope... scopes) { + NuitonValidator<O> result = newValidator(type, null, scopes); + return result; + } + + public static <O> NuitonValidator<O> newValidator(Class<O> type, + String context, + NuitonValidatorScope... scopes) { + + String providerName = getDefaultProviderName(); + + NuitonValidator<O> result = newValidator(providerName, + type, + context, + scopes); + return result; + } + + public static <O> NuitonValidator<O> newValidator(String providerName, + Class<O> type, + String context, + NuitonValidatorScope... scopes) throws NullPointerException { + + if (type == null) { + throw new NullPointerException( + "type parameter can not be null."); + } + + // get the provider + NuitonValidatorProvider provider = getProvider(providerName); + + + // obtain validator model form the provider + NuitonValidatorModel<O> model = + provider.getModel(type, context, scopes); + + // obtain validator from the the provider + NuitonValidator<O> result = provider.newValidator(model); + return result; + } + + public static Map<String, NuitonValidatorProvider> getProviders() { + if (providers == null) { + providers = new TreeMap<String, NuitonValidatorProvider>(); + ServiceLoader<NuitonValidatorProvider> serviceLoader = + ServiceLoader.load(NuitonValidatorProvider.class); + + for (NuitonValidatorProvider provider : serviceLoader) { + if (log.isInfoEnabled()) { + log.info("obtain validator provider " + provider.getName()); + } + providers.put(provider.getName(), provider); + } + } + return providers; + } + + public static String getDefaultProviderName() throws IllegalStateException { + + if (defaultProviderName == null) { + + // takes the first provider from existing provider + + Map<String, NuitonValidatorProvider> providers = getProviders(); + if (providers.isEmpty()) { + throw new IllegalStateException( + "Could not find any provider of validator."); + } + defaultProviderName = providers.keySet().iterator().next(); + + if (log.isInfoEnabled()) { + log.info("Set the default provider name to " + defaultProviderName); + } + } + + return defaultProviderName; + } + + public static void setDefaultProviderName(String defaultProviderName) throws IllegalArgumentException, NullPointerException { + + if (defaultProviderName == null) { + throw new NullPointerException("defaultProviderName can not be null."); + } + // check provider exists + getProvider(defaultProviderName); + + NuitonValidatorFactory.defaultProviderName = defaultProviderName; + } + + protected static NuitonValidatorProvider getProvider(String providerName) throws IllegalArgumentException, NullPointerException { + + if (providerName == null) { + + // take the default validator provider name + throw new NullPointerException( + "providerName parameter can not be null."); + } + + NuitonValidatorProvider provider = getProviders().get(providerName); + if (provider == null) { + throw new IllegalArgumentException( + "Could not find provider named '" + + defaultProviderName + "', existing providers are : " + + getProviders().keySet()); + } + return provider; + } + + protected NuitonValidatorFactory() { + // avoid instanciation of this factory + } + + +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorFactory.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorModel.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorModel.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorModel.java 2011-01-17 18:00:50 UTC (rev 2011) @@ -0,0 +1,87 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin + * %% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import java.io.Serializable; +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +/** + * Represents the model of a {@link NuitonValidator}. + * <p/> + * This model describing properties of a validator : + * <ul> + * <li>{@link #type} : the type of object which can be validated by the validator</li> + * <li>{@link #context} : the context of validation, if no context is required then the context is {@code null}. + * <li>{@link #scopes} : the scopes of validation (see {@link NuitonValidatorScope})</li> + * <li>{@link #fields} : the fields that can be validated by the validator</li> + * </ul> + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0 + */ +public class NuitonValidatorModel<O> implements Serializable { + + private static final long serialVersionUID = 1L; + + /** Type of object to validate */ + protected Class<O> type; + + /** Context of validation (can be {@code null}, for no context). */ + protected String context; + + /** Set of scopes that can be validated for the type and context */ + protected Set<NuitonValidatorScope> scopes; + + /** Set of fields that can be validated for the type and context */ + protected Map<NuitonValidatorScope, String[]> fields; + + public NuitonValidatorModel(Class<O> type, + String context, + Set<NuitonValidatorScope> scopes, + Map<NuitonValidatorScope, String[]> fields) { + this.type = type; + this.context = context; + this.scopes = Collections.unmodifiableSet(scopes); + this.fields = Collections.unmodifiableMap(fields); + } + + public Class<O> getType() { + return type; + } + + public String getContext() { + return context; + } + + public Set<NuitonValidatorScope> getScopes() { + return scopes; + } + + public Map<NuitonValidatorScope, String[]> getFields() { + return fields; + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorModel.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorProvider.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorProvider.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorProvider.java 2011-01-17 18:00:50 UTC (rev 2011) @@ -0,0 +1,57 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin + * %% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import java.util.ServiceLoader; + +/** + * Provider of {@link NuitonValidator}. + * <p/> + * An implementation of a such class provides a implementation of a validator models + * and also of validator. + * <p/> + * <b>Note:</b> Providers are used in the {@link NuitonValidatorFactory} and + * should be registered via the {@link ServiceLoader} api. + * + * @author tchemit <chemit@codelutin.com> + * @see NuitonValidatorModel + * @see NuitonValidator + * @see ServiceLoader + * @since 2.0 + */ +public interface NuitonValidatorProvider { + + String getName(); + + <O> NuitonValidatorModel<O> getModel(Class<O> type, + String context, + NuitonValidatorScope... scopes); + + <O> NuitonValidatorModel<O> newModel(Class<O> type, + String context, + NuitonValidatorScope... scopes); + + <O> NuitonValidator<O> newValidator(NuitonValidatorModel<O> model); +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorProvider.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorResult.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorResult.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorResult.java 2011-01-17 18:00:50 UTC (rev 2011) @@ -0,0 +1,222 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin + * %% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +/** + * Default implementation of the {@link NuitonValidatorResult} contract. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0 + */ +public class NuitonValidatorResult { + + public static class FieldMap<V> extends TreeMap<String, V> { + + private static final long serialVersionUID = 1L; + } + + protected EnumMap<NuitonValidatorScope, FieldMap<List<String>>> messages; + + protected Map<String, FieldMap<Object>> tagValues; + + public boolean isValid() { + return !hasFatalMessages() && !hasErrorMessagess(); + } + + public boolean hasMessagesForScope(NuitonValidatorScope scope) { + boolean result = false; + if (messages != null) { + result = messages.containsKey(scope); + } + return result; + } + + public boolean hasMessagesForScope(String field, NuitonValidatorScope scope) { + boolean result = false; + if (messages != null) { + result = messages.containsKey(scope); + + if (result) { + FieldMap<List<String>> fieldMap = messages.get(scope); + result = fieldMap != null && fieldMap.containsKey(field); + } + } + return result; + } + + public boolean hasFatalMessages() { + boolean result = hasMessagesForScope(NuitonValidatorScope.FATAL); + return result; + } + + public boolean hasErrorMessagess() { + boolean result = hasMessagesForScope(NuitonValidatorScope.ERROR); + return result; + } + + public boolean hasInfoMessages() { + boolean result = hasMessagesForScope(NuitonValidatorScope.INFO); + return result; + } + + public boolean hasWarningMessages() { + boolean result = hasMessagesForScope(NuitonValidatorScope.WARNING); + return result; + } + + public void addMessagesForScope(NuitonValidatorScope scope, Map<String, List<String>> newMessages) { + if (messages == null) { + messages = new EnumMap<NuitonValidatorScope, FieldMap<List<String>>>(NuitonValidatorScope.class); + } + + FieldMap<List<String>> fieldMap = messages.get(scope); + + if (fieldMap == null) { + fieldMap = new FieldMap<List<String>>(); + messages.put(scope, fieldMap); + } + + for (Map.Entry<String, List<String>> entry : newMessages.entrySet()) { + String fieldName = entry.getKey(); + List<String> messages = entry.getValue(); + List<String> oldMessages = fieldMap.get(fieldName); + if (oldMessages == null) { + oldMessages = messages; + fieldMap.put(fieldName, oldMessages); + } else { + oldMessages.addAll(messages); + } + } + } + + public List<String> getMessagesForScope(NuitonValidatorScope scope) { + + List<String> result = new ArrayList<String>(); + if (messages != null) { + FieldMap<List<String>> fieldMap = messages.get(scope); + for (List<String> messages : fieldMap.values()) { + result.addAll(messages); + } + } + return result; + } + + public List<String> getMessagesForScope(String field, + NuitonValidatorScope scope) { + + List<String> result = null; + if (messages != null) { + FieldMap<List<String>> fieldMap = messages.get(scope); + result = fieldMap.get(field); + } + if (result == null) { + result = Collections.emptyList(); + } + return result; + } + + public List<String> getFatalMessages(String field) { + List<String> result = + getMessagesForScope(field, NuitonValidatorScope.FATAL); + return result; + } + + public List<String> getErrorMessages(String field) { + List<String> result = + getMessagesForScope(field, NuitonValidatorScope.ERROR); + return result; + } + + public List<String> getInfoMessages(String field) { + List<String> result = + getMessagesForScope(field, NuitonValidatorScope.INFO); + return result; + } + + public List<String> getWarningMessages(String field) { + List<String> result = + getMessagesForScope(field, NuitonValidatorScope.WARNING); + return result; + } + + public Map<String, Object> getTagValues(String field) { + Map<String, Object> result = null; + if (tagValues != null) { + result = tagValues.get(field); + } + if (result == null) { + result = Collections.emptyMap(); + } + return result; + } + + public List<String> getFieldsForScope(NuitonValidatorScope scope) { + + List<String> result = null; + if (messages != null) { + FieldMap<List<String>> fieldMap = messages.get(scope); + result = new ArrayList<String>(fieldMap.keySet()); + } + if (result == null) { + result = Collections.emptyList(); + } + return result; + } + + public List<String> getFieldsForFatal() { + List<String> result = getFieldsForScope(NuitonValidatorScope.FATAL); + return result; + } + + public List<String> getFieldsForError() { + List<String> result = getFieldsForScope(NuitonValidatorScope.ERROR); + return result; + } + + public List<String> getFieldsForInfo() { + List<String> result = getFieldsForScope(NuitonValidatorScope.INFO); + return result; + } + + public List<String> getFieldsForWarning() { + List<String> result = getFieldsForScope(NuitonValidatorScope.WARNING); + return result; + } + + protected EnumMap<NuitonValidatorScope, FieldMap<List<String>>> getMessages() { + return messages; + } + + protected Map<String, FieldMap<Object>> getTagValues() { + return tagValues; + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorResult.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorScope.java (from rev 2010, trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorScope.java) =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorScope.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/NuitonValidatorScope.java 2011-01-17 18:00:50 UTC (rev 2011) @@ -0,0 +1,79 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator; + +import static org.nuiton.i18n.I18n.n_; + +/** + * The differents levels of messages in validation process. + * <p/> + * The order of the enum defines the severity of validation. + * <p/> + * Always begin with fatal, then error, then if no error found, try warning, then info... + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0 + */ +public enum NuitonValidatorScope { + + /** + * the fatal error scope level. + * <p/> + * When a message of a such scope is found on a validator, then the + * validator is invalid and modified. + */ + FATAL(n_("validator.scope.fatal.label")), + /** + * the error scope level. + * <p/> + * When a message of a such scope is found on a validator, then the + * validator is invalid and modified. + */ + ERROR(n_("validator.scope.error.label")), + /** + * the warning scope level. + * <p/> + * When a message of a such scope is found on a validator, then the + * validator is still valid but modified. + */ + WARNING(n_("validator.scope.warning.label")), + /** + * the information scope level. + * <p/> + * When a message of a sucg scope is found on a validator, then the + * validator is still valid and not modified. + */ + INFO(n_("validator.scope.info.label")); + + private final String label; + + NuitonValidatorScope(String label) { + this.label = label; + } + + public String getLabel() { + return label; + } +} Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2NuitonValidator.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2NuitonValidator.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2NuitonValidator.java 2011-01-17 18:00:50 UTC (rev 2011) @@ -0,0 +1,112 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin + * %% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.xwork2; + +import org.nuiton.validator.NuitonValidator; +import org.nuiton.validator.NuitonValidatorModel; +import org.nuiton.validator.NuitonValidatorResult; +import org.nuiton.validator.NuitonValidatorScope; + +import java.util.Arrays; +import java.util.EnumMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Implementation of {@link NuitonValidator} using {@code XWorks2} validators. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0 + */ +public class XWork2NuitonValidator<O> implements NuitonValidator<O> { + + protected NuitonValidatorModel<O> model; + + /** xworks scope validators * */ + protected Map<NuitonValidatorScope, XWork2ScopeValidator<O>> validators; + + public XWork2NuitonValidator(NuitonValidatorModel<O> model) { + + this.model = model; + + // init validators + validators = new EnumMap<NuitonValidatorScope, XWork2ScopeValidator<O>>(NuitonValidatorScope.class); + + Class<O> type = model.getType(); + String context = model.getContext(); + + Map<NuitonValidatorScope, String[]> fieldsMap = model.getFields(); + + for (Map.Entry<NuitonValidatorScope, String[]> entry : fieldsMap.entrySet()) { + + NuitonValidatorScope scope = entry.getKey(); + + String scopeContext = + XWork2ValidatorUtil.getContextForScope( + context, + scope + ); + + Set<String> fields = new HashSet<String>( + Arrays.asList(entry.getValue())); + + XWork2ScopeValidator<O> newValidator = + XWork2ValidatorUtil.newXWorkScopeValidator( + type, + scopeContext, + fields + ); + + validators.put(scope, newValidator); + } + } + + @Override + public NuitonValidatorModel<O> getModel() { + return model; + } + + @Override + public NuitonValidatorResult validate(O object) throws NullPointerException { + + if (object == null) { + throw new NullPointerException("object parameter can not be null."); + } + + NuitonValidatorResult result = new NuitonValidatorResult(); + + for (NuitonValidatorScope scope : validators.keySet()) { + + XWork2ScopeValidator<O> validator = validators.get(scope); + + Map<String, List<String>> newMessages = validator.validate(object); + + result.addMessagesForScope(scope, newMessages); + } + return result; + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2NuitonValidator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2NuitonValidatorProvider.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2NuitonValidatorProvider.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2NuitonValidatorProvider.java 2011-01-17 18:00:50 UTC (rev 2011) @@ -0,0 +1,76 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin + * %% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.xwork2; + +import org.nuiton.validator.AbstractNuitonValidatorProvider; +import org.nuiton.validator.NuitonValidator; +import org.nuiton.validator.NuitonValidatorModel; +import org.nuiton.validator.NuitonValidatorScope; + +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Map; +import java.util.Set; + +/** + * Provider of validator for the xworks nuiton validator. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0 + */ +public class XWork2NuitonValidatorProvider extends AbstractNuitonValidatorProvider { + + public static final String PROVIDER_NAME = "xwork2"; + + public XWork2NuitonValidatorProvider() { + super(PROVIDER_NAME); + } + + @Override + public <O> NuitonValidatorModel<O> newModel(Class<O> type, + String context, + NuitonValidatorScope... scopes) { + + if (scopes.length == 0) { + // use all scopes + scopes = NuitonValidatorScope.values(); + } + + Map<NuitonValidatorScope, String[]> fields = + XWork2ValidatorUtil.detectFields(type, context, scopes); + + Set<NuitonValidatorScope> scopeSet = + EnumSet.noneOf(NuitonValidatorScope.class); + scopeSet.addAll(Arrays.asList(scopes)); + + return new NuitonValidatorModel<O>(type, context, scopeSet, fields); + } + + @Override + public <O> NuitonValidator<O> newValidator(NuitonValidatorModel<O> model) { + return new XWork2NuitonValidator<O>(model); + } + +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2NuitonValidatorProvider.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2ScopeValidator.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2ScopeValidator.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2ScopeValidator.java 2011-01-17 18:00:50 UTC (rev 2011) @@ -0,0 +1,225 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.xwork2; + +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ValidationAwareSupport; +import com.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ActionValidatorManager; +import com.opensymphony.xwork2.validator.DelegatingValidatorContext; +import com.opensymphony.xwork2.validator.ValidationException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * A customized validator for a given bean. + * <p/> + * Use the method {@link #validate(Object)} to obtain the messages detected by + * the validator for the given bean. + * + * @param <O> type of the bean to validate. + * @author tchemit <chemit@codelutin.com> + * @since 2.0 + */ +public class XWork2ScopeValidator<O> { + + /** Logger */ + private static final Log log = LogFactory.getLog(XWork2ScopeValidator.class); + + protected final static Map<String, List<String>> EMPTY_RESULT = + Collections.unmodifiableMap(new HashMap<String, List<String>>()); + + /** the type of bean to validate */ + protected final Class<O> type; + + /** the validation named context (can be null) */ + protected String context; + + /** the list of field names detected for this validator */ + protected Set<String> fieldNames; + + // -- + // XWorks fields + // -- + + protected ValidationAwareSupport validationSupport; + + protected DelegatingValidatorContext validationContext; + + protected ActionValidatorManager validator; + + protected ValueStack vs; + + protected XWork2ScopeValidator(Class<O> type, + String context, + Set<String> fieldNames, + ValueStack vs) { + + this.type = type; + this.context = context; + this.fieldNames = fieldNames; + + validationSupport = new ValidationAwareSupport(); + validationContext = new DelegatingValidatorContext(validationSupport); + + if (vs == null) { + + // create a standalone value stack + vs = XWork2ValidatorUtil.createValuestack(); + if (log.isDebugEnabled()) { + log.debug("create a standalone value stack " + vs); + } + } else { + if (log.isDebugEnabled()) { + log.debug("use given value stack " + vs); + } + } + + this.vs = vs; + + validator = XWork2ValidatorUtil.newValidationManager(vs); + } + + public Class<O> getType() { + return type; + } + + public String getContext() { + return context; + } + + public Set<String> getFieldNames() { + return fieldNames; + } + + public ActionValidatorManager getValidator() { + return validator; + } + + /** + * Test if the validator contains the field given his name + * + * @param fieldName the name of the searched field + * @return <code>true</code> if validator contaisn this field, + * <code>false</code> otherwise + */ + public boolean containsField(String fieldName) { + return fieldNames.contains(fieldName); + } + + /** + * Valide le bean donné et retourne les messages produits. + * + * @param bean le bean a valider (il doit etre non null) + * @return le dictionnaire des messages produits par la validation indexées + * par le nom du champs du bean impacté. + */ + public Map<String, List<String>> validate(O bean) { + + if (bean == null) { + throw new NullPointerException( + "bean parameter can not be null in method validate"); + } + + Map<String, List<String>> result = EMPTY_RESULT; + + + if (fieldNames.isEmpty()) { + return result; + } + + // on lance la validation uniquement si des champs sont a valider + try { + + //TC - 20081024 : since context is in a ThreadLocal variable, + // we must do the check + if (ActionContext.getContext() == null) { + ActionContext.setContext(new ActionContext(vs.getContext())); + } + + validator.validate(bean, context, validationContext); + + if (log.isTraceEnabled()) { + log.trace("Action errors: " + + validationContext.getActionErrors()); + log.trace("Action messages: " + + validationContext.getActionMessages()); + log.trace("Field errors: " + + validationContext.getFieldErrors()); + } + + if (log.isDebugEnabled()) { + log.debug(this + " : " + + validationContext.getFieldErrors()); + } + + // retreave errors by field + if (validationContext.hasFieldErrors()) { + Map<?, ?> messages = validationContext.getFieldErrors(); + result = new HashMap<String, List<String>>(messages.size()); + for (Object fieldName : messages.keySet()) { + Collection<?> c = + (Collection<?>) messages.get(fieldName); + List<String> mm = new ArrayList<String>(c.size()); + for (Object message : c) { + // tchemit 2010-08-28 : trim the incoming message + // (I18n will not translate it otherwise) + String messageStr = message == null ? "" : message + ""; + mm.add(messageStr.trim()); + } + result.put(fieldName + "", mm); + } + } + + } catch (ValidationException eee) { + if (log.isWarnEnabled()) { + log.warn("Error during validation on " + type + + " for reason : " + eee.getMessage(), eee); + } + + } finally { + + // on nettoye toujours le validateur apres operation + validationSupport.clearErrorsAndMessages(); + } + + return result; + } + + @Override + public String toString() { + return super.toString() + "<beanClass:" + type + + ", contextName:" + context + ">"; + } + +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2ScopeValidator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2ValidatorUtil.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2ValidatorUtil.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2ValidatorUtil.java 2011-01-17 18:00:50 UTC (rev 2011) @@ -0,0 +1,218 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin + * %% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.xwork2; + +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.config.ConfigurationManager; +import com.opensymphony.xwork2.inject.Container; +import com.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.util.ValueStackFactory; +import com.opensymphony.xwork2.validator.ActionValidatorManager; +import com.opensymphony.xwork2.validator.FieldValidator; +import com.opensymphony.xwork2.validator.Validator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.validator.NuitonValidatorScope; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +/** + * Usefull methods to works with work2 validator api. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0 + */ +public class XWork2ValidatorUtil { + + /** Logger. */ + static private final Log log = LogFactory.getLog(XWork2ValidatorUtil.class); + + /** + * a shared value stack to allow external operations on it (for example add + * some datas in stack to be usedby validators + */ + static private ValueStack sharedValueStack; + + public static ValueStack getSharedValueStack() { + if (sharedValueStack == null) { + + // init context + sharedValueStack = createValuestack(); + if (log.isDebugEnabled()) { + log.debug("init shared value stack " + sharedValueStack); + } + } + return sharedValueStack; + } + + public static ValueStack createValuestack() { + + ConfigurationManager confManager = new ConfigurationManager(); + Configuration conf = confManager.getConfiguration(); + Container container = conf.getContainer(); + ValueStackFactory stackFactory = + container.getInstance(ValueStackFactory.class); + ValueStack vs = stackFactory.createValueStack(); + return vs; + } + + public static <O> XWork2ScopeValidator<O> newXWorkScopeValidator(Class<O> beanClass, + String contextName, + Set<String> fields + ) { + return newXWorkScopeValidator(beanClass, + contextName, + fields, + getSharedValueStack() + ); + } + + public static <O> XWork2ScopeValidator<O> newXWorkScopeValidator(Class<O> beanClass, + String contextName, + Set<String> fields, + ValueStack vs) { + + return new XWork2ScopeValidator<O>(beanClass, + contextName, + fields, + vs + ); + } + + + public static String getContextForScope(String context, + NuitonValidatorScope scope) { + return (context == null ? "" : context + "-") + + scope.name().toLowerCase(); + } + + protected static ActionValidatorManager newValidationManager(ValueStack vs) { + + if (vs == null) { + vs = createValuestack(); + + if (log.isDebugEnabled()) { + log.debug("create a standalone value stack " + vs); + } + } else { + if (log.isDebugEnabled()) { + log.debug("use given value stack " + vs); + } + } + + ActionContext context = new ActionContext(vs.getContext()); + + // must set the action context otherwise can't obtain after validators + // with the method validator.getValidators(XXX) + // Later in the code, we could not having reference to the ValueStack + // before using a validator... Must be cleaned... + ActionContext.setContext(context); + + // init validator + Container container = context.getContainer(); + ActionValidatorManager validatorManager = + container.getInstance(ActionValidatorManager.class, + "no-annotations"); + + return validatorManager; + } + + public static <O> Map<NuitonValidatorScope, String[]> detectFields(Class<O> type, + String context, + NuitonValidatorScope[] scopeUniverse) { + + + ActionValidatorManager validatorManager = newValidationManager(null); + + Map<NuitonValidatorScope, String[]> fields = new TreeMap<NuitonValidatorScope, String[]>(); + + for (NuitonValidatorScope scope : scopeUniverse) { + + Set<String> fieldNames = detectFieldsForScope(validatorManager, type, scope, context, false); + + if (log.isDebugEnabled()) { + log.debug("detected validator fields for scope " + scope + ":" + context + + " : " + fieldNames); + } + + if (!fieldNames.isEmpty()) { + + // fields detected in this validator, keep it + + fields.put(scope, fieldNames.toArray(new String[fieldNames.size()])); + } + } + + return fields; + + } + + protected static Set<String> detectFieldsForScope(ActionValidatorManager validator, + Class<?> type, + NuitonValidatorScope scope, + String context, + boolean includeDefaultContext) { + + + String scopeContext = getContextForScope(context, scope); + + + Set<String> fields = new HashSet<String>(); + + int skip = 0; + if (scopeContext != null && !includeDefaultContext) { + // count the number of validator to skip + for (Validator<?> v : validator.getValidators(type, null)) { + // we only work on FieldValidator at the moment + if (v instanceof FieldValidator) { + skip++; + } + } + } + + for (Validator<?> v : validator.getValidators(type, scopeContext)) { + // we only work on FieldValidator at the moment + if (v instanceof FieldValidator) { + if (skip > 0) { + skip--; + continue; + } + FieldValidator fieldValidator = (FieldValidator) v; + if (log.isDebugEnabled()) { + log.debug("context " + context + " - field " + + fieldValidator.getFieldName()); + } + String fName = fieldValidator.getFieldName(); + fields.add(fName); + } + } + + return fields; + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/xwork2/XWork2ValidatorUtil.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/nuiton-validator/src/main/resources/META-INF/services/org.nuiton.validator.NuitonValidatorProvider =================================================================== --- trunk/nuiton-validator/src/main/resources/META-INF/services/org.nuiton.validator.NuitonValidatorProvider (rev 0) +++ trunk/nuiton-validator/src/main/resources/META-INF/services/org.nuiton.validator.NuitonValidatorProvider 2011-01-17 18:00:50 UTC (rev 2011) @@ -0,0 +1 @@ +org.nuiton.validator.xwork2.XWork2NuitonValidatorProvider \ No newline at end of file Property changes on: trunk/nuiton-validator/src/main/resources/META-INF/services/org.nuiton.validator.NuitonValidatorProvider ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL
participants (1)
-
tchemit@users.nuiton.org