jaxx.runtime.validator.BeanValidatorDetector Maven / Gradle / Ivy
/*
* *##%
* JAXX Runtime
* Copyright (C) 2008 - 2009 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
* .
* ##%*
*/
package jaxx.runtime.validator;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Un detecteur de validateurs pour un liste de classes données et un
* répertoire où chercher les fichiers de validation.
*
* @author chemit
*
* @since 1.6.0
*/
public class BeanValidatorDetector {
/** to use log facility, just put in your code: log.info(\"...\"); */
private static final Log log = LogFactory.getLog(BeanValidatorDetector.class);
public SortedSet> detect(File sourceRoot, Class>... types) {
SortedSet> result = detect(BeanValidator.class, sourceRoot, null, types);
return result;
}
public SortedSet> detect(Class> validatorClass, File sourceRoot, Pattern contextFilter, Class>... types) {
SortedSet> result = new TreeSet>(new BeanValidatorComparator());
for (Class> c : types) {
File dir = getClassDir(sourceRoot, c);
if (!dir.exists()) {
// pas de repertoire adequate
log.debug("skip non existing directory " + dir);
continue;
}
String[] contexts = getContexts(c, dir);
if (log.isDebugEnabled()) {
log.debug("contexts : " + Arrays.toString(contexts));
}
if (contexts.length > 0) {
String[] realContexts = getContextsWithoutScopes(contexts);
if (log.isDebugEnabled()) {
log.debug("realContexts : " + Arrays.toString(realContexts));
}
if (contextFilter != null) {
// filter contexts
realContexts = getFilterContexts(contextFilter, realContexts);
if (log.isDebugEnabled()) {
log.debug("filterContexts : " + Arrays.toString(realContexts));
}
}
for (String context : realContexts) {
// on cherche le validateur
BeanValidator> validator = getValidator(validatorClass, c, context.isEmpty() ? null : context);
if (validator != null) {
// on enregistre le validateur
result.add(validator);
}
}
}
}
return result;
}
/**
* Pour un context et un type d'entité donné, instancie un validateur
* et test si ce validateur est utilisable (i.e qu'il admet des champs
* à valider).
*
* Si aucun champ n'est trouvé dans le validateur, alors on retourne null.
*
* @param le type du bean
* @param validatorClass le type de validateur a instancie
* @param klass le type du bean
* @param context le context du validateur
* @return le validateur initialisé, ou null
si aucun scope
* détecté dans le validateur.
*/
protected BeanValidator getValidator(Class> validatorClass, Class klass, String context) {
// BeanValidator valitator = new BeanValidator(klass, context);
BeanValidator valitator;
try {
valitator = (BeanValidator) validatorClass.getConstructor(Class.class, String.class).newInstance(klass, context);
} catch (Exception ex) {
throw new RuntimeException("could not instanciate validator " + validatorClass + " for reason " + ex.getMessage(), ex);
}
Set scopes = valitator.getScopes();
if (scopes.isEmpty()) {
valitator = null;
if (log.isDebugEnabled()) {
log.debug(klass + " : validator skip (no scopes detected)");
}
} else {
if (log.isDebugEnabled()) {
log.debug(klass + " : keep validator " + valitator);
}
}
return valitator;
}
protected File getClassDir(File sourceRoot, Class> clazz) {
String path = clazz.getPackage().getName().replaceAll("\\.", File.separator);
File dir = new File(sourceRoot, path);
return dir;
}
protected String[] getContexts(Class> clazz, File dir) {
Set result = new TreeSet();
ValidatorFilenameFilter filter = new ValidatorFilenameFilter(clazz);
if (log.isDebugEnabled()) {
log.debug("dir : " + dir);
}
String[] files = dir.list(filter);
for (String file : files) {
if (log.isDebugEnabled()) {
log.debug("file " + file);
}
String context = file.substring(filter.prefix.length(), file.length() - ValidatorFilenameFilter.SUFFIX.length());
if (log.isDebugEnabled()) {
log.debug("detect " + clazz.getSimpleName() + " context [" + context + "]");
}
result.add(context);
}
return result.toArray(new String[result.size()]);
}
protected String[] getContextsWithoutScopes(String[] contexts) {
Set result = new TreeSet();
BeanValidatorScope[] scopes = BeanValidatorScope.values();
for (String context : contexts) {
for (BeanValidatorScope scope : scopes) {
String scopeName = scope.name().toLowerCase();
if (!context.endsWith(scopeName)) {
// pas concerne par ce scope
continue;
}
if (log.isDebugEnabled()) {
log.debug("detect context : " + context);
}
String realContext = context.substring(0, context.length() - scopeName.length());
if (realContext.endsWith("-")) {
realContext = realContext.substring(0, realContext.length() - 1);
}
result.add(realContext);
}
}
return result.toArray(new String[result.size()]);
}
protected String[] getFilterContexts(Pattern contextFilter, String[] realContexts) {
List result = new ArrayList();
for (String c : realContexts) {
Matcher m = contextFilter.matcher(c);
if (m.matches()) {
result.add(c);
}
}
return result.toArray(new String[result.size()]);
}
protected static class ValidatorFilenameFilter implements FilenameFilter {
protected static final String SUFFIX = "-validation.xml";
protected Class> clazz;
protected String prefix;
public ValidatorFilenameFilter(Class> clazz) {
this.clazz = clazz;
this.prefix = clazz.getSimpleName() + "-";
}
@Override
public boolean accept(File dir, String name) {
boolean result = name.endsWith(SUFFIX);
if (result) {
result = name.startsWith(prefix);
}
return result;
}
}
protected static class BeanValidatorComparator implements Comparator> {
@Override
public int compare(BeanValidator> o1, BeanValidator> o2) {
String contextName1 = o1.getBeanClass().getSimpleName() + "-" + (o1.getContextName() == null ? "" : o1.getContextName());
String contextName2 = o2.getBeanClass().getSimpleName() + "-" + (o2.getContextName() == null ? "" : o2.getContextName());
return contextName1.compareTo(contextName2);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy