in core/src/main/java/org/apache/struts2/validator/DefaultValidatorFactory.java [116:194]
private void parseValidators() {
LOG.debug("Loading validator definitions.");
List<File> files = new ArrayList<>();
try {
// Get custom validator configurations via the classpath
Iterator<URL> urls = ClassLoaderUtil.getResources("", DefaultValidatorFactory.class, false);
while (urls.hasNext()) {
URL u = urls.next();
try {
URI uri = new URI(u.toExternalForm().replaceAll(" ", "%20"));
if (!uri.isOpaque() && "file".equalsIgnoreCase(uri.getScheme())) {
File f = new File(uri);
FilenameFilter filter = (file, fileName) -> fileName.contains("-validators.xml");
// First check if this is a directory
// If yes, then just do a "list" to get all files in this directory
// and match the filenames with *-validators.xml. If the filename
// matches then add to the list of files to be parsed
if (f.isDirectory()) {
try {
File[] ff = f.listFiles(filter);
if ( ff != null && ff.length > 0) {
files.addAll(Arrays.asList(ff));
}
} catch (SecurityException se) {
LOG.error("Security Exception while accessing directory '{}'", f, se);
}
} else {
// If this is not a directory, then get hold of the inputstream.
// If its not a ZipInputStream, then create a ZipInputStream out
// of it. The intention is to allow nested jar files to be scanned
// for *-validators.xml.
// Ex: struts-app.jar -> MyApp.jar -> Login-validators.xml should be
// parsed and loaded.
ZipInputStream zipInputStream = null;
try (InputStream inputStream = u.openStream()) {
if (inputStream instanceof ZipInputStream) {
zipInputStream = (ZipInputStream) inputStream;
} else {
zipInputStream = new ZipInputStream(inputStream);
}
ZipEntry zipEntry = zipInputStream.getNextEntry();
while (zipEntry != null) {
if (zipEntry.getName().endsWith("-validators.xml")) {
LOG.trace("Adding validator {}", zipEntry.getName());
files.add(new File(zipEntry.getName()));
}
zipEntry = zipInputStream.getNextEntry();
}
} finally {
//cleanup
if (zipInputStream != null) {
zipInputStream.close();
}
}
}
}
} catch (Exception ex) {
LOG.error("Unable to load {}", u, ex);
}
}
} catch (IOException e) {
throw new ConfigurationException("Unable to parse validators", e);
}
// Parse default validator configurations
String resourceName = "org/apache/struts2/validator/validators/default.xml";
retrieveValidatorConfiguration(resourceName);
// Overwrite and extend defaults with application specific validator configurations
resourceName = "validators.xml";
retrieveValidatorConfiguration(resourceName);
// Add custom (plugin) specific validator configurations
for (File file : files) {
retrieveValidatorConfiguration(file.getName());
}
}