private void doMigrate(File dir) { idToNumber = new TreeMap<String, Integer>(); File[] kids = dir.listFiles(); // Need to process symlinks first so we can rename to them. List<File> kidsList = new ArrayList<File>(Arrays.asList(kids)); Iterator<File> it = kidsList.iterator(); while (it.hasNext()) { File kid = it.next(); String name = kid.getName(); try { Integer.parseInt(name); } catch (NumberFormatException x) { LOGGER.log(FINE, "ignoring nonnumeric entry {0}", name); continue; } try { if (Util.isSymlink(kid)) { LOGGER.log( FINE, "deleting build number symlink {0} → {1}", new Object[] {name, Util.resolveSymlink(kid)}); } else if (kid.isDirectory()) { LOGGER.log(FINE, "ignoring build directory {0}", name); continue; } else { LOGGER.log(WARNING, "need to delete anomalous file entry {0}", name); } Util.deleteFile(kid); it.remove(); } catch (Exception x) { LOGGER.log(WARNING, "failed to process " + kid, x); } } it = kidsList.iterator(); while (it.hasNext()) { File kid = it.next(); try { String name = kid.getName(); try { Integer.parseInt(name); LOGGER.log(FINE, "skipping new build dir {0}", name); continue; } catch (NumberFormatException x) { // OK, next… } if (!kid.isDirectory()) { LOGGER.log(FINE, "skipping non-directory {0}", name); continue; } long timestamp; try { synchronized (legacyIdFormatter) { timestamp = legacyIdFormatter.parse(name).getTime(); } } catch (ParseException x) { LOGGER.log(WARNING, "found unexpected dir {0}", name); continue; } File buildXml = new File(kid, "build.xml"); if (!buildXml.isFile()) { LOGGER.log(WARNING, "found no build.xml in {0}", name); continue; } String xml = FileUtils.readFileToString(buildXml, Charsets.UTF_8); Matcher m = NUMBER_ELT.matcher(xml); if (!m.find()) { LOGGER.log(WARNING, "could not find <number> in {0}/build.xml", name); continue; } int number = Integer.parseInt(m.group(1)); String nl = m.group(2); xml = m.replaceFirst( " <id>" + name + "</id>" + nl + " <timestamp>" + timestamp + "</timestamp>" + nl); File newKid = new File(dir, Integer.toString(number)); move(kid, newKid); FileUtils.writeStringToFile(new File(newKid, "build.xml"), xml, Charsets.UTF_8); LOGGER.log(FINE, "fully processed {0} → {1}", new Object[] {name, number}); idToNumber.put(name, number); } catch (Exception x) { LOGGER.log(WARNING, "failed to process " + kid, x); } } }