/*******************************************************************************
* Copyright 2011 André Rouél
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package net.sf.jacclog.logformat;
import java.util.ArrayList;
import java.util.List;
import net.sf.jacclog.logformat.field.BytesReceivedField;
import net.sf.jacclog.logformat.field.BytesSendField;
import net.sf.jacclog.logformat.field.CanonicalServerNameField;
import net.sf.jacclog.logformat.field.ConnectionStatusField;
import net.sf.jacclog.logformat.field.CustomRequestTimeField;
import net.sf.jacclog.logformat.field.Field;
import net.sf.jacclog.logformat.field.FilenameField;
import net.sf.jacclog.logformat.field.HttpLastStatusField;
import net.sf.jacclog.logformat.field.HttpStatusField;
import net.sf.jacclog.logformat.field.IgnorableField;
import net.sf.jacclog.logformat.field.LocalIpAddressField;
import net.sf.jacclog.logformat.field.ProcessIdField;
import net.sf.jacclog.logformat.field.QueryStringField;
import net.sf.jacclog.logformat.field.RemoteHostField;
import net.sf.jacclog.logformat.field.RemoteIpAddressField;
import net.sf.jacclog.logformat.field.RemoteLognameField;
import net.sf.jacclog.logformat.field.RemoteUserField;
import net.sf.jacclog.logformat.field.RequestFirstLineField;
import net.sf.jacclog.logformat.field.RequestHeaderAcceptCharsetField;
import net.sf.jacclog.logformat.field.RequestHeaderAcceptEncodingField;
import net.sf.jacclog.logformat.field.RequestHeaderAcceptField;
import net.sf.jacclog.logformat.field.RequestHeaderAcceptLanguageField;
import net.sf.jacclog.logformat.field.RequestHeaderAuthorizationField;
import net.sf.jacclog.logformat.field.RequestHeaderCacheControlField;
import net.sf.jacclog.logformat.field.RequestHeaderConnectionField;
import net.sf.jacclog.logformat.field.RequestHeaderContentLengthField;
import net.sf.jacclog.logformat.field.RequestHeaderContentTypeField;
import net.sf.jacclog.logformat.field.RequestHeaderCookieField;
import net.sf.jacclog.logformat.field.RequestHeaderDateField;
import net.sf.jacclog.logformat.field.RequestHeaderExpectField;
import net.sf.jacclog.logformat.field.RequestHeaderFromField;
import net.sf.jacclog.logformat.field.RequestHeaderHostField;
import net.sf.jacclog.logformat.field.RequestHeaderIfMatchField;
import net.sf.jacclog.logformat.field.RequestHeaderIfModifiedSinceField;
import net.sf.jacclog.logformat.field.RequestHeaderIfNoneMatchField;
import net.sf.jacclog.logformat.field.RequestHeaderIfRangeField;
import net.sf.jacclog.logformat.field.RequestHeaderIfUnmodifiedSinceField;
import net.sf.jacclog.logformat.field.RequestHeaderMaxForwardsField;
import net.sf.jacclog.logformat.field.RequestHeaderPragmaField;
import net.sf.jacclog.logformat.field.RequestHeaderProxyAuthorizationField;
import net.sf.jacclog.logformat.field.RequestHeaderRangeField;
import net.sf.jacclog.logformat.field.RequestHeaderRefererField;
import net.sf.jacclog.logformat.field.RequestHeaderTeField;
import net.sf.jacclog.logformat.field.RequestHeaderUpgradeField;
import net.sf.jacclog.logformat.field.RequestHeaderUserAgentField;
import net.sf.jacclog.logformat.field.RequestHeaderViaField;
import net.sf.jacclog.logformat.field.RequestHeaderWarningField;
import net.sf.jacclog.logformat.field.RequestInMillisField;
import net.sf.jacclog.logformat.field.RequestInSecondsField;
import net.sf.jacclog.logformat.field.RequestMethodField;
import net.sf.jacclog.logformat.field.RequestProtocolField;
import net.sf.jacclog.logformat.field.RequestTimeField;
import net.sf.jacclog.logformat.field.ResponseHeaderAcceptRangesField;
import net.sf.jacclog.logformat.field.ResponseHeaderAgeField;
import net.sf.jacclog.logformat.field.ResponseHeaderAllowField;
import net.sf.jacclog.logformat.field.ResponseHeaderCacheControlField;
import net.sf.jacclog.logformat.field.ResponseHeaderConnectionField;
import net.sf.jacclog.logformat.field.ResponseHeaderContentDispositionField;
import net.sf.jacclog.logformat.field.ResponseHeaderContentEncodingField;
import net.sf.jacclog.logformat.field.ResponseHeaderContentLanguageField;
import net.sf.jacclog.logformat.field.ResponseHeaderContentLengthField;
import net.sf.jacclog.logformat.field.ResponseHeaderContentLocationField;
import net.sf.jacclog.logformat.field.ResponseHeaderContentRangeField;
import net.sf.jacclog.logformat.field.ResponseHeaderContentTypeField;
import net.sf.jacclog.logformat.field.ResponseHeaderDateField;
import net.sf.jacclog.logformat.field.ResponseHeaderEtagField;
import net.sf.jacclog.logformat.field.ResponseHeaderExpiresField;
import net.sf.jacclog.logformat.field.ResponseHeaderLastModifiedField;
import net.sf.jacclog.logformat.field.ResponseHeaderLinkField;
import net.sf.jacclog.logformat.field.ResponseHeaderLocationField;
import net.sf.jacclog.logformat.field.ResponseHeaderP3pField;
import net.sf.jacclog.logformat.field.ResponseHeaderPragmaField;
import net.sf.jacclog.logformat.field.ResponseHeaderProxyAuthenticateField;
import net.sf.jacclog.logformat.field.ResponseHeaderRefreshField;
import net.sf.jacclog.logformat.field.ResponseHeaderRetryAfterField;
import net.sf.jacclog.logformat.field.ResponseHeaderServerField;
import net.sf.jacclog.logformat.field.ResponseHeaderSetCookieField;
import net.sf.jacclog.logformat.field.ResponseHeaderStrictTransportSecurityField;
import net.sf.jacclog.logformat.field.ResponseHeaderTrailerField;
import net.sf.jacclog.logformat.field.ResponseHeaderTransferEncodingField;
import net.sf.jacclog.logformat.field.ResponseHeaderVaryField;
import net.sf.jacclog.logformat.field.ResponseHeaderViaField;
import net.sf.jacclog.logformat.field.ResponseHeaderWarningField;
import net.sf.jacclog.logformat.field.ResponseHeaderWwwAuthenticateField;
import net.sf.jacclog.logformat.field.ResponseInBytesClfField;
import net.sf.jacclog.logformat.field.ResponseInBytesField;
import net.sf.jacclog.logformat.field.ServerNameField;
import net.sf.jacclog.logformat.field.ServerPortField;
import net.sf.jacclog.logformat.field.UrlPathField;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CommonTokenStream;
public class LogFormat {
public final static class Builder {
private transient final List<Field> fields = new ArrayList<Field>();
public Builder appendBytesReceivedField() {
return appendField(BytesReceivedField.getInstance());
}
public Builder appendBytesSendField() {
return appendField(BytesSendField.getInstance());
}
public Builder appendCanonicalServerNameField() {
return appendField(CanonicalServerNameField.getInstance());
}
public Builder appendConnectionStatusField() {
return appendField(ConnectionStatusField.getInstance());
}
public Builder appendCustomRequestTimeField() {
return appendField(CustomRequestTimeField.getInstance());
}
/**
* Appends a field to list.
*
* @param field
* @return Builder (itself)
*/
public Builder appendField(final Field field) {
if (field == null) {
throw new IllegalArgumentException("Argument 'field' can not be null.");
}
fields.add(field);
return this;
}
public Builder appendFilenameField() {
return appendField(FilenameField.getInstance());
}
public Builder appendHttpLastStatusField() {
return appendField(HttpLastStatusField.getInstance());
}
public Builder appendHttpStatusField() {
return appendField(HttpStatusField.getInstance());
}
public Builder appendIgnorableField() {
return appendField(IgnorableField.getInstance());
}
public Builder appendLocalIpAddressField() {
return appendField(LocalIpAddressField.getInstance());
}
public Builder appendProcessIdField() {
return appendField(ProcessIdField.getInstance());
}
public Builder appendQueryStringField() {
return appendField(QueryStringField.getInstance());
}
public Builder appendRemoteHostField() {
return appendField(RemoteHostField.getInstance());
}
public Builder appendRemoteIpAddressField() {
return appendField(RemoteIpAddressField.getInstance());
}
public Builder appendRemoteLognameField() {
return appendField(RemoteLognameField.getInstance());
}
public Builder appendRemoteUserField() {
return appendField(RemoteUserField.getInstance());
}
public Builder appendRequestFirstLineField() {
return appendField(RequestFirstLineField.getInstance());
}
public Builder appendRequestHeaderAcceptCharsetField() {
return appendField(RequestHeaderAcceptCharsetField.getInstance());
}
public Builder appendRequestHeaderAcceptEncodingField() {
return appendField(RequestHeaderAcceptEncodingField.getInstance());
}
public Builder appendRequestHeaderAcceptField() {
return appendField(RequestHeaderAcceptField.getInstance());
}
public Builder appendRequestHeaderAcceptLanguageField() {
return appendField(RequestHeaderAcceptLanguageField.getInstance());
}
public Builder appendRequestHeaderAuthorizationField() {
return appendField(RequestHeaderAuthorizationField.getInstance());
}
public Builder appendRequestHeaderCacheControlField() {
return appendField(RequestHeaderCacheControlField.getInstance());
}
public Builder appendRequestHeaderConnectionField() {
return appendField(RequestHeaderConnectionField.getInstance());
}
public Builder appendRequestHeaderContentLengthField() {
return appendField(RequestHeaderContentLengthField.getInstance());
}
public Builder appendRequestHeaderContentTypeField() {
return appendField(RequestHeaderContentTypeField.getInstance());
}
public Builder appendRequestHeaderCookieField() {
return appendField(RequestHeaderCookieField.getInstance());
}
public Builder appendRequestHeaderDateField() {
return appendField(RequestHeaderDateField.getInstance());
}
public Builder appendRequestHeaderExpectField() {
return appendField(RequestHeaderExpectField.getInstance());
}
public Builder appendRequestHeaderFromField() {
return appendField(RequestHeaderFromField.getInstance());
}
public Builder appendRequestHeaderHostField() {
return appendField(RequestHeaderHostField.getInstance());
}
public Builder appendRequestHeaderIfMatchField() {
return appendField(RequestHeaderIfMatchField.getInstance());
}
public Builder appendRequestHeaderIfModifiedSinceField() {
return appendField(RequestHeaderIfModifiedSinceField.getInstance());
}
public Builder appendRequestHeaderIfNoneMatchField() {
return appendField(RequestHeaderIfNoneMatchField.getInstance());
}
public Builder appendRequestHeaderIfRangeField() {
return appendField(RequestHeaderIfRangeField.getInstance());
}
public Builder appendRequestHeaderIfUnmodifiedSinceField() {
return appendField(RequestHeaderIfUnmodifiedSinceField.getInstance());
}
public Builder appendRequestHeaderMaxForwardsField() {
return appendField(RequestHeaderMaxForwardsField.getInstance());
}
public Builder appendRequestHeaderPragmaField() {
return appendField(RequestHeaderPragmaField.getInstance());
}
public Builder appendRequestHeaderProxyAuthorizationField() {
return appendField(RequestHeaderProxyAuthorizationField.getInstance());
}
public Builder appendRequestHeaderRangeField() {
return appendField(RequestHeaderRangeField.getInstance());
}
public Builder appendRequestHeaderRefererField() {
return appendField(RequestHeaderRefererField.getInstance());
}
public Builder appendRequestHeaderTeField() {
return appendField(RequestHeaderTeField.getInstance());
}
public Builder appendRequestHeaderUpgradeField() {
return appendField(RequestHeaderUpgradeField.getInstance());
}
public Builder appendRequestHeaderUserAgentField() {
return appendField(RequestHeaderUserAgentField.getInstance());
}
public Builder appendRequestHeaderViaField() {
return appendField(RequestHeaderViaField.getInstance());
}
public Builder appendRequestHeaderWarningField() {
return appendField(RequestHeaderWarningField.getInstance());
}
public Builder appendRequestInMillisField() {
return appendField(RequestInMillisField.getInstance());
}
public Builder appendRequestInSecondsField() {
return appendField(RequestInSecondsField.getInstance());
}
public Builder appendRequestMethodField() {
return appendField(RequestMethodField.getInstance());
}
public Builder appendRequestProtocolField() {
return appendField(RequestProtocolField.getInstance());
}
public Builder appendRequestTimeField() {
return appendField(RequestTimeField.getInstance());
}
public Builder appendResponseHeaderAcceptRangesField() {
return appendField(ResponseHeaderAcceptRangesField.getInstance());
}
public Builder appendResponseHeaderAgeField() {
return appendField(ResponseHeaderAgeField.getInstance());
}
public Builder appendResponseHeaderAllowField() {
return appendField(ResponseHeaderAllowField.getInstance());
}
public Builder appendResponseHeaderCacheControlField() {
return appendField(ResponseHeaderCacheControlField.getInstance());
}
public Builder appendResponseHeaderConnectionField() {
return appendField(ResponseHeaderConnectionField.getInstance());
}
public Builder appendResponseHeaderContentDispositionField() {
return appendField(ResponseHeaderContentDispositionField.getInstance());
}
public Builder appendResponseHeaderContentEncodingField() {
return appendField(ResponseHeaderContentEncodingField.getInstance());
}
public Builder appendResponseHeaderContentLanguageField() {
return appendField(ResponseHeaderContentLanguageField.getInstance());
}
public Builder appendResponseHeaderContentLengthField() {
return appendField(ResponseHeaderContentLengthField.getInstance());
}
public Builder appendResponseHeaderContentLocationField() {
return appendField(ResponseHeaderContentLocationField.getInstance());
}
public Builder appendResponseHeaderContentRangeField() {
return appendField(ResponseHeaderContentRangeField.getInstance());
}
public Builder appendResponseHeaderContentTypeField() {
return appendField(ResponseHeaderContentTypeField.getInstance());
}
public Builder appendResponseHeaderDateField() {
return appendField(ResponseHeaderDateField.getInstance());
}
public Builder appendResponseHeaderEtagField() {
return appendField(ResponseHeaderEtagField.getInstance());
}
public Builder appendResponseHeaderExpiresField() {
return appendField(ResponseHeaderExpiresField.getInstance());
}
public Builder appendResponseHeaderLastModifiedField() {
return appendField(ResponseHeaderLastModifiedField.getInstance());
}
public Builder appendResponseHeaderLinkField() {
return appendField(ResponseHeaderLinkField.getInstance());
}
public Builder appendResponseHeaderLocationField() {
return appendField(ResponseHeaderLocationField.getInstance());
}
public Builder appendResponseHeaderP3pField() {
return appendField(ResponseHeaderP3pField.getInstance());
}
public Builder appendResponseHeaderPragmaField() {
return appendField(ResponseHeaderPragmaField.getInstance());
}
public Builder appendResponseHeaderProxyAuthenticateField() {
return appendField(ResponseHeaderProxyAuthenticateField.getInstance());
}
public Builder appendResponseHeaderRefreshField() {
return appendField(ResponseHeaderRefreshField.getInstance());
}
public Builder appendResponseHeaderRetryAfterField() {
return appendField(ResponseHeaderRetryAfterField.getInstance());
}
public Builder appendResponseHeaderServerField() {
return appendField(ResponseHeaderServerField.getInstance());
}
public Builder appendResponseHeaderSetCookieField() {
return appendField(ResponseHeaderSetCookieField.getInstance());
}
public Builder appendResponseHeaderStrictTransportSecurityField() {
return appendField(ResponseHeaderStrictTransportSecurityField.getInstance());
}
public Builder appendResponseHeaderTrailerField() {
return appendField(ResponseHeaderTrailerField.getInstance());
}
public Builder appendResponseHeaderTransferEncodingField() {
return appendField(ResponseHeaderTransferEncodingField.getInstance());
}
public Builder appendResponseHeaderVaryField() {
return appendField(ResponseHeaderVaryField.getInstance());
}
public Builder appendResponseHeaderViaField() {
return appendField(ResponseHeaderViaField.getInstance());
}
public Builder appendResponseHeaderWarningField() {
return appendField(ResponseHeaderWarningField.getInstance());
}
public Builder appendResponseHeaderWwwAuthenticateField() {
return appendField(ResponseHeaderWwwAuthenticateField.getInstance());
}
public Builder appendResponseInBytesClfField() {
return appendField(ResponseInBytesClfField.getInstance());
}
public Builder appendResponseInBytesField() {
return appendField(ResponseInBytesField.getInstance());
}
public Builder appendServerNameField() {
return appendField(ServerNameField.getInstance());
}
public Builder appendServerPortField() {
return appendField(ServerPortField.getInstance());
}
public Builder appendUrlPathField() {
return appendField(UrlPathField.getInstance());
}
public LogFormat build() {
return new LogFormat(fields);
}
}
public static enum Defaults {
/**
* NCSA extended/combined log format<br>
* <br>
* Format string: <code>%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i"</code>
*/
COMBINED(new LogFormat.Builder().appendRemoteHostField().appendRemoteLognameField().appendRemoteUserField()
.appendRequestTimeField().appendRequestFirstLineField().appendHttpLastStatusField()
.appendResponseInBytesClfField().appendRequestHeaderRefererField().appendRequestHeaderUserAgentField()
.build()),
/**
* Common Log Format (CLF)<br>
* <br>
* Format string: <code>%h %l %u %t "%r" %>s %b</code>
*/
COMMON(new LogFormat.Builder().appendRemoteHostField().appendRemoteLognameField().appendRemoteUserField()
.appendRequestTimeField().appendRequestFirstLineField().appendHttpLastStatusField()
.appendResponseInBytesClfField().build()),
/**
* Common Log Format with Virtual Host<br>
* <br>
* Format string: <code>%v %h %l %u %t "%r" %>s %b</code>
*/
COMMON_WITH_VHOST(new LogFormat.Builder().appendCanonicalServerNameField().appendRemoteHostField()
.appendRemoteLognameField().appendRemoteUserField().appendRequestTimeField()
.appendRequestFirstLineField().appendHttpLastStatusField().appendResponseInBytesClfField().build());
private LogFormat format;
Defaults(final LogFormat format) {
this.format = format;
}
public LogFormat getFormat() {
return format;
}
}
/**
* Parses a format string and returns an object of type <code>LogFormat</code>.<br>
* <br>
* If the format string can not be read <code>null</code> will be returned.
*
* @param format
* @return
* @throws IllegalArgumentException
* if the given argument is <code>null</code>
* @throws LogFormatParsingException
* if the given log format can not be parsed
*/
public static LogFormat parse(final String format) {
if (format == null) {
throw new IllegalArgumentException("Argument 'format' can not be null.");
}
LogFormat result = null;
if (format.equalsIgnoreCase("COMMON")) {
result = Defaults.COMMON.getFormat();
} else if (format.equalsIgnoreCase("COMMON_WITH_VHOST")) {
result = Defaults.COMMON_WITH_VHOST.getFormat();
} else if (format.equalsIgnoreCase("COMBINED")) {
result = Defaults.COMBINED.getFormat();
} else {
final ANTLRStringStream input = new ANTLRStringStream(format);
final LogFormatLexer lexer = new LogFormatLexer(input);
final CommonTokenStream tokens = new CommonTokenStream(lexer);
final LogFormatParser parser = new LogFormatParser(tokens);
try {
result = parser.format();
} catch (final Exception e) {
throw new LogFormatParsingException("The format '" + format + "' is not valid.", e);
}
}
return result;
}
private final List<Field> fields;
private LogFormat(final List<Field> fields) {
if (fields == null || fields.isEmpty()) {
throw new IllegalArgumentException("Argument 'fields' can not be null or empty.");
}
this.fields = fields;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final LogFormat other = (LogFormat) obj;
if (fields == null) {
if (other.fields != null) {
return false;
}
} else if (!fields.equals(other.fields)) {
return false;
}
return true;
}
/**
* Gets a copied list of fields.
*
* @return a copied field list
*/
public List<Field> getFields() {
return new ArrayList<Field>(fields);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((fields == null) ? 0 : fields.hashCode());
return result;
}
}