in src/main/java/org/apache/tomcat/jakartaee/ClassConverter.java [113:188]
protected boolean convertInternal(String path, InputStream src, OutputStream dest, EESpecProfile profile, ClassLoader loader)
throws IOException {
byte[] classBytes = IOUtils.toByteArray(src);
ClassParser parser = new ClassParser(new ByteArrayInputStream(classBytes), "unknown");
JavaClass javaClass = parser.parse();
boolean converted = false;
// Loop through constant pool
Constant[] constantPool = javaClass.getConstantPool().getConstantPool();
// Need an int as the maximum pool size is 2^16
for (int i = 0; i < constantPool.length; i++) {
if (constantPool[i] instanceof ConstantUtf8) {
ConstantUtf8 c = (ConstantUtf8) constantPool[i];
String str = c.getBytes();
String newString = profile.convert(str);
// Object comparison is deliberate
if (newString != str) {
if (loader != null) {
// Since this is a runtime conversion, the idea is to only convert to
// Jakarta EE specification classes that exist in the container
String[] split = newString.split(";|<");
for (String current : split) {
int pos = current.indexOf(profile.getTarget() + "/");
boolean dotMode = false;
if (pos < 0) {
pos = current.indexOf(profile.getTarget() + ".");
dotMode = true;
}
if (pos >= 0) {
String resourceName = current.substring(pos);
if (dotMode) {
resourceName = resourceName.replace('.', '/');
}
resourceName = resourceName + ".class";
if (loader.getResource(resourceName) == null) {
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, sm.getString("classConverter.skipName",
profile.getSource(),
current.substring(pos).replace('/','.')));
}
// Cancel the replacement as the replacement does not exist
String originalFragment;
if (dotMode) {
originalFragment = current.replace(profile.getTarget() + ".", profile.getSource() + ".");
} else {
originalFragment = current.replace(profile.getTarget() + "/", profile.getSource() + "/");
}
newString = newString.replace(current, originalFragment);
}
}
}
}
c = new ConstantUtf8(newString);
constantPool[i] = c;
converted = true;
}
}
}
if (logger.isLoggable(Level.FINE)) {
if (converted) {
logger.log(Level.FINE, sm.getString("classConverter.converted", path.replace('/','.')));
} else if (logger.isLoggable(Level.FINEST)) {
logger.log(Level.FINEST, sm.getString("classConverter.noConversion", path.replace('/','.')));
}
}
if (converted) {
javaClass.dump(dest);
} else {
IOUtils.writeChunked(classBytes, dest);
}
return converted;
}