@@ -0,0 +1,3555 @@
+package gq.baijie.catalog.usecase;%0A%0Aimport java.io.IOException;%0Aimport java.security.MessageDigest;%0Aimport java.util.EnumMap;%0Aimport java.util.List;%0Aimport java.util.Map;%0A%0Aimport javax.annotation.Nonnull;%0A%0Aimport gq.baijie.catalog.entity.DirectoryFile;%0Aimport gq.baijie.catalog.entity.File;%0Aimport gq.baijie.catalog.entity.Hash;%0Aimport gq.baijie.catalog.entity.RegularFile;%0A%0Apublic class CheckFileInformation implements UseCase %7B%0A%0A    @Nonnull%0A    private final DirectoryFile rootDirectoryFile;%0A%0A    @Nonnull%0A    private final FileCheckerListener fileCheckerListener;%0A%0A    public CheckFileInformation(%0A            @Nonnull DirectoryFile rootDirectoryFile,%0A            @Nonnull FileCheckerListener fileCheckerListener%0A    ) %7B%0A        this.rootDirectoryFile = rootDirectoryFile;%0A        this.fileCheckerListener = fileCheckerListener;%0A    %7D%0A%0A    @Override%0A    public void execute() %7B%0A        checkFiles();%0A    %7D%0A%0A    private void checkFiles() %7B%0A        final EnumMap%3CHash.Algorithm, MessageDigest%3E messageDigestCache =%0A                new EnumMap%3C%3E(Hash.Algorithm.class);%0A        checkFiles(rootDirectoryFile, messageDigestCache);%0A    %7D%0A%0A    @Nonnull%0A    private CheckResult checkFiles(%0A            @Nonnull DirectoryFile directory,%0A            @Nonnull Map%3CHash.Algorithm, MessageDigest%3E messageDigestCache%0A    ) %7B%0A        CheckResult result = CheckResult.CONTINUE;%0A        for (final File file : directory.getContent()) %7B%0A            if (file instanceof DirectoryFile) %7B%0A                result = checkFiles((DirectoryFile) file, messageDigestCache);%0A            %7D else if (file instanceof RegularFile) %7B%0A                result = checkFile((RegularFile) file, messageDigestCache);%0A            %7D else %7B%0A                throw new UnsupportedOperationException(%22unknown instance of File:%22 + file);%0A            %7D%0A            if (result == CheckResult.TERMINATE) %7B%0A                break;%0A            %7D%0A        %7D%0A        return result;%0A    %7D%0A%0A    @Nonnull%0A    private CheckResult checkFile(%0A            @Nonnull final RegularFile file,%0A            @Nonnull Map%3CHash.Algorithm, MessageDigest%3E messageDigestCache%0A    ) %7B%0A        List%3CHash%3E fileHashs = file.getHashs();%0A        final Hash%5B%5D hashResultContainer = new Hash%5BfileHashs.size()%5D;%0A        final Hash.Algorithm%5B%5D algorithms = new Hash.Algorithm%5BfileHashs.size()%5D;%0A        int count = 0;%0A        for (Hash hash : fileHashs) %7B%0A            algorithms%5Bcount++%5D = hash.getAlgorithm();%0A        %7D%0A        try %7B%0A            new HashFile(file.getPath(), algorithms, messageDigestCache, hashResultContainer)%0A                    .execute();%0A        %7D catch (RuntimeException e) %7B%0A            if (e.getCause() instanceof IOException) %7B%0A                return fileCheckerListener.onCheckFileFailed(file, (IOException) e.getCause());%0A            %7D else %7B%0A                throw e;%0A            %7D%0A        %7D%0A        return fileCheckerListener.onFileChecked(file, hashResultContainer);%0A    %7D%0A%0A%0A    public static interface FileCheckerListener %7B%0A%0A        @Nonnull%0A        public CheckResult onCheckFileFailed(RegularFile file, IOException exception);%0A%0A        /**%0A         * called after the file is checked%0A         *%0A         * @param file      the file on check%0A         * @param realHashs current hash value of the file on the file system.%0A         *                  Its order is same to the order of %7B@code file.getHashs()%7D%0A         */%0A        @Nonnull%0A        public CheckResult onFileChecked(RegularFile file, Hash%5B%5D realHashs);%0A%0A    %7D%0A%0A    public static enum CheckResult %7B%0A        CONTINUE,%0A        TERMINATE%0A    %7D%0A%0A%7D%0A

add CheckFileInformation Use Case