org.glite.security.voms.admin.persistence.dao.hibernate.AuditSearchDAOHibernate.java Source code

Java tutorial

Introduction

Here is the source code for org.glite.security.voms.admin.persistence.dao.hibernate.AuditSearchDAOHibernate.java

Source

/**
 * Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2006-2016
 *
 * 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 org.glite.security.voms.admin.persistence.dao.hibernate;

import java.util.List;

import org.apache.commons.lang.Validate;
import org.glite.security.voms.admin.persistence.dao.generic.AuditSearchDAO;
import org.glite.security.voms.admin.persistence.model.audit.AuditEvent;
import org.glite.security.voms.admin.view.actions.audit.AuditLogSearchParams;
import org.glite.security.voms.admin.view.actions.audit.AuditLogSearchResults;
import org.glite.security.voms.admin.view.actions.audit.ScrollableAuditLogSearchResults;
import org.hibernate.Criteria;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.type.StringType;

public class AuditSearchDAOHibernate extends GenericHibernateDAO<AuditEvent, Long> implements AuditSearchDAO {

    AuditSearchDAOHibernate() {

    }

    @SuppressWarnings("unchecked")
    @Override
    public List<AuditEvent> findLatestEvents(int numEvents) {

        Validate.isTrue(numEvents >= 0, "numEvents must be a positive integer.");

        Criteria crit = createCriteria();
        crit.addOrder(Order.desc("timestamp"));
        crit.setMaxResults(numEvents);

        return crit.list();
    }

    @Override
    public Integer countEvents() {

        Criteria crit = createCriteria();
        crit.setProjection(Projections.rowCount());
        return (Integer) crit.uniqueResult();
    }

    protected Criteria buildCriteriaFromParams(AuditLogSearchParams sp) {

        Criteria crit = createCriteria();

        crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

        if (sp.getFromTime() != null) {
            crit.add(Restrictions.ge("timestamp", sp.getFromTime()));
        }

        if (sp.getToTime() != null) {
            crit.add(Restrictions.le("timestamp", sp.getToTime()));
        }

        if (sp.getFilterString() != null && !sp.getFilterString().trim().equals("")) {

            if (sp.getFilterType().equals(AuditLogSearchParams.FULL_SEARCH_KEY)) {

                // Full search is basically search over principal
                // and audit event data point values
                String filterString = String.format("%%%s%%", sp.getFilterString());

                // This is due to another ugly limitation of Hibernate 3.3
                // which does not support criteria queries on embedded
                // collections
                // See https://hibernate.atlassian.net/browse/HHH-869

                crit.add(Restrictions.disjunction().add(Restrictions.sqlRestriction(
                        "{alias}.event_id in (select ae.event_id from audit_event ae, audit_event_data aed where ae.event_id = aed.event_id and aed.value like ?)",
                        filterString, StringType.INSTANCE))
                        .add(Restrictions.like("principal", sp.getFilterString().trim(), MatchMode.ANYWHERE)));

            } else {
                crit.add(Restrictions.like(sp.getFilterType(), sp.getFilterString().trim(), MatchMode.ANYWHERE));
            }

        }

        if (sp.getFirstResult() != null) {
            crit.setFirstResult(sp.getFirstResult());
        }

        if (sp.getMaxResults() != null) {
            crit.setMaxResults(sp.getMaxResults());
        }

        crit.addOrder(Order.desc("timestamp"));
        return crit;
    }

    @SuppressWarnings("unchecked")
    @Override
    public AuditLogSearchResults findEventsMatchingParams(AuditLogSearchParams sp) {

        Criteria crit = buildCriteriaFromParams(sp);
        List<AuditEvent> results = crit.list();

        crit.setProjection(Projections.rowCount());

        // This is a workaround for
        // https://hibernate.atlassian.net/browse/HHH-4761
        // TLDR:
        // The count(*) project doesn't work well with
        // the limit implementation of the MySQL Hibernate dialect.
        // Since what we need here is a way to count all results
        // matching the query in a way that is not relative to the page
        // size, we can ignore the pagination limits and just set
        // arbirtray values and the count(*) result will be accurate
        crit.setFirstResult(0);
        crit.setMaxResults(100);

        Long count = (Long) crit.uniqueResult();

        if (count == null) {
            count = 0L;
        }

        return new AuditLogSearchResults(sp, count, results);
    }

    public ScrollableAuditLogSearchResults scrollEventsMatchingParams(AuditLogSearchParams sp, ScrollMode mode) {

        Criteria crit = buildCriteriaFromParams(sp);
        ScrollableResults results = crit.scroll(mode);

        return new ScrollableAuditLogSearchResults(sp, results);

    }

    @Override
    public Integer countEventsMatchingParams(AuditLogSearchParams sp) {

        Criteria crit = buildCriteriaFromParams(sp);
        crit.setProjection(Projections.rowCount());

        // This is a workaround for
        // https://hibernate.atlassian.net/browse/HHH-4761
        // TLDR:
        // The count(*) project doesn't work well with
        // the limit implementation of the MySQL Hibernate dialect.
        // Since what we need here is a way to count all results
        // matching the query in a way that is not relative to the page
        // size, we can ignore the pagination limits and just set
        // arbirtray values and the count(*) result will be accurate
        crit.setFirstResult(0);
        crit.setMaxResults(100);

        return (Integer) crit.uniqueResult();
    }

}