protected boolean convertInternal()

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;
    }