protected boolean isRebuildRequired()

in src/main/org/apache/tools/ant/taskdefs/optional/ejb/WebsphereDeploymentTool.java [651:809]


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

        JarFile genericJar = null;
        JarFile wasJar = null;
        File newwasJarFile = null;
        JarOutputStream newJarStream = null;
        ClassLoader genericLoader = null;

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

                //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 WebSphere jar entries
                Map<String, JarEntry> wasEntries = wasJar.stream()
                        .collect(Collectors.toMap(ZipEntry::getName, je -> je, (a, b) -> b));

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

                Map<String, JarEntry> replaceEntries = new HashMap<>();
                for (String filepath : genericEntries.keySet()) {
                    if (!wasEntries.containsKey(filepath)) {
                        // a file doesn't exist rebuild
                        log("File " + filepath + " not present in websphere jar",
                            Project.MSG_VERBOSE);
                        rebuild = true;
                        break;
                    }
                    // File name/path match
                    // Check files see if same
                    JarEntry genericEntry = genericEntries.get(filepath);
                    JarEntry wasEntry = wasEntries.get(filepath);

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

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

                            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 {
                            // is it the manifest. If so ignore it
                            if (!genericEntry.getName().equals("META-INF/MANIFEST.MF")) {
                                //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);
                    newwasJarFile = new File(websphereJarFile.getAbsolutePath() + ".temp");
                    if (newwasJarFile.exists()) {
                        newwasJarFile.delete();
                    }

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

                    // Copy files from old WebSphere jar
                    for (JarEntry je : wasEntries.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 fle from original WebSphere jar

                            is = wasJar.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("websphere Jar rebuild needed due to changed "
                        + "interface or XML", Project.MSG_VERBOSE);
                }
            } else {
                rebuild = true;
            }
        } catch (ClassNotFoundException cnfe) {
            throw new BuildException(
                "ClassNotFoundException while processing ejb-jar file. Details: "
                    + cnfe.getMessage(),
                cnfe);
        } catch (IOException ioe) {
            throw new BuildException(
                "IOException while processing ejb-jar file . Details: "
                    + ioe.getMessage(),
                ioe);
        } finally {
            // need to close files and perhaps rename output
            FileUtils.close(genericJar);
            FileUtils.close(wasJar);
            FileUtils.close(newJarStream);

            if (newJarStream != null) {
                try {
                    FILE_UTILS.rename(newwasJarFile, websphereJarFile);
                } 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;
    }