/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF 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.apache.openjpa.persistence; import java.util.Arrays; import java.util.BitSet; import java.util.Collection; import org.apache.openjpa.datacache.CacheStatistics; import org.apache.openjpa.datacache.DataCache; import org.apache.openjpa.datacache.DelegatingDataCache; import org.apache.openjpa.meta.ClassMetaData; import org.apache.openjpa.meta.MetaDataRepository; /** * Implements the L2 cache over the data store via delegation to DataCache. * * @author Abe White * @since 0.4.1 */ public class StoreCacheImpl implements StoreCache { private final MetaDataRepository _repos; private final DelegatingDataCache _cache; /** * Constructor; supply delegate. */ public StoreCacheImpl(EntityManagerFactoryImpl emf, DataCache cache) { _repos = emf.getConfiguration().getMetaDataRepositoryInstance(); _cache = new DelegatingDataCache(cache, PersistenceExceptions.TRANSLATOR); } /** * Delegate. */ public DataCache getDelegate() { return _cache.getDelegate(); } public boolean contains(Class cls, Object oid) { return _cache.getDelegate() != null && _cache.contains (JPAFacadeHelper.toOpenJPAObjectId(getMetaData(cls), oid)); } public boolean containsAll(Class cls, Object... oids) { return containsAll(cls, Arrays.asList(oids)); } public boolean containsAll(Class cls, Collection oids) { if (_cache.getDelegate() == null) return oids.isEmpty(); BitSet set = _cache.containsAll(JPAFacadeHelper.toOpenJPAObjectIds (getMetaData(cls), oids)); for (int i = 0; i < oids.size(); i++) if (!set.get(i)) return false; return true; } public void pin(Class cls, Object oid) { if (_cache.getDelegate() != null) _cache.pin(JPAFacadeHelper.toOpenJPAObjectId(getMetaData(cls), oid)); } public void pinAll(Class cls, Object... oids) { pinAll(cls, Arrays.asList(oids)); } public void pinAll(Class cls, Collection oids) { if (_cache.getDelegate() != null) _cache.pinAll(JPAFacadeHelper.toOpenJPAObjectIds (getMetaData(cls), oids)); } public void unpin(Class cls, Object oid) { if (_cache.getDelegate() != null) _cache.unpin(JPAFacadeHelper.toOpenJPAObjectId(getMetaData(cls), oid)); } public void unpinAll(Class cls, Object... oids) { unpinAll(cls, Arrays.asList(oids)); } public void unpinAll(Class cls, Collection oids) { if (_cache.getDelegate() != null) _cache.unpinAll(JPAFacadeHelper.toOpenJPAObjectIds (getMetaData(cls), oids)); } public void evict(Class cls, Object oid) { if (_cache.getDelegate() != null) _cache.remove(JPAFacadeHelper.toOpenJPAObjectId(getMetaData(cls), oid)); } public void evictAll(Class cls, Object... oids) { evictAll(cls, Arrays.asList(oids)); } public void evictAll(Class cls, Collection oids) { if (_cache.getDelegate() != null) _cache.removeAll(JPAFacadeHelper.toOpenJPAObjectIds (getMetaData(cls), oids)); } public void evictAll() { _cache.clear(); } @Override public <T> T unwrap(Class<T> cls) { if (cls.isInstance(this)) { return cls.cast(this); } throw new javax.persistence.PersistenceException(cls.getName() + " not supported"); } public CacheStatistics getStatistics() { return (_cache == null) ? null : _cache.getStatistics(); } /** * Return metadata for the given class, throwing the proper exception * if not persistent. */ private ClassMetaData getMetaData(Class cls) { try { return _repos.getMetaData(cls, null, true); } catch (RuntimeException re) { throw PersistenceExceptions.toPersistenceException(re); } } public int hashCode() { return (_cache == null) ? 0 : _cache.hashCode(); } public boolean equals(Object other) { if (other == this) return true; if ((other == null) || (other.getClass() != this.getClass())) return false; if (_cache == null) return false; return _cache.equals (((StoreCacheImpl) other)._cache); } @SuppressWarnings("unchecked") public void evict(Class cls) { // Check MetaData throws a consistent exception with evict(Class, // Object) if(getMetaData(cls) != null) { _cache.removeAll(cls, true); } } }