/* * Copyright (C) 2005-2007 Alfresco Software Limited. * * This program 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 2 * of the License, or (at your option) any later version. * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * As a special exception to the terms and conditions of version 2.0 of * the GPL, you may redistribute this Program in connection with Free/Libre * and Open Source Software ("FLOSS") applications as described in Alfresco's * FLOSS exception. You should have recieved a copy of the text describing * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ package org.alfresco.repo.domain.hibernate; import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Set; import org.alfresco.util.GUID; import org.hibernate.CacheMode; import org.hibernate.Session; import org.hibernate.engine.EntityKey; import com.sun.corba.se.spi.legacy.connection.GetEndPointInfoAgainException; /** * Support to (optionally) listen to hibernate events generated by a hibernate session. The tracking is bound to a * transaction resource * * @author andyh */ public class HibernateSessionHelperResource implements HibernateSessionHelperResourceProvider { LinkedHashMap> marks = new LinkedHashMap>(); String currentMark = null; HibernateSessionHelperResource() { } public String getCurrentMark() { return currentMark; } public List getMarks(Session session) { ArrayList answer = new ArrayList(marks.size()); for (String key : marks.keySet()) { answer.add(key); } return answer; } public void mark(Session session) { Thread thread = Thread.currentThread(); String guid = GUID.generate(); mark(session, guid); } @SuppressWarnings("unchecked") public void mark(Session session, String label) { session.flush(); if (label == null) { throw new HibernateSessionHelperResourceException("Null key is not supported"); } if (marks.containsKey(label)) { throw new HibernateSessionHelperResourceException("Key already exists - " + label); } if (marks.size() == 0) { SessionSizeResourceManager.setDisableInTransaction(); } HashSet mark = new HashSet((Set) session.getStatistics().getEntityKeys()); marks.put(label, mark); currentMark = label; //System.out.println("Mark "+marks.size()+" "+currentMark); } public void removeMark(Session session) { if (currentMark != null) { removeMark(session, currentMark); } else { throw new HibernateSessionHelperResourceException("No current mark"); } } public void removeMark(Session session, String label) { if (label == null) { throw new HibernateSessionHelperResourceException("Null key is not supported"); } if (!marks.containsKey(label)) { throw new HibernateSessionHelperResourceException("Key does not exist - " + label); } if (marks.size() > 0) { marks.remove(label); if (label.equals(currentMark)) { currentMark = getLastMarkOrNull(); } } if (marks.size() == 0) { SessionSizeResourceManager.setEnableInTransaction(); } } public void reset(Session session) { if (currentMark != null) { doResetAndRemove(session, currentMark, false); } else { throw new HibernateSessionHelperResourceException("No current mark"); } } public void reset(Session session, String label) { doResetAndRemove(session, label, false); } public void resetAndRemoveMark(Session session) { if (currentMark != null) { doResetAndRemove(session, currentMark, true); } else { throw new HibernateSessionHelperResourceException("No current mark"); } } public void resetAndRemoveMark(Session session, String label) { doResetAndRemove(session, label, true); } @SuppressWarnings("unchecked") private void doResetAndRemove(Session session, String label, boolean remove) { if (label == null) { throw new HibernateSessionHelperResourceException("Null key is not supported"); } if (!marks.containsKey(label)) { throw new HibernateSessionHelperResourceException("Key does not exist - " + label); } if (marks.size() > 0) { session.flush(); Set check = marks.get(label); Set current = new HashSet((Set) session.getStatistics().getEntityKeys()); Set toEvict = new HashSet(Math.max((int) (current.size() / .75f) + 1, 16)); for (EntityKey key : current) { if (!check.contains(key)) { if (!key.getEntityName().startsWith("org.alfresco")) { System.out.println("Oops: " + key.getEntityName()); } if(key.getEntityName().equals(QNameEntityImpl.class.getName())) { //System.out.println("Skipping: " + key.getEntityName()); continue; } Object val = session.get(key.getEntityName(), key.getIdentifier()); if (val != null) { toEvict.add(val); } } } for (Object evitee : toEvict) { session.evict(evitee); } String last; while ((last = getLastMarkOrNull()) != null) { if (!label.equals(last)) { marks.remove(last); } else { if (remove) { marks.remove(last); } break; } } currentMark = getLastMarkOrNull(); if (marks.size() == 0) { SessionSizeResourceManager.setEnableInTransaction(); } //System.out.println("Removed "+marks.size()+" "+label); } } private String getLastMarkOrNull() { String mark = null; for (String key : marks.keySet()) { mark = key; } return mark; } }