001// Generated by delombok at Sat May 11 08:17:52 CEST 2019
002package com.credibledoc.substitution.doc.module.substitution;
003
004import com.credibledoc.combiner.date.DateService;
005import com.credibledoc.combiner.log.buffered.LogBufferedReader;
006import com.credibledoc.combiner.log.buffered.LogFileReader;
007import com.credibledoc.combiner.node.file.NodeFile;
008import com.credibledoc.combiner.tactic.Tactic;
009import com.credibledoc.substitution.core.exception.SubstitutionRuntimeException;
010import com.credibledoc.substitution.doc.module.substitution.application.Substitution;
011import org.springframework.stereotype.Service;
012import javax.inject.Inject;
013import java.io.File;
014import java.text.SimpleDateFormat;
015import java.util.Date;
016import java.util.regex.Matcher;
017import java.util.regex.Pattern;
018
019/**
020 * Implementation of the {@link Tactic}
021
022 * for the {@link Substitution}.
023 */
024@Service
025public class SubstitutionTactic implements Tactic {
026    /**
027     * RegEx of a date in a {@link Substitution} log line,
028
029     * for example <pre>29.09.2018 22:53:42.494|https-jsse-nio-15443-exec-1...</pre>
030     */
031    private static final String PATTERN_DATE_STRING = "\\d\\d\\.\\d\\d\\.\\d\\d\\d\\d\\s\\d\\d:\\d\\d:\\d\\d\\.\\d\\d\\d";
032    /**
033     * Compiled {@value #PATTERN_DATE_STRING} value
034     */
035    private static final Pattern PATTERN_DATE = Pattern.compile(PATTERN_DATE_STRING);
036    /**
037     * {@link Pattern} of date and time of {@link Substitution}, for example
038
039     * for example <pre>29.09.2018 22:53:42.494|https-jsse-nio-15443-exec-1...</pre>
040     */
041    private static final String DATE_FORMAT_STRING = "dd.MM.yyyy HH:mm:ss.SSS";
042    private static final String ONE_SPACE = " ";
043    private static final int THREAD_NAME_INDEX = 35;
044    private static final String PIPE = "|";
045    private final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT_STRING);
046
047    @Override
048    public Date findDate(File file) {
049        try (LogBufferedReader logBufferedReader = new LogBufferedReader(new LogFileReader(file))) {
050            String line = logBufferedReader.readLine();
051            while (line != null) {
052                Date date = parseDateFromLine(line);
053                if (date != null) {
054                    return date;
055                }
056                line = logBufferedReader.readLine();
057            }
058            return null;
059        } catch (Exception e) {
060            throw new SubstitutionRuntimeException("Cannot find date. File: " + file.getAbsolutePath(), e);
061        }
062    }
063
064    @Override
065    public Date findDate(String line, NodeFile nodeFile) {
066        return parseDateFromLine(line);
067    }
068
069    @Override
070    public boolean containsDate(String line) {
071        if (line == null) {
072            return false;
073        }
074        return PATTERN_DATE.matcher(line).find();
075    }
076
077    @Override
078    public String parseDateStingFromLine(String line) {
079        if (line == null) {
080            return null;
081        }
082        return findDateString(line);
083    }
084
085    /**
086     * Parse a {@link Date} from a log line.
087
088     *
089
090     * @param line    for example
091
092     *                <pre>29.09.2018 22:53:42.494|https-jsse-nio-15443-exec-1...</pre>
093
094     *                for {@link Substitution}
095
096     * @return a parsed {@link Date}, for example 13.04.2018 07:27:41.462
097
098     * or 'null' if the line is null or the date cannot be found.
099     */
100    private Date parseDateFromLine(String line) {
101        if (line == null) {
102            return null;
103        }
104        try {
105            String clientDateString = findDateString(line);
106            if (clientDateString != null) {
107                return simpleDateFormat.parse(clientDateString);
108            }
109            return null;
110        } catch (Exception e) {
111            throw new SubstitutionRuntimeException("Cannot parse a date from the line: " + line, e);
112        }
113    }
114
115    /**
116     * Parse a {@link Date} from a log line.
117
118     *
119
120     * @param line for example
121
122     * <pre>29.09.2018 22:53:42.494|https-jsse-nio-15443-exec-1...</pre>
123
124     * for {@link Substitution}
125
126     * @return a parsed {@link Date}, for example 13.04.2018 07:27:41.462 or 'null' if the line is 'null' or the date cannot be found.
127     */
128    private String findDateString(String line) {
129        int maxLength = line.length() > 90 ? 90 : line.length();
130        String dateString = null;
131        Matcher matcher = PATTERN_DATE.matcher(line.substring(0, maxLength));
132        if (matcher.find()) {
133            dateString = matcher.group();
134        }
135        return dateString;
136    }
137
138    /**
139     * Examples:
140
141     * <pre>05.11.2018 08:37:08.100|https-jsse-nio-15443-exec-10|DEBUG|...</pre>
142
143     * <pre>19.12.2018 06:17:56.761 http-nio-8080-exec-305 INFO  [1212121]...</pre>
144     */
145    @Override
146    public String findThreadName(String line) {
147        int beginIndex = line.indexOf(PIPE);
148        int endIndex = line.indexOf(PIPE, beginIndex + 1);
149        if (isPipeSeparator(line)) {
150            if (beginIndex != -1 && endIndex != -1) {
151                return line.substring(beginIndex + PIPE.length(), endIndex);
152            }
153        } else {
154            int firstSpaceIndex = line.indexOf(ONE_SPACE);
155            int secondSpaceIndex = line.indexOf(ONE_SPACE, firstSpaceIndex + 1);
156            int thirdSpaceIndex = line.indexOf(ONE_SPACE, secondSpaceIndex + 1);
157            return line.substring(secondSpaceIndex + 1, thirdSpaceIndex);
158        }
159        return null;
160    }
161
162    private boolean isPipeSeparator(String line) {
163        return line.substring(0, THREAD_NAME_INDEX).contains(PIPE);
164    }
165
166    @Override
167    public Date findDate(String line) {
168        return DateService.getInstance().parseDateTimeFromLine(line, simpleDateFormat, PATTERN_DATE, 35);
169    }
170
171    @Inject
172    @java.lang.SuppressWarnings("all")
173    public SubstitutionTactic() {
174    }
175}