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+")";
}
}