Package org.jasig.portal.events.handlers.db

Source Code of org.jasig.portal.events.handlers.db.JpaPortalEventStore

/**
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Jasig licenses this file to you 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.jasig.portal.events.handlers.db;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.hibernate.ejb.HibernateEntityManager;
import org.jasig.portal.events.BatchingEventHandler;
import org.jasig.portal.events.EventType;
import org.jasig.portal.events.PortalEvent;
import org.jasig.portal.events.handlers.AbstractLimitedSupportEventHandler;
import org.jasig.portal.groups.GroupsException;
import org.jasig.portal.groups.IGroupMember;
import org.jasig.portal.security.IPerson;
import org.jasig.portal.services.GroupService;
import org.springframework.stereotype.Repository;

/**
* Stores portal events using JPA/Hibenate no internall batch segementation is done to the passed list
* of {@link PortalEvent}s. If a {@link PortalEvent} is not mapped as a persistent entity a message is logged
* at the WARN level and the event is ignored.
*
* @author Eric Dalquist
* @version $Revision$
*/
@Repository
public class JpaPortalEventStore extends AbstractLimitedSupportEventHandler implements BatchingEventHandler, IPortalEventStore {
    protected final Log logger = LogFactory.getLog(this.getClass());
   
    protected static final String STATS_SESSION_ID_PERSON_ATTR = JpaPortalEventStore.class.getName() + ".StatsSessionId";
   
    private EntityManager entityManager;
    private boolean logSessionGroups = true;
   
    /**
     * @return the entityManager
     */
    public EntityManager getEntityManager() {
        return this.entityManager;
    }
    /**
     * @param entityManager the entityManager to set
     */
    @PersistenceContext(unitName = "uPortalStatsPersistence")
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
   
    /**
     * @return the logSessionGroups
     */
    public boolean isLogSessionGroups() {
        return logSessionGroups;
    }
    /**
     * If group keys should be included in the stats session. This can be disabled to reduce the ammount
     * of data stored in the stats tables.
     *
     * @param logSessionGroups the logSessionGroups to set
     */
    public void setLogSessionGroups(boolean logSessionGroups) {
        this.logSessionGroups = logSessionGroups;
    }
   
    /* (non-Javadoc)
     * @see org.jasig.portal.events.EventHandler#handleEvent(org.jasig.portal.events.PortalEvent)
     */
    public void handleEvent(PortalEvent event) {
        this.storePortalEvents(event);
       
    }
   
    /* (non-Javadoc)
     * @see org.jasig.portal.events.BatchingEventHandler#handleEvents(org.jasig.portal.events.PortalEvent[])
     */
    public void handleEvents(PortalEvent... events) {
        this.storePortalEvents(events);
    }
   
    /* (non-Javadoc)
     * @see org.jasig.portal.events.handlers.db.IPortalEventStore#storePortalEvents(org.jasig.portal.events.PortalEvent[])
     */
    public void storePortalEvents(PortalEvent... portalEvents) {
        for (final PortalEvent portalEvent : portalEvents) {
            //Load the StatsSession into the event if it isn't already there
            if (portalEvent.getStatsSession() == null) {
                final IPerson person = portalEvent.getPerson();
                final StatsSession statsSession = this.getStatsSession(person);
                portalEvent.setStatsSession(statsSession);
            }

            //Ensure the EventType has been persisted, assumes un-persisted events have an id of 0
            final EventType eventType = portalEvent.getEventType().intern();
            if (eventType.getId() == 0 || !this.entityManager.contains(eventType)) {
                //If an existing EventType is found load it, if not persist the one we have
                //Due to EventType's behavior we don't need to replace the eventType with the foundEventType, they synchronize on load
                final EventType foundEventType = this.findExistingEventType(eventType);
                if (foundEventType == null) {
                    this.entityManager.persist(eventType);
                }
            }
           
            try {
                this.entityManager.persist(portalEvent);
            }
            catch (IllegalArgumentException iae) {
                this.logger.warn(portalEvent.getClass().getName() + " is not mapped as a persistent entity and will not be stored. event=[" + portalEvent + "], message=" + iae.getMessage());
            }
        }
    }

    /**
     * Gets a StatsSession object for the specified person, creating, populating and persisting it if needed
     */
    protected StatsSession getStatsSession(final IPerson person) {
        //Gets the statsSessionId from the IPerson object
        final Long statsSessionId = (Long)person.getAttribute(STATS_SESSION_ID_PERSON_ATTR);

        StatsSession statsSession = null;
        //Try and load the appropriate stats session based on the ID in the user's person object
        if (statsSessionId != null && statsSessionId > 0) {
            statsSession = this.entityManager.find(StatsSession.class, statsSessionId);
        }
       
        //If no statsSessionId is found, create one for the user
        if (statsSession == null) {
            statsSession = new StatsSession();
            final String userName = (String)person.getAttribute(IPerson.USERNAME);
            statsSession.setUserName(userName);
           
            if (this.logSessionGroups) {
                try {
                    //Load the user's groups for this session
                    this.updateStatsSessionGroups(statsSession, person);
                }
                catch (org.jasig.portal.groups.GroupsException ge) {
                    this.logger.warn("Exception while loading groups for person='" + person + "' and session='" + statsSession + "'", ge);
                }
            }
           
            this.entityManager.persist(statsSession);
           
            person.setAttribute(STATS_SESSION_ID_PERSON_ATTR, statsSession.getSessionId());
        }

        return statsSession;
    }
   
    /**
     * Sets the {@link StatsSession#setGroups(Set)} using the keys from the {@link IGroupMember}s returned by
     * {@link IGroupMember#getAllContainingGroups()}
     */
    protected void updateStatsSessionGroups(final StatsSession session, final IPerson person) throws GroupsException {
        final IGroupMember member = GroupService.getGroupMember(person.getEntityIdentifier());
       
        final Set<String> groupKeys = new HashSet<String>();
        for (final Iterator<IGroupMember> groupItr = member.getAllContainingGroups(); groupItr.hasNext(); ) {
            final IGroupMember group = groupItr.next();
            groupKeys.add(group.getKey());
        }
       
        session.setGroups(groupKeys);
    }

    /**
     * Contains the logic to query for an already persisted EventType with the same type value.
     */
    protected EventType findExistingEventType(EventType eventType) {
        if (eventType.getId() != 0) {
            final EventType foundEventType = this.entityManager.find(EventType.class, eventType.getId());
            if (foundEventType != null) {
                return foundEventType;
            }
           
            eventType.setId(0);
        }
       
        //No id, do a lookup based on the event type
        final HibernateEntityManager hibernateEntityManager = ((HibernateEntityManager)this.entityManager);
        final Session session = hibernateEntityManager.getSession();
       
        //Setup the Criteria query
        final Criteria eventTypeCriteria = session.createCriteria(EventType.class);
        eventTypeCriteria.add(Restrictions.naturalId().set("type", eventType.getType()));
        eventTypeCriteria.setCacheable(true);
        eventTypeCriteria.setMaxResults(1);
       
        final EventType foundEventType = (EventType)eventTypeCriteria.uniqueResult();
        return foundEventType;
    }
}
TOP

Related Classes of org.jasig.portal.events.handlers.db.JpaPortalEventStore

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.