net.sf.jacclog.service.analyzer.internal.LogEntryAnalyzer.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.jacclog.service.analyzer.internal.LogEntryAnalyzer.java

Source

/*******************************************************************************
 * Copyright 2011 Andr Roul
 * 
 * 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.service.analyzer.internal;

import java.util.ArrayList;
import java.util.List;

import jsr166y.ForkJoinPool;
import net.sf.jacclog.api.LogEntryService;
import net.sf.jacclog.api.domain.ReadableLogEntry;
import net.sf.jacclog.api.domain.http.ReadableHttpRequestHeaderField;
import net.sf.jacclog.api.domain.http.ReadableHttpResponseHeaderField;
import net.sf.jacclog.service.analyzer.LogEntryAnalysisResult;
import net.sf.jacclog.service.analyzer.internal.task.AnalysisByEntriesTask;
import net.sf.jacclog.service.analyzer.internal.task.AnalysisByIntervalTask;
import net.sf.jacclog.uasparser.UserAgentStringParser;

import org.joda.time.Interval;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogEntryAnalyzer implements net.sf.jacclog.service.analyzer.LogEntryAnalyzer {

    private static final Logger LOG = LoggerFactory.getLogger(LogEntryAnalyzer.class);

    protected static final int THREADS = Runtime.getRuntime().availableProcessors();

    /**
     * Casts a <code>long</code> to an <code>int</code> if the value not smaller than {@link Integer.MIN_VALUE} or
     * greater than {@link Integer.MAX_VALUE}.
     * 
     * @param longValue
     * @throws IllegalArgumentException
     *             If the given <code>long</code> is smaller than {@link Integer.MIN_VALUE} or greater than
     *             {@link Integer.MAX_VALUE}
     * @return An <code>int</code>
     */
    private static int castLongToInt(final long longValue) {
        if (longValue < Integer.MIN_VALUE || longValue > Integer.MAX_VALUE) {
            throw new IllegalArgumentException(
                    "Cannot cast '" + longValue + "' to int without changing its value.");
        }
        return (int) longValue;
    }

    private final LogEntryAnalysisResult.Builder builder = new LogEntryAnalysisResult.Builder();

    private final UserAgentStringParser parser;

    private final LogEntryService<ReadableLogEntry<ReadableHttpRequestHeaderField, ReadableHttpResponseHeaderField>> service;

    public LogEntryAnalyzer(
            final LogEntryService<ReadableLogEntry<ReadableHttpRequestHeaderField, ReadableHttpResponseHeaderField>> service,
            final UserAgentStringParser parser) {
        if (service == null) {
            throw new IllegalArgumentException("Argument 'service' can not be null.");
        }

        if (parser == null) {
            throw new IllegalArgumentException("Argument 'parser' can not be null.");
        }

        this.service = service;
        this.parser = parser;
    }

    @Override
    public LogEntryAnalyzer analyze(final Interval interval) {
        validateInterval(interval);

        // Number of log entries to be analyzed
        final int count = castLongToInt(service.count(interval));

        final AnalysisByIntervalTask analyzer = new AnalysisByIntervalTask(service, parser, builder, interval, 0,
                count);
        final ForkJoinPool pool = new ForkJoinPool(THREADS);
        pool.invoke(analyzer);

        LOG.info("Done. Analyzed: " + count);
        return this;
    }

    @Override
    public LogEntryAnalyzer analyze(
            final List<ReadableLogEntry<ReadableHttpRequestHeaderField, ReadableHttpResponseHeaderField>> entries) {
        if (entries == null) {
            throw new IllegalArgumentException("Argument 'entries' can not be null.");
        }

        final AnalysisByEntriesTask analyzer = new AnalysisByEntriesTask(entries, parser, builder, 0,
                entries.size());
        final ForkJoinPool pool = new ForkJoinPool(THREADS);
        pool.invoke(analyzer);

        LOG.info("Done. Analyzed: " + entries.size());
        return this;
    }

    @Override
    public LogEntryAnalyzer analyze(
            final ReadableLogEntry<ReadableHttpRequestHeaderField, ReadableHttpResponseHeaderField> entry) {
        if (entry == null) {
            throw new IllegalArgumentException("Argument 'entry' can not be null.");
        }

        final List<ReadableLogEntry<ReadableHttpRequestHeaderField, ReadableHttpResponseHeaderField>> entries = new ArrayList<ReadableLogEntry<ReadableHttpRequestHeaderField, ReadableHttpResponseHeaderField>>();
        entries.add(entry);
        analyze(entries);

        return this;
    }

    public LogEntryAnalysisResult.Builder getBuilder() {
        return builder;
    }

    public UserAgentStringParser getParser() {
        return parser;
    }

    public LogEntryService<ReadableLogEntry<ReadableHttpRequestHeaderField, ReadableHttpResponseHeaderField>> getService() {
        return service;
    }

    @Override
    public LogEntryAnalysisResult toResult() {
        return builder.build();
    }

    /**
     * Validates a time interval if it is suitable for an analysis.
     * 
     * @param interval
     *            Time interval
     */
    private void validateInterval(final Interval interval) {
        if (interval == null) {
            throw new IllegalArgumentException("Argument 'interval' can not be null.");
        }

        if (interval.getStart().isAfter(interval.getEndMillis())) {
            throw new IllegalArgumentException("The time interval specify an negative range.");
        }
    }

}