/**
  * Returns the configuration file (default is {@code config.xml}) located in {@code diffDir}.
  * {@code diffDir} must either start with {@code HUDSON_HOME} and contain {@code config-history}
  * or be located under the configured {@code historyRootDir}. It also must not contain a '..'
  * pattern. Otherwise an {@link IllegalArgumentException} will be thrown.
  *
  * <p>This is to ensure that this plugin will not be abused to get arbitrary xml configuration
  * files located anywhere on the system.
  *
  * @param diffDir timestamped history directory.
  * @return xmlfile.
  */
 protected XmlFile getConfigXml(final String diffDir) {
   final JobConfigHistory plugin = hudson.getPlugin(JobConfigHistory.class);
   final File configuredHistoryRootDir = plugin.getConfiguredHistoryRootDir();
   final String allowedHistoryRootDir =
       configuredHistoryRootDir == null
           ? getHudson().getRootDir().getAbsolutePath()
           : configuredHistoryRootDir.getAbsolutePath();
   File configFile = null;
   if (diffDir != null) {
     if (!diffDir.startsWith(allowedHistoryRootDir) || diffDir.contains("..")) {
       throw new IllegalArgumentException(
           diffDir + " does not start with " + allowedHistoryRootDir + " or contains '..'");
     } else if (configuredHistoryRootDir == null
         && !diffDir.contains(JobConfigHistoryConsts.DEFAULT_HISTORY_DIR)) {
       throw new IllegalArgumentException(
           diffDir + " does not contain '" + JobConfigHistoryConsts.DEFAULT_HISTORY_DIR + "'");
     }
     configFile = plugin.getConfigFile(new File(diffDir));
   }
   if (configFile == null) {
     throw new IllegalArgumentException("Unable to get history from: " + diffDir);
   } else {
     return new XmlFile(configFile);
   }
 }
 /** {@inheritDoc} */
 @Override
 public void onChange(final Saveable o, final XmlFile file) {
   final JobConfigHistory plugin = getPlugin();
   LOG.log(FINEST, "In onChange for {0}", o);
   if (plugin.isSaveable(o, file)) {
     final HistoryDao configHistoryListenerHelper = getHistoryDao(plugin);
     configHistoryListenerHelper.saveItem(file);
   }
   LOG.log(FINEST, "onChange for {0} done.", o);
 }