com.subgraph.vega.internal.model.requests.RequestLog.java Source code

Java tutorial

Introduction

Here is the source code for com.subgraph.vega.internal.model.requests.RequestLog.java

Source

/*******************************************************************************
 * Copyright (c) 2011 Subgraph.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Subgraph - initial API and implementation
 ******************************************************************************/
package com.subgraph.vega.internal.model.requests;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;

import com.db4o.ObjectContainer;
import com.db4o.events.Event4;
import com.db4o.events.EventListener4;
import com.db4o.events.EventRegistry;
import com.db4o.events.EventRegistryFactory;
import com.db4o.events.ObjectInfoEventArgs;
import com.db4o.query.Predicate;
import com.db4o.query.Query;
import com.subgraph.vega.api.http.requests.IHttpResponse;
import com.subgraph.vega.api.model.conditions.IHttpConditionSet;
import com.subgraph.vega.api.model.requests.IRequestLog;
import com.subgraph.vega.api.model.requests.IRequestLogRecord;
import com.subgraph.vega.api.model.requests.IRequestLogUpdateListener;
import com.subgraph.vega.internal.model.conditions.HttpConditionSet;

public class RequestLog implements IRequestLog {
    private final ObjectContainer database;
    private final RequestLogId requestLogId;
    private final HttpMessageCloner cloner;
    private final List<RequestLogListener> listenerList = new ArrayList<RequestLogListener>();
    private final Object lock = new Object();

    public RequestLog(final ObjectContainer database) {
        this.database = database;
        this.requestLogId = getRequestLogId(database);
        this.cloner = new HttpMessageCloner(database);
        final EventRegistry registry = EventRegistryFactory.forObjectContainer(database);

        registry.activated().addListener(new EventListener4<ObjectInfoEventArgs>() {

            @Override
            public void onEvent(Event4<ObjectInfoEventArgs> arg0, ObjectInfoEventArgs args) {
                final Object ob = args.object();
                if (ob instanceof RequestLogResponse) {
                    final RequestLogResponse r = (RequestLogResponse) ob;
                    r.setDatabase(database);
                } else if (ob instanceof RequestLogEntityEnclosingRequest) {
                    final RequestLogEntityEnclosingRequest r = (RequestLogEntityEnclosingRequest) ob;
                    r.setDatabase(database);
                }
            }
        });
    }

    private RequestLogId getRequestLogId(ObjectContainer database) {
        List<RequestLogId> result = database.query(RequestLogId.class);
        if (result.size() == 0) {
            RequestLogId rli = new RequestLogId();
            database.store(rli);
            return rli;
        } else if (result.size() == 1) {
            return result.get(0);
        } else {
            throw new IllegalStateException("Database corrupted, found multiple RequestLogId instances");
        }
    }

    @Override
    public long allocateRequestId() {
        final long id = requestLogId.allocateId();
        database.store(requestLogId);
        return id;
    }

    @Override
    public long addRequestResponse(IHttpResponse response) {
        if (response.getRequestId() != -1) {
            return response.getRequestId();
        }
        final long id = allocateRequestId();
        final HttpRequest newRequest = cloner.copyRequest(response.getOriginalRequest());
        final HttpResponse newResponse = cloner.copyResponse(response.getRawResponse());
        database.store(newRequest);
        database.store(newResponse);
        final RequestLogRecord record = new RequestLogRecord(id, newRequest, newResponse, response.getHost(),
                response.getRequestMilliseconds());
        synchronized (lock) {
            database.store(record);
            filterNewRecord(record);
        }
        response.setRequestId(id);
        return id;
    }

    private void filterNewRecord(IRequestLogRecord record) {
        for (RequestLogListener listener : listenerList) {
            listener.filterRecord(record);
        }
    }

    @Override
    public RequestLogRecord lookupRecord(final long requestId) {
        synchronized (this) {
            List<RequestLogRecord> result = database.query(new Predicate<RequestLogRecord>() {
                private static final long serialVersionUID = 1L;

                @Override
                public boolean match(RequestLogRecord record) {
                    return record.requestId == requestId;
                }
            });

            if (result.size() == 0)
                return null;
            else if (result.size() == 1)
                return result.get(0);
            else
                throw new IllegalStateException(
                        "Database corrupted, found multiple RequestLogRecords for id == " + requestId);
        }
    }

    @Override
    public List<IRequestLogRecord> getAllRecords() {
        if (!hasRecords()) {
            return Collections.emptyList();
        }
        final Query query = database.query();
        query.constrain(IRequestLogRecord.class);
        return query.execute();
    }

    private boolean hasRecords() {
        final Query query = database.query();
        query.constrain(IRequestLogRecord.class);
        return query.execute().size() > 0;
    }

    public List<IRequestLogRecord> getRecordsByConditionSet(IHttpConditionSet conditionFilter) {
        if (conditionFilter instanceof HttpConditionSet) {
            return ((HttpConditionSet) conditionFilter).filterRequestLog(database);
        } else {
            return Collections.emptyList();
        }
    }

    @Override
    public void addUpdateListener(IRequestLogUpdateListener callback) {
        synchronized (lock) {
            listenerList.add(new RequestLogListener(callback, null, getAllRecords().size()));
        }
    }

    @Override
    public void addUpdateListener(IRequestLogUpdateListener callback, IHttpConditionSet conditionFilter) {
        synchronized (lock) {
            listenerList.add(new RequestLogListener(callback, conditionFilter,
                    getRecordsByConditionSet(conditionFilter).size()));
        }
    }

    @Override
    public void removeUpdateListener(IRequestLogUpdateListener callback) {
        synchronized (lock) {
            final Iterator<RequestLogListener> it = listenerList.iterator();
            while (it.hasNext()) {
                RequestLogListener listener = it.next();
                if (listener.getListenerCallback() == callback)
                    it.remove();
            }
        }
    }
}