protected boolean isRebuildRequired()

in src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java [663:821]


    protected boolean isRebuildRequired(File genericJarFile, File weblogicJarFile) {
        boolean rebuild = false;

        JarFile genericJar = null;
        JarFile wlJar = null;
        File newWLJarFile = null;
        JarOutputStream newJarStream = null;
        ClassLoader genericLoader = null;

        try {
            log("Checking if weblogic Jar needs to be rebuilt for jar " + weblogicJarFile.getName(),
                Project.MSG_VERBOSE);
            // Only go forward if the generic and the WebLogic file both exist
            if (genericJarFile.exists() && genericJarFile.isFile()
                 && weblogicJarFile.exists() && weblogicJarFile.isFile()) {
                //open jar files
                genericJar = new JarFile(genericJarFile);
                wlJar = new JarFile(weblogicJarFile);

                Map<String, JarEntry> replaceEntries = new HashMap<>();

                //get the list of generic jar entries
                Map<String, JarEntry> genericEntries = genericJar.stream()
                        .collect(Collectors.toMap(je -> je.getName().replace('\\', '/'),
                                je -> je, (a, b) -> b));
                // get the list of WebLogic jar entries
                Map<String, JarEntry> wlEntries = wlJar.stream().collect(Collectors.toMap(ZipEntry::getName,
                        je -> je, (a, b) -> b));

                // Cycle through generic and make sure its in WebLogic
                genericLoader = getClassLoaderFromJar(genericJarFile);

                for (String filepath : genericEntries.keySet()) {
                    if (!wlEntries.containsKey(filepath)) {
                        // a file doesn't exist rebuild
                        log("File " + filepath + " not present in weblogic jar",
                            Project.MSG_VERBOSE);
                        rebuild = true;
                        break;
                    }
                    // File name/path match
                    // Check files see if same
                    JarEntry genericEntry = genericEntries.get(filepath);
                    JarEntry wlEntry = wlEntries.get(filepath);

                    if (genericEntry.getCrc() != wlEntry.getCrc()
                        || genericEntry.getSize() != wlEntry.getSize()) {

                        if (genericEntry.getName().endsWith(".class")) {
                            //File are different see if its an object or an interface
                            String classname = genericEntry.getName()
                                    .replace(File.separatorChar, '.')
                                    .replace('/', '.');

                            classname = classname.substring(0, classname.lastIndexOf(".class"));

                            Class<?> genclass = genericLoader.loadClass(classname);

                            if (genclass.isInterface()) {
                                //Interface changed   rebuild jar.
                                log("Interface " + genclass.getName()
                                    + " has changed", Project.MSG_VERBOSE);
                                rebuild = true;
                                break;
                            }
                            //Object class Changed   update it.
                            replaceEntries.put(filepath, genericEntry);
                        } else if (!genericEntry.getName().equals("META-INF/MANIFEST.MF")) {
                            // it is not the manifest, otherwise we'd ignore it
                            // File other then class changed   rebuild
                            log("Non class file " + genericEntry.getName()
                                + " has changed", Project.MSG_VERBOSE);
                            rebuild = true;
                            break;
                        }
                    }
                }

                if (!rebuild) {
                    log("No rebuild needed - updating jar", Project.MSG_VERBOSE);
                    newWLJarFile = new File(weblogicJarFile.getAbsolutePath() + ".temp");
                    if (newWLJarFile.exists()) {
                        newWLJarFile.delete();
                    }

                    newJarStream = new JarOutputStream(Files.newOutputStream(newWLJarFile.toPath()));
                    newJarStream.setLevel(0);

                    // Copy files from old WebLogic jar
                    for (JarEntry je : wlEntries.values()) {
                        if (je.getCompressedSize() == -1
                            || je.getCompressedSize() == je.getSize()) {
                            newJarStream.setLevel(0);
                        } else {
                            newJarStream.setLevel(JAR_COMPRESS_LEVEL);
                        }

                        InputStream is;
                        // Update with changed Bean class
                        if (replaceEntries.containsKey(je.getName())) {
                            log("Updating Bean class from generic Jar "
                                + je.getName(), Project.MSG_VERBOSE);
                            // Use the entry from the generic jar
                            je = replaceEntries.get(je.getName());
                            is = genericJar.getInputStream(je);
                        } else {
                            //use file from original WebLogic jar

                            is = wlJar.getInputStream(je);
                        }
                        newJarStream.putNextEntry(new JarEntry(je.getName()));

                        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
                        int bytesRead;
                        while ((bytesRead = is.read(buffer)) != -1) {
                            newJarStream.write(buffer, 0, bytesRead);
                        }
                        is.close();
                    }
                } else {
                    log("Weblogic Jar rebuild needed due to changed "
                         + "interface or XML", Project.MSG_VERBOSE);
                }
            } else {
                rebuild = true;
            }
        } catch (ClassNotFoundException cnfe) {
            String cnfmsg = "ClassNotFoundException while processing ejb-jar file"
                 + ". Details: "
                 + cnfe.getMessage();

            throw new BuildException(cnfmsg, cnfe);
        } catch (IOException ioe) {
            String msg = "IOException while processing ejb-jar file "
                 + ". Details: "
                 + ioe.getMessage();

            throw new BuildException(msg, ioe);
        } finally {
            FileUtils.close(genericJar);
            FileUtils.close(wlJar);
            FileUtils.close(newJarStream);

            if (newJarStream != null) {
                try {
                    FILE_UTILS.rename(newWLJarFile, weblogicJarFile);
                } catch (IOException renameException) {
                    log(renameException.getMessage(), Project.MSG_WARN);
                    rebuild = true;
                }
            }
            if (genericLoader instanceof AntClassLoader) {
                @SuppressWarnings("resource")
                AntClassLoader loader = (AntClassLoader) genericLoader;
                loader.cleanup();
            }
        }
        return rebuild;
    }