org.dragoneronca.nlp.wol.domain.WolEntityIterator.java Source code

Java tutorial

Introduction

Here is the source code for org.dragoneronca.nlp.wol.domain.WolEntityIterator.java

Source

/*
 * Copyright Paolo Dragone 2014.
 * Copyright Alessandro Ronca 2014.
 *
 * This file is part of Wiktionary Ontology.
 *
 * Wiktionary Ontology is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Wiktionary Ontology is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Wiktionary Ontology. If not, see <http://www.gnu.org/licenses/>.
 */

package org.dragoneronca.nlp.wol.domain;

import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.log4j.Logger;
import org.dragoneronca.nlp.wol.WolConfiguration;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * An iterator over entities of type T.
 * <p/>
 * It performs a bounding of the results of the queries in order to limit the memory needed to
 * iterte them.
 *
 * @author Paolo Dragone
 * @author Alessandro Ronca
 */
public class WolEntityIterator<T> implements Iterator<T> {

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

    private static final int MAX_RETRIEVED_DELTA = 1000;

    private final String name;
    private final Class<T> tClass;
    private boolean clear = false;
    private boolean logEnabled = false;

    private int offset = 0;
    private int max = 0;

    private LinkedList<T> results = new LinkedList<>();

    private Object[] parameters;
    private boolean ended = false;

    /**
     * Creates a new WolEntityIterator for entities of type tClass, using the query associated with
     * the given name.
     *
     * @param tClass The type of the entity returned by the query
     * @param name   The name of the query to be executed
     */
    public WolEntityIterator(Class<T> tClass, String name) {
        this.tClass = tClass;
        this.name = name;
        PropertiesConfiguration properties = WolConfiguration.getInstance().getConfiguration("environment");
        this.max = properties.getInt("entity_iterator.default_max");
    }

    public WolEntityIterator(Class<T> tClass, String name, int max, boolean logEnabled) {
        this(tClass, name, max);
        this.logEnabled = logEnabled;
    }

    /**
     * Creates a new WolEntityIterator for entities of type tClass, using the query associated with
     * the given name.
     *
     * @param tClass The type of the entity returned by the query
     * @param name   The name of the query to be executed
     */
    public WolEntityIterator(Class<T> tClass, String name, int max) {
        this.tClass = tClass;
        this.name = name;
        this.max = max + MAX_RETRIEVED_DELTA;
    }

    public WolEntityIterator(Class<T> tClass, String name, int max, boolean logEnabled, boolean clear) {
        this(tClass, name, max);
        this.logEnabled = logEnabled;
        this.clear = clear;
    }

    /**
     * Sets the parameters of the query.
     * <p/>
     * If the query has mandatory parameters they must be set before the offset next or hasNext.
     *
     * @param parameters The list of parameters (positional assignment)
     */
    public void setParameters(Object... parameters) {
        this.parameters = parameters;
    }

    @Override
    public boolean hasNext() {
        return !ended && (!results.isEmpty() || retrieveResults());
    }

    @SuppressWarnings("unchecked")
    private boolean retrieveResults() {
        if (ended) {
            return false;
        } else if (!results.isEmpty()) {
            return true;
        }

        WolDomainContext domainContext = WolDomainContext.getInstance();
        EntityManager entityManager = domainContext.getEntityManager();
        if (clear) {
            entityManager.clear();
        }
        TypedQuery<T> q = entityManager.createNamedQuery(name, tClass);

        if (parameters != null) {
            int i = 1;
            for (Object parameter : parameters) {
                q.setParameter(i++, parameter);
            }
        }
        q.setFirstResult(offset).setMaxResults(max);

        long startQueryTime = System.currentTimeMillis();
        if (logEnabled) {
            LOG.info("Starting query: " + name + "\t\tType: " + tClass.getSimpleName());
        }

        Runtime.getRuntime().gc();
        List<T> resultList = q.getResultList();

        if (!resultList.isEmpty()) {
            results.addAll(resultList);
            offset += results.size();

            long endQueryTime = System.currentTimeMillis();
            if (logEnabled) {
                LOG.info("Retrieved " + results.size() + " results in " + ((endQueryTime - startQueryTime) / 1000)
                        + " sec.");
            }

            return true;
        } else {
            ended = true;
            return false;
        }
    }

    @Override
    public T next() {
        if (!hasNext()) {
            return null;
        }
        return results.removeFirst();
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException();
    }
}