package fr.yunes; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * The <code>AccessEntry</code> class represents entries of Apache access.log files. * This is a primitive implementation of what is expected. * Thus, this is not for real life usage, only for training purpose. * * @version 1.0 * @author yunes */ public class AccessEntry { private String address; private ZonedDateTime date; private String request; private String url; private String proto; private int code = -1; private int length = -1; private String referer; private UserAgent userAgent; private boolean state = true; private String text; private final String regex = "^(\\S+) (\\S+) (\\S+) " + "\\[([\\w:/]+\\s[+\\-]\\d{4})\\] \"(\\S+)" + " (\\S+)\\s*(\\S+)?\\s*\" (\\d{3}) (\\S+) \"(\\S+)\" \"([^\"]*)\" \"(.*)\""; private final Pattern pattern = Pattern.compile(regex); /** * Constructs a new <code>AccessEntry</code> from a given <code>String</code>. * Strings must roughly be in Apache custom log format, <em>i.e.:</em><br> * <pre>109.184.11.34 - - [12/Dec/2015:18:32:56 +0100] "GET /administrator/ HTTP/1.1" 200 4263 "-" "Mozilla/5.0 (Windows NT 6.0; rv:34.0) Gecko/20100101 Firefox/34.0" "-"</pre> * If the string can't be parsed, the object is in incorrect state and the string is stored in the text property. * * @param line the string to be parsed. */ public AccessEntry(String line) { final Matcher matcher = pattern.matcher(line); if (matcher.find()) { address = matcher.group(1); String d = matcher.group(4); DateTimeFormatter format = DateTimeFormatter.ofPattern("dd/MMM/uuuu:HH:mm:ss Z", Locale.ENGLISH); date = ZonedDateTime.parse(d,format); request = matcher.group(5); url = matcher.group(6); proto = matcher.group(7); try { code = Integer.parseInt(matcher.group(8)); } catch(NumberFormatException e) {} try { length = Integer.parseInt(matcher.group(9)); } catch(NumberFormatException e) {} referer = matcher.group(10); userAgent = new UserAgent(matcher.group(11)); } else { state = false; text = line; } } public String getProto() { return proto; } public int getCode() { return code; } public String getRequest() { return request; } public String getURL() { return url; } public boolean isCorrect() { return state; } public UserAgent getUserAgent() { return userAgent; } public ZonedDateTime getDate() { return date; } public int getLength() { return length; } public String getText() { return text; } public String toString() { if (state) { return "IP=" + address + ", Date=" + date + ", Request=" + request + ", URL=" + url + ", Proto=" + proto + ", Code=" + code + ", Length=" + length + ", UserAgent" + userAgent ; } return "Bad ("+text+")"; } }