/** * Returns the configuration history entries for one {@link Slave}. * * @return history list for one {@link Slave}. * @throws IOException if {@link JobConfigHistoryConsts#HISTORY_FILE} might not be read or the * path might not be urlencoded. */ public final List<ConfigInfo> getSlaveConfigs() throws IOException { checkConfigurePermission(); final ArrayList<ConfigInfo> configs = new ArrayList<ConfigInfo>(); final ArrayList<HistoryDescr> values = new ArrayList<HistoryDescr>(getHistoryDao().getRevisions(slave).values()); for (final HistoryDescr historyDescr : values) { final String timestamp = historyDescr.getTimestamp(); final XmlFile oldRevision = getHistoryDao().getOldRevision(slave, timestamp); if (oldRevision.getFile() != null) { configs.add(ConfigInfo.create(slave.getNodeName(), true, historyDescr, true)); } else if ("Deleted".equals(historyDescr.getOperation())) { configs.add(ConfigInfo.create(slave.getNodeName(), false, historyDescr, true)); } } Collections.sort(configs, ParsedDateComparator.DESCENDING); return configs; }
/** * Gets config history entries for the view options 'created', 'deleted' and 'jobs'. While 'jobs' * displays all available job config history entries, 'deleted' and 'created' only show the last * or the first one respectively. * * @param itemDir The job directory as File * @param folderName Something Jesse Glick came up with but never documented, probably the * folderName. * @throws IOException If one of the entries cannot be read. */ void getConfigsForType(File itemDir, String folderName) throws IOException { final String itemName = folderName.isEmpty() ? itemDir.getName() : folderName + "/" + itemDir.getName(); final List<HistoryDescr> historyEntries = new ArrayList<HistoryDescr>(overViewhistoryDao.getJobHistory(itemName).values()); if (historyEntries.isEmpty()) { return; } final boolean isADeletedJob = DeletedFileFilter.accepts(itemName); final boolean isNotADeletedJob = !isADeletedJob; if ("created".equals(type)) { if (isADeletedJob) { return; } HistoryDescr histDescr = historyEntries.get(0); if ("Created".equals(histDescr.getOperation())) { final ConfigInfo config = ConfigInfo.create(itemName, true, histDescr, true); configs.add(config); } else { // Why would the created entry not be the first one? Answer: // There's always a 'Changed' entry before the 'Created' entry, // because in the Jenkins core, when creating a new job, // the SaveableListener (which handles changes) fires // before the ItemListener (which handles creation, deletion etc.) // Older versions of the plugin didn't show this behaviour // since it was masked by some race condition. histDescr = historyEntries.get(1); if ("Created".equals(histDescr.getOperation())) { final ConfigInfo config = ConfigInfo.create(itemName, true, histDescr, true); configs.add(config); } } } else if ("deleted".equals(type)) { final HistoryDescr histDescr = historyEntries.get(historyEntries.size() - 1); if ("Deleted".equals(histDescr.getOperation())) { final ConfigInfo config = ConfigInfo.create(itemName, false, histDescr, false); configs.add(config); } } else { configs.addAll( HistoryDescrToConfigInfo.convert(itemName, true, historyEntries, isNotADeletedJob)); } }