Completed
Branch master (7277eb)
by Zaahid
02:51
created

setVerbose(boolean[])   A

Complexity

Conditions 2

Size

Total Lines 8
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 8
c 0
b 0
f 0
dl 0
loc 8
ccs 0
cts 5
cp 0
crap 6
rs 10
1
/*
2
 * Copyright 2014-2018, Armenak Grigoryan, and individual contributors as indicated
3
 * by the @authors tag. See the copyright.txt in the distribution for a
4
 * full listing of individual contributors.
5
 *
6
 * This is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU Lesser General Public License as
8
 * published by the Free Software Foundation; either version 2.1 of
9
 * the License, or (at your option) any later version.
10
 *
11
 * This software is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
 * Lesser General Public License for more details.
15
 */
16
package com.strider.datadefender;
17
18
import com.strider.datadefender.discoverer.Discoverer;
19
import com.strider.datadefender.requirement.Requirement;
20
import com.strider.datadefender.requirement.file.Loader;
21
22
import java.io.FileNotFoundException;
23
import java.io.PrintWriter;
24
import java.util.concurrent.Callable;
25
import java.util.stream.Collectors;
26
27
import org.apache.commons.lang3.StringUtils;
28
import org.apache.logging.log4j.ThreadContext;
29
30
import picocli.CommandLine;
31
import picocli.CommandLine.Command;
32
import picocli.CommandLine.HelpCommand;
33
import picocli.CommandLine.IParameterExceptionHandler;
34
import picocli.CommandLine.Model.CommandSpec;
35
import picocli.CommandLine.ParameterException;
36
import picocli.CommandLine.ScopeType;
37
import picocli.CommandLine.TypeConversionException;
38
import picocli.CommandLine.UnmatchedArgumentException;
39
40
import lombok.extern.log4j.Log4j2;
41
42
/**
43
 * Entry point to Data Defender.
44
 *
45
 * This class will parse and analyze the parameters and execute appropriate
46
 * service.
47
 *
48
 * @author Zaahid Bateson
49
 */
50
@Command(
51
    name = "datadefender",
52
    mixinStandardHelpOptions = true,
53
    version = "2.0.1",
54
    description = "Data detection and anonymization tool",
55
    synopsisSubcommandLabel = "COMMAND",
56
    subcommands = {
57
        HelpCommand.class,
58
        Anonymize.class,
59
        Extract.class,
60
        Discover.class
61
    }
62
)
63
@Log4j2
64
public class DataDefender implements Callable<Integer> {
65
66
    // initializing system property used by ModelDiscoveryConfig option parameter help
67
    static {
68
        System.setProperty("AVAILABLE-MODELS", StringUtils.join(
69
            Discoverer.BUILT_IN_MODELS.keySet().stream().sorted().collect(Collectors.toList()),
70
            ", "
71
        ));
72
    }
73
74
    @CommandLine.Option(names = "--debug", description = "Enable debug logging in log file", scope = ScopeType.INHERIT)
75
    public void setDebug(boolean debug) {
76
        System.out.println("DEBUG file logging turned on.");
77
        ThreadContext.put("file-level", "debug");
78
        log.warn("Private/sensitive data that should be anonymized will be "
79
            + "logged to configured debug output streams.");
80
    }
81
82
    @CommandLine.Option(names = { "-v", "--verbose" }, description = "Enable more verbose console output, specify two -v for console debug logging", scope = ScopeType.INHERIT)
83
    public void setVerbose(boolean[] verbosity) {
84
        if (verbosity.length < 2) {
85
            ThreadContext.put("console-level", "info");
86
        } else {
87
            ThreadContext.put("console-level", "debug");
88
            log.warn("Private/sensitive data that should be anonymized will be "
89
                + "logged to the console in this mode.");
90
        }
91
    }
92
93
    /**
94
     * Copied from picocli documentation, presents a shorter "Usage" help when
95
     * there's an error in the options/arguments.
96
     *
97
     * https://picocli.info
98
     */
99
    public static class ShortErrorMessageHandler implements IParameterExceptionHandler {
100
101
        public int handleParseException(ParameterException ex, String[] args) {
102
            CommandLine cmd = ex.getCommandLine();
103
            PrintWriter writer = cmd.getErr();
104
105
            writer.println(ex.getMessage());
106
            UnmatchedArgumentException.printSuggestions(ex, writer);
107
            writer.print(cmd.getHelp().fullSynopsis()); // since 4.1
108
109
            CommandSpec spec = cmd.getCommandSpec();
110
            writer.printf("Try '%s --help' for more information.%n", spec.qualifiedName());
111
112
            return cmd.getExitCodeExceptionMapper() != null
113
                        ? cmd.getExitCodeExceptionMapper().getExitCode(ex)
114
                        : spec.exitCodeOnInvalidInput();
115
        }
116
    }
117
118
    public static class RequirementConverter implements CommandLine.ITypeConverter<Requirement> {
119
        public Requirement convert(String value) throws Exception {
120
            Loader loader = new Loader();
121
            try {
122
                return loader.load(value);
123
            } catch (FileNotFoundException e) {
124
                log.debug("Error loading requirements file", e);
125
                throw new TypeConversionException("Unable to load requirements file: " + e.getMessage());
126
            } catch (Exception e) {
127
                Throwable exc = e;
128
                if (StringUtils.isBlank(e.getMessage()) && e.getCause() != null) {
129
                    exc = e.getCause();
130
                }
131
                log.debug("Error loading requirements.", exc);
132
                throw new TypeConversionException("Unable to load requirements file: " + exc.getMessage());
133
            }
134
        }
135
    }
136
137
    @Override
138
    public Integer call() throws Exception {
139
        CommandLine.usage(this, System.out);
140
        return 0;
141
    }
142
143
    public static void main(String... args) throws Exception {
144
145
        ThreadContext.put("console-level", "");
146
        ThreadContext.put("file-level", "");
147
148
        CommandLine cmd = new CommandLine(new DataDefender())
149
            .registerConverter(Requirement.class, new RequirementConverter())
150
            .setParameterExceptionHandler(new ShortErrorMessageHandler());
151
        int exitCode = cmd.execute(args);
152
        System.exit(exitCode);
153
    }
154
}
155