/* * Copyright (c) 2008-2012, 2015 Eike Stepper (Berlin, Germany) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Martin Taal - copied from CDORevisionPropertyHandler and adapted * Eike Stepper - maintenance */ package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; import org.eclipse.emf.ecore.EStructuralFeature; import org.hibernate.collection.spi.PersistentCollection; import java.util.HashMap; import java.util.Map; /** * Keeps mappings from object/feature combinations to a hibernate persistable list. This works because the write action * is done in one thread. * * @author Martin Taal */ public class PersistableListHolder { private static PersistableListHolder instance = new PersistableListHolder(); private static ThreadLocal<Map<Key, PersistentCollection>> listMapping = new ThreadLocal<Map<Key, PersistentCollection>>(); public PersistableListHolder() { } public void putListMapping(Object target, EStructuralFeature feature, PersistentCollection collection) { Key key = new Key(target, feature); final PersistentCollection currentCachedValue = getListMapping(target, feature); if (currentCachedValue == collection) { return; } if (currentCachedValue != null) { throw new IllegalStateException("There is already a list mapping present"); } getListMapping().put(key, collection); } public PersistentCollection getListMapping(Object target, EStructuralFeature feature) { Key key = new Key(target, feature); return getListMapping().get(key); } private Map<Key, PersistentCollection> getListMapping() { if (listMapping.get() == null) { listMapping.set(new HashMap<Key, PersistentCollection>()); } return listMapping.get(); } public void clearListMapping() { listMapping.set(null); } public static PersistableListHolder getInstance() { return instance; } public static void setInstance(PersistableListHolder instance) { PersistableListHolder.instance = instance; } private static final class Key { private Object owner; private EStructuralFeature feature; public Key(Object owner, EStructuralFeature feature) { this.owner = owner; this.feature = feature; } @Override public boolean equals(Object obj) { if (!(obj instanceof Key)) { return false; } Key otherKey = (Key)obj; // the owner is uniquely present in mem, the same applies for the feature // therefore == is allowed return owner == otherKey.owner && feature == otherKey.feature; } @Override public int hashCode() { return owner.hashCode() + feature.hashCode(); } } }