/******************************************************************************* * See the NOTICE file distributed with this work for additional information * regarding copyright ownership. * * 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 hr.fer.zemris.vhdllab.entity; import java.util.Date; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.NoResultException; import javax.persistence.PostPersist; import javax.persistence.PostRemove; import javax.persistence.PostUpdate; import javax.persistence.PreRemove; import javax.persistence.Query; import org.apache.log4j.Logger; public class HistoryListener { /** * Logger for this class */ private static final Logger LOG = Logger.getLogger(HistoryListener.class); private static EntityManagerFactory entityManagerFactory; public static void setEntityManagerFactory( EntityManagerFactory entityManagerFactory) { HistoryListener.entityManagerFactory = entityManagerFactory; } private EntityManager newEntityManager() { EntityManager em = entityManagerFactory.createEntityManager(); em.getTransaction().begin(); return em; } private void closeEntityManager(EntityManager em) { em.getTransaction().commit(); em.close(); } @PreRemove public void preFileRemove(Object o) { if(o instanceof File) { File f = (File) o; Project project = f.getProject(); if(project != null) { /* * Project is being removed which will, by cascade, delete * files. But Project#removeFile will not be called which means * that post remove project reference will not be set so we do * it manually (because post remove event depends on it)! */ f.setPostRemoveProjectReference(project); } } } @PostPersist public void createHistory(Object o) { try { EntityManager em = newEntityManager(); Object history; if (o instanceof Project) { Project project = (Project) o; ProjectHistory projectHistory; try { projectHistory = getLastProjectHistory(em, project); } catch (NoResultException e) { projectHistory = null; } History h; if(projectHistory == null) { h = new History(); } else { h = new History(projectHistory.getHistory().getInsertVersion()+1, 0); } history = new ProjectHistory(project, h); } else if(o instanceof File) { File f = (File) o; ProjectHistory projectHistory = getLastProjectHistory(em, f.getProject()); FileHistory fileHistory; try { fileHistory = getLastFileHistory(em, projectHistory.getId(), f.getName()); } catch (Exception e) { fileHistory = null; } History h; if(fileHistory == null) { h = new History(); } else { h = new History(fileHistory.getHistory().getInsertVersion()+1, 0); } history = new FileHistory(f, projectHistory.getId(), h); } else { history = null; } if (history != null) { em.persist(history); } closeEntityManager(em); } catch (Exception e) { LOG.error("Exception in history creation.", e); } } @PostUpdate public void updateHistory(Object o) { try { EntityManager em = newEntityManager(); Object history; if (o instanceof File) { File f = (File) o; ProjectHistory projectHistory = getLastProjectHistory(em, f.getProject()); FileHistory fileHistory = getLastFileHistory(em, projectHistory.getId(), f.getName()); History h = new History(fileHistory.getHistory().getInsertVersion(), fileHistory.getHistory().getUpdateVersion()+1); history = new FileHistory(f, fileHistory.getProjectId(), h); } else { history = null; } if (history != null) { em.persist(history); } closeEntityManager(em); } catch (Exception e) { LOG.error("Exception in history creation.", e); } } @PostRemove public void removeHistory(Object o) { try { EntityManager em = newEntityManager(); if (o instanceof Project) { Project project = (Project) o; ProjectHistory projectHistory = getLastProjectHistory(em, project); projectHistory.getHistory().setDeletedOn(new Date()); em.persist(projectHistory); } else if(o instanceof File) { File f = (File) o; ProjectHistory projectHistory = getLastProjectHistory(em, f.getPostRemoveProjectReference()); FileHistory fileHistory = getLastFileHistory(em, projectHistory.getId(), f.getName()); fileHistory.getHistory().setDeletedOn(new Date()); em.persist(fileHistory); } closeEntityManager(em); } catch (Exception e) { LOG.error("Exception in history creation.", e); } } private ProjectHistory getLastProjectHistory(EntityManager em, Project project) { String userId = project.getUserId(); String name = project.getName(); StringBuilder sb = new StringBuilder(1000); sb.append("select h from ProjectHistory as h"); sb.append(" where h.userId = :userId"); sb.append(" and h.name = :name"); sb.append(" and h.history.insertVersion = ("); sb.append(" select max(ih.history.insertVersion) from ProjectHistory as ih"); sb.append(" where ih.userId = :userId and ih.name = :name)"); sb.append(" and h.history.updateVersion = ("); sb.append(" select max(uh.history.updateVersion) from ProjectHistory as uh"); sb.append(" where uh.userId = :userId and uh.name = :name"); sb.append(" and uh.history.insertVersion = h.history.insertVersion)"); Query query = em.createQuery(sb.toString()); query.setParameter("userId", userId); query.setParameter("name", name); return (ProjectHistory) query.getSingleResult(); } private FileHistory getLastFileHistory(EntityManager em, Integer projectId, String name) { StringBuilder sb = new StringBuilder(1000); sb.append("select h from FileHistory as h"); sb.append(" where h.projectId = :projectId"); sb.append(" and h.name = :name"); sb.append(" and h.history.insertVersion = ("); sb.append(" select max(ih.history.insertVersion) from FileHistory as ih"); sb.append(" where ih.projectId = :projectId and ih.name = :name)"); sb.append(" and h.history.updateVersion = ("); sb.append(" select max(uh.history.updateVersion) from FileHistory as uh"); sb.append(" where uh.projectId = :projectId and uh.name = :name"); sb.append(" and uh.history.insertVersion = h.history.insertVersion)"); Query query = em.createQuery(sb.toString()); query.setParameter("projectId", projectId); query.setParameter("name", name); return (FileHistory) query.getSingleResult(); } }