4
\$\begingroup\$

Currently I am working on some kind of mechanism which will be able to monitor directory and when file with extension .pdf appears I need to mock some kind of processing on this file. Let's say, renaming and creating log file with the information of this processing. And as I wrote it is some kind of mock. So information which will be added to log file will be mocked/hard coded.

So what I was able to do is this:

public class FileUtils {

    private FileUtils() {}

    private static final EnumMap<ImportOption, Consumer<String>> runOnOption = new EnumMap<> (ImportOption.class);
    static {
        runOnOption.put(ImportOption.SUCCEEDED, (filePath) -> processSucceededPdfFile(filePath));
        runOnOption.put(ImportOption.FAILED, (filePath) -> processFailFile(filePath));
        runOnOption.put(ImportOption.WARNING, (filePath) -> processWarningPdfFile(filePath));
        runOnOption.put(ImportOption.ERROR_ON_MISSING_RIGHTS, (filePath) -> processErrorPdfFile(filePath));
    }


    private final static String FILE_PATH_TO_DIR = "D:\\dirTest";

    private static final String SUCCEEDED_EXTENSION = ".1.SUCCEEDED";
    private static final String UPDATING_EXTENSION = ".1.UPDATING";
    private static final String log_EXTENSION = ".1.log";

    public static void monitorDirectory(String dirLocation, ImportOption option) {

        String dirPath = FILE_PATH_TO_DIR + File.separator + dirPath;

        try {
            WatchService watchService = FileSystems.getDefault().newWatchService();

            Path path = Paths.get(dirPath);
            path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
            System.out.println("Starting monitoring: ");
            WatchKey key = watchService.take();
                for (WatchEvent<?> event : key.pollEvents()) {

                    String fileName = event.context().toString();

                    if (ispdfFile(fileName)) {

                        runOnOption.get(option).accept(fileName);
                        break;

                    }
                }
        }
        catch (IOException | InterruptedException e) {
        }
    }

    private static boolean ispdfFile(String fileName) {
        return fileName.substring(fileName.lastIndexOf('.'), fileName.length()).equals(".pdf");
    }

    private static void processFailFile(String filePath){
        Path pdfFilePath = Paths.get(filePath);
        Path updatingPath = Paths.get(filePath + UPDATING_EXTENSION);
        Path failedPath = Paths.get(filePath + SUCCEEDED_EXTENSION);


        try {
            Files.move(pdfFilePath, updatingPath);
            Files.move(updatingPath, failedPath);
        }
        catch (IOException e) {
        }
    }

    private static void processSucceededpdfFile(String filePath){
        Path pdfFilePath = Paths.get(filePath);
        Path updatingPath = Paths.get(filePath + UPDATING_EXTENSION);
        Path logPath = Paths.get(filePath + LOG_EXTENSION);
        Path succeededPath = Paths.get(filePath + SUCCEEDED_EXTENSION);


        try {
            Files.move(pdfFilePath, updatingPath);
            Files.move(updatingPath, succeededPath);
            Files.createFile(logPath);
            Files.write(logPath, LogFileContent.SUCCEEDED_LOG_CONTENT.getBytes());
        }
        catch (IOException e) {
        }

    }

    private static void processErrorpdfFile(String filePath){
        Path pdfFilePath = Paths.get(filePath);
        Path updatingGPath = Paths.get(filePath + UPDATING_EXTENSION);
        Path logPath = Paths.get(filePath + LOG_EXTENSION);
        Path succeededPath = Paths.get(filePath + SUCCEEDED_EXTENSION);

        try {
            Files.move(pdfFilePath, updatingPath);
            Files.move(updatingPath, succeededPath);
            Files.createFile(logPath);
            Files.write(logPath, LogFileContent.ERROR_RIGHT_LOG_CONTENT.getBytes());
        }
        catch (Exception e) {
        }

    }

    private static void processWarningpdfFile(String filePath) {
        Path pdfFilePath = Paths.get(filePath);
        Path updatingPath = Paths.get(filePath + UPDATING_EXTENSION);
        Path logPath = Paths.get(filePath + LOG_EXTENSION);
        Path succeededPath = Paths.get(filePath + SUCCEEDED_EXTENSION);


        try {
            Files.move(pdfFilePath, updatingPath);
            Files.move(updatingGPath, succeededPath);
            Files.createFile(logPath);
            Files.write(logPath, LogFileContent.WARNING_LOG_CONTENT.getBytes());
        }
        catch (Exception e) {
        }

    }
}

So this code will be used like this:

FileUtils.monitorDirectory(dirLocation, importOption/*Enum*/);

So what I dont like? Mostly every method witch process in name. They seems to be realy similar to each others. And because it is utils/static class I am not sure how to reduce this duplicate code.

ImportOption enum in some time could contain much more options. But processing will not change much, except maybe content of log file.

If you have any other points, please go ahead with them.

\$\endgroup\$
  • \$\begingroup\$ Instantly I see try/catch blocks with no exception handling. There is a rarely a good reason to do this. \$\endgroup\$ – James Trotter Feb 6 at 13:15
  • \$\begingroup\$ @JamesTrotter Please put all criticisms and suggestions for improvements in answers. \$\endgroup\$ – 200_success Feb 6 at 20:02
6
\$\begingroup\$

Hello Suule and welcome to Codereview.

What you can do is use a strategy pattern to say what to do in each case. This will not only allow you to reuse the "process" but also to decouple the monitoring and processing code.

FileUtils.monitor(String directory, Consumer<File> action);

class LogAction implements Consumer<File> {

    private final String content;

    public LogAction(String content) {
        this.content = content;
    }

    @Override
    public void accept(File file) {
        Path logPath = Paths.get(file.getName() + LOG_EXTENSION);
        try {
            Files.write(logPath, this.content.getBytes());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

FileUtils.monitor("some/directory", new MoveAction(..).andThen(new LogAction(..));

Also note that the ispdfFile(String):boolean method can be simplified with String#endsWith(String):boolean.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.