import java.io.File File nball = new File('/space/src/nb/core-main') for (File module : nball.listFiles().sort()) { if (module.name == 'openide.util' || module.name == 'visualweb.libs.batik') { continue } for (File root : ['src', 'test/unit/src', 'test/qa-functional/src'].collect{new File(module, it)}) { if (root.isDirectory()) { for (File provider : new File(root, 'META-INF/services').listFiles()?.sort()) { fixup(root, provider) } } } } void fixup(File root, File provider) { List impls = [] Map> impl2Masked = [:] Map impl2Position = [:] String currImpl for (String line : provider.readLines()) { if (line =~ /^#-/) { masked = line.replaceFirst(/^#-/, '') impl2Masked[currImpl] = impl2Masked[currImpl] ?: [] impl2Masked[currImpl] += masked } else if (line =~ /^#position=/) { position = line.replaceFirst(/^#position=/, '') impl2Position[currImpl] = position } else if (line =~ /^#/) { println "$provider: COMMENT: $line" } else if (line =~ /^\S/) { impl = line currImpl = impl impls += impl } } if (currImpl) { if (impl2Masked.containsKey(null)) { impl2Masked[currImpl] = impl2Masked.remove(null) } boolean ok = true impls.each { ok &= register(provider, root, it, provider.name, impl2Position[it], impl2Masked[it]) } if (ok) { provider.delete() } else { println "$provider: not removing" } } else if (impl2Masked.size() > 0 || impl2Position.size() > 0 || impl2Position.containsKey(null)) { println "$provider: WARNING: inconvertible registrations; impl2Masked=$impl2Masked; impl2Position=$impl2Position" } else { println "$provider: WARNING: no registrations" provider.delete() } } boolean register(File provider, File root, String impl, String xface, String position, List masked) { File src = new File(root, impl.replaceFirst(/\$.+/, '').replace('.', '/') + '.java') if (!src.file) { println "$provider: WARNING: no such file $src" return false } String implshort = impl.replaceFirst(/.+[.$]/, '') String xfaceshort = xface.replaceFirst(/.+[.]/, '').replace('$', '.') String txt = src.text String ann = "@ServiceProvider(service=${xfaceshort}.class" if (position != null) { ann += ", position=$position" } if (masked != null) { ann += ", supersedes=" if (masked.size() == 1) { ann += "\"${masked[0]}\"" } else { ann =+ '{' + masked.collect{"\"$it\""}.join(', ') + '}' } } ann += ')\n' java.util.regex.Matcher m = txt =~ /(?m)(^[ \t]*)(?:(?:public|static|final)\s+)*class\s+$implshort\s+([^{]+)\{/ if (!m.find()) { println "$src: WARNING: could not find definition of $implshort" return false } // XXX check for existence of @ServiceProvider and use @ServiceProviders txt = txt.substring(0, m.start()) + m.group(1) + ann + txt.substring(m.start()) String imports = 'import org.openide.util.lookup.ServiceProvider;' if (!m.group(2).contains(xfaceshort)) { imports += "\nimport ${xface.replaceFirst(/\$.+/, '')};" } // XXX try to sort new import reasonably txt = txt.replaceFirst(/(package [\w.]+;\n)/, "\$1\n$imports") src.write(txt) return true }