/* * Copyright (C) 2003-2011 eXo Platform SAS. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.exoplatform.social.core.storage.cache; import org.exoplatform.services.cache.ExoCache; import org.exoplatform.social.core.space.SpaceFilter; import org.exoplatform.social.core.space.model.Space; import org.exoplatform.social.core.storage.SpaceStorageException; import org.exoplatform.social.core.storage.cache.model.data.IntegerData; import org.exoplatform.social.core.storage.cache.model.data.ListSpacesData; import org.exoplatform.social.core.storage.cache.model.key.ListSpacesKey; import org.exoplatform.social.core.storage.cache.model.key.SpaceFilterKey; import org.exoplatform.social.core.storage.cache.model.key.SpaceType; import org.exoplatform.social.core.storage.impl.SpaceStorageImpl; import org.exoplatform.social.core.storage.api.SpaceStorage; import org.exoplatform.social.core.storage.cache.loader.ServiceContext; import org.exoplatform.social.core.storage.cache.model.data.SpaceData; import org.exoplatform.social.core.storage.cache.model.key.SpaceKey; import org.exoplatform.social.core.storage.cache.model.key.SpaceRefKey; import java.util.ArrayList; import java.util.List; /** * @author <a href="mailto:alain.defrance@exoplatform.com">Alain Defrance</a> * @version $Revision$ */ public class CachedSpaceStorage implements SpaceStorage { private final ExoCache<SpaceKey, SpaceData> exoSpaceCache; private final ExoCache<SpaceRefKey, SpaceKey> exoRefSpaceCache; private final ExoCache<SpaceFilterKey, IntegerData> exoSpacesCountCache; private final ExoCache<ListSpacesKey, ListSpacesData> exoSpacesCache; private final FutureExoCache<SpaceKey, SpaceData, ServiceContext<SpaceData>> spaceCache; private final FutureExoCache<SpaceRefKey, SpaceKey, ServiceContext<SpaceKey>> spaceRefCache; private final FutureExoCache<SpaceFilterKey, IntegerData, ServiceContext<IntegerData>> spacesCountCache; private final FutureExoCache<ListSpacesKey, ListSpacesData, ServiceContext<ListSpacesData>> spacesCache; private final SpaceStorageImpl storage; /** * Build the activity list from the caches Ids. * * @param data ids * @return activities */ private List<Space> buildSpaces(ListSpacesData data) { List<Space> spaces = new ArrayList<Space>(); for (SpaceKey k : data.getIds()) { Space s = getSpaceById(k.getId()); spaces.add(s); } return spaces; } /** * Build the ids from the space list. * * @param spaces spaces * @return ids */ private ListSpacesData buildIds(List<Space> spaces) { List<SpaceKey> data = new ArrayList<SpaceKey>(); for (Space s : spaces) { SpaceKey k = new SpaceKey(s.getId()); exoSpaceCache.put(k, new SpaceData(s)); data.add(k); } return new ListSpacesData(data); } public CachedSpaceStorage(final SpaceStorageImpl storage, final SocialStorageCacheService cacheService) { this.storage = storage; this.exoSpaceCache = cacheService.getSpaceCache(); this.exoRefSpaceCache = cacheService.getSpaceRefCache(); this.exoSpacesCountCache = cacheService.getSpacesCountCache(); this.exoSpacesCache = cacheService.getSpacesCache(); this.spaceCache = CacheType.SPACE.createFutureCache(exoSpaceCache); this.spaceRefCache = CacheType.SPACE_REF.createFutureCache(exoRefSpaceCache); this.spacesCountCache = CacheType.SPACES_COUNT.createFutureCache(exoSpacesCountCache); this.spacesCache = CacheType.SPACES.createFutureCache(exoSpacesCache); } private void cleanRef(SpaceData removed) { exoRefSpaceCache.remove(new SpaceRefKey(removed.getDisplayName())); exoRefSpaceCache.remove(new SpaceRefKey(null, removed.getPrettyName())); exoRefSpaceCache.remove(new SpaceRefKey(null, null, removed.getGroupId())); exoRefSpaceCache.remove(new SpaceRefKey(null, null, null, removed.getUrl())); } /** * {@inheritDoc} */ public Space getSpaceByDisplayName(final String spaceDisplayName) throws SpaceStorageException { // SpaceRefKey refKey = new SpaceRefKey(spaceDisplayName); // SpaceKey key = spaceRefCache.get( new ServiceContext<SpaceKey>() { public SpaceKey execute() { Space space = storage.getSpaceByDisplayName(spaceDisplayName); if (space != null) { SpaceKey key = new SpaceKey(space.getId()); exoSpaceCache.put(key, new SpaceData(space)); return key; } else { return null; } } }, refKey); // if (key != null) { return getSpaceById(key.getId()); } else { return null; } } /** * {@inheritDoc} */ public void saveSpace(final Space space, final boolean isNew) throws SpaceStorageException { // storage.saveSpace(space, isNew); // SpaceData removed = exoSpaceCache.remove(new SpaceKey(space.getId())); exoSpacesCountCache.clearCache(); exoSpacesCache.clearCache(); if (removed != null) { cleanRef(removed); } } /** * {@inheritDoc} */ public void deleteSpace(final String id) throws SpaceStorageException { // storage.deleteSpace(id); // SpaceData removed = exoSpaceCache.remove(new SpaceKey(id)); exoSpacesCountCache.clearCache(); exoSpacesCache.clearCache(); if (removed != null) { cleanRef(removed); } } /** * {@inheritDoc} */ public int getMemberSpacesCount(final String userId) throws SpaceStorageException { // SpaceFilterKey key = new SpaceFilterKey(userId, null, null); // return spacesCountCache.get( new ServiceContext<IntegerData>() { public IntegerData execute() { return new IntegerData(storage.getMemberSpacesCount(userId)); } }, key) .build(); } /** * {@inheritDoc} */ public int getMemberSpacesByFilterCount(final String userId, final SpaceFilter spaceFilter) { // SpaceFilterKey key = new SpaceFilterKey(userId, spaceFilter, SpaceType.MEMBER); // return spacesCountCache.get( new ServiceContext<IntegerData>() { public IntegerData execute() { return new IntegerData(storage.getMemberSpacesByFilterCount(userId, spaceFilter)); } }, key) .build(); } /** * {@inheritDoc} */ public List<Space> getMemberSpaces(final String userId) throws SpaceStorageException { return storage.getMemberSpaces(userId); } /** * {@inheritDoc} */ public List<Space> getMemberSpaces(final String userId, final long offset, final long limit) throws SpaceStorageException { // SpaceFilterKey key = new SpaceFilterKey(userId, null, SpaceType.MEMBER); ListSpacesKey listKey = new ListSpacesKey(key, offset, limit); // ListSpacesData keys = spacesCache.get( new ServiceContext<ListSpacesData>() { public ListSpacesData execute() { List<Space> got = storage.getMemberSpaces(userId, offset, limit); return buildIds(got); } }, listKey); // return buildSpaces(keys); } /** * {@inheritDoc} */ public List<Space> getMemberSpacesByFilter( final String userId, final SpaceFilter spaceFilter, final long offset, final long limit) { // SpaceFilterKey key = new SpaceFilterKey(userId, spaceFilter, SpaceType.MEMBER); ListSpacesKey listKey = new ListSpacesKey(key, offset, limit); // ListSpacesData keys = spacesCache.get( new ServiceContext<ListSpacesData>() { public ListSpacesData execute() { List<Space> got = storage.getMemberSpacesByFilter(userId, spaceFilter, offset, limit); return buildIds(got); } }, listKey); // return buildSpaces(keys); } /** * {@inheritDoc} */ public int getPendingSpacesCount(final String userId) throws SpaceStorageException { // SpaceFilterKey key = new SpaceFilterKey(userId, null, SpaceType.PENDING); // return spacesCountCache.get( new ServiceContext<IntegerData>() { public IntegerData execute() { return new IntegerData(storage.getPendingSpacesCount(userId)); } }, key) .build(); } /** * {@inheritDoc} */ public int getPendingSpacesByFilterCount(final String userId, final SpaceFilter spaceFilter) { // SpaceFilterKey key = new SpaceFilterKey(userId, spaceFilter, SpaceType.PENDING); // return spacesCountCache.get( new ServiceContext<IntegerData>() { public IntegerData execute() { return new IntegerData(storage.getPendingSpacesByFilterCount(userId, spaceFilter)); } }, key) .build(); } /** * {@inheritDoc} */ public List<Space> getPendingSpaces(final String userId) throws SpaceStorageException { return storage.getPendingSpaces(userId); } /** * {@inheritDoc} */ public List<Space> getPendingSpaces(final String userId, final long offset, final long limit) throws SpaceStorageException { // SpaceFilterKey key = new SpaceFilterKey(userId, null, SpaceType.PENDING); ListSpacesKey listKey = new ListSpacesKey(key, offset, limit); // ListSpacesData keys = spacesCache.get( new ServiceContext<ListSpacesData>() { public ListSpacesData execute() { List<Space> got = storage.getPendingSpaces(userId, offset, limit); return buildIds(got); } }, listKey); // return buildSpaces(keys); } /** * {@inheritDoc} */ public List<Space> getPendingSpacesByFilter( final String userId, final SpaceFilter spaceFilter, final long offset, final long limit) { // SpaceFilterKey key = new SpaceFilterKey(userId, spaceFilter, SpaceType.PENDING); ListSpacesKey listKey = new ListSpacesKey(key, offset, limit); // ListSpacesData keys = spacesCache.get( new ServiceContext<ListSpacesData>() { public ListSpacesData execute() { List<Space> got = storage.getPendingSpacesByFilter(userId, spaceFilter, offset, limit); return buildIds(got); } }, listKey); // return buildSpaces(keys); } /** * {@inheritDoc} */ public int getInvitedSpacesCount(final String userId) throws SpaceStorageException { // SpaceFilterKey key = new SpaceFilterKey(userId, null, SpaceType.INVITED); // return spacesCountCache.get( new ServiceContext<IntegerData>() { public IntegerData execute() { return new IntegerData(storage.getInvitedSpacesCount(userId)); } }, key) .build(); } /** * {@inheritDoc} */ public int getInvitedSpacesByFilterCount(final String userId, final SpaceFilter spaceFilter) { // SpaceFilterKey key = new SpaceFilterKey(userId, spaceFilter, SpaceType.INVITED); // return spacesCountCache.get( new ServiceContext<IntegerData>() { public IntegerData execute() { return new IntegerData(storage.getInvitedSpacesByFilterCount(userId, spaceFilter)); } }, key) .build(); } /** * {@inheritDoc} */ public List<Space> getInvitedSpaces(final String userId) throws SpaceStorageException { return storage.getInvitedSpaces(userId); } /** * {@inheritDoc} */ public List<Space> getInvitedSpaces(final String userId, final long offset, final long limit) throws SpaceStorageException { // SpaceFilterKey key = new SpaceFilterKey(userId, null, SpaceType.INVITED); ListSpacesKey listKey = new ListSpacesKey(key, offset, limit); // ListSpacesData keys = spacesCache.get( new ServiceContext<ListSpacesData>() { public ListSpacesData execute() { List<Space> got = storage.getInvitedSpaces(userId, offset, limit); return buildIds(got); } }, listKey); // return buildSpaces(keys); } /** * {@inheritDoc} */ public List<Space> getInvitedSpacesByFilter( final String userId, final SpaceFilter spaceFilter, final long offset, final long limit) { // SpaceFilterKey key = new SpaceFilterKey(userId, spaceFilter, SpaceType.INVITED); ListSpacesKey listKey = new ListSpacesKey(key, offset, limit); // ListSpacesData keys = spacesCache.get( new ServiceContext<ListSpacesData>() { public ListSpacesData execute() { List<Space> got = storage.getInvitedSpacesByFilter(userId, spaceFilter, offset, limit); return buildIds(got); } }, listKey); // return buildSpaces(keys); } /** * {@inheritDoc} */ public int getPublicSpacesCount(final String userId) throws SpaceStorageException { // SpaceFilterKey key = new SpaceFilterKey(userId, null, SpaceType.PUBLIC); // return spacesCountCache.get( new ServiceContext<IntegerData>() { public IntegerData execute() { return new IntegerData(storage.getPublicSpacesCount(userId)); } }, key) .build(); } /** * {@inheritDoc} */ public int getPublicSpacesByFilterCount(final String userId, final SpaceFilter spaceFilter) { // SpaceFilterKey key = new SpaceFilterKey(userId, spaceFilter, SpaceType.PUBLIC); // return spacesCountCache.get( new ServiceContext<IntegerData>() { public IntegerData execute() { return new IntegerData(storage.getPublicSpacesByFilterCount(userId, spaceFilter)); } }, key) .build(); } /** * {@inheritDoc} */ public List<Space> getPublicSpacesByFilter( final String userId, final SpaceFilter spaceFilter, final long offset, final long limit) { // SpaceFilterKey key = new SpaceFilterKey(userId, spaceFilter, SpaceType.PUBLIC); ListSpacesKey listKey = new ListSpacesKey(key, offset, limit); // ListSpacesData keys = spacesCache.get( new ServiceContext<ListSpacesData>() { public ListSpacesData execute() { List<Space> got = storage.getPublicSpacesByFilter(userId, spaceFilter, offset, limit); return buildIds(got); } }, listKey); // return buildSpaces(keys); } /** * {@inheritDoc} */ public List<Space> getPublicSpaces(final String userId) throws SpaceStorageException { return storage.getPublicSpaces(userId); } /** * {@inheritDoc} */ public List<Space> getPublicSpaces(final String userId, final long offset, final long limit) throws SpaceStorageException { // SpaceFilterKey key = new SpaceFilterKey(userId, null, SpaceType.PUBLIC); ListSpacesKey listKey = new ListSpacesKey(key, offset, limit); // ListSpacesData keys = spacesCache.get( new ServiceContext<ListSpacesData>() { public ListSpacesData execute() { List<Space> got = storage.getPublicSpaces(userId, offset, limit); return buildIds(got); } }, listKey); // return buildSpaces(keys); } /** * {@inheritDoc} */ public int getAccessibleSpacesCount(final String userId) throws SpaceStorageException { // SpaceFilterKey key = new SpaceFilterKey(userId, null, SpaceType.ACCESSIBLE); // return spacesCountCache.get( new ServiceContext<IntegerData>() { public IntegerData execute() { return new IntegerData(storage.getAccessibleSpacesCount(userId)); } }, key) .build(); } /** * {@inheritDoc} */ public int getAccessibleSpacesByFilterCount(final String userId, final SpaceFilter spaceFilter) { // SpaceFilterKey key = new SpaceFilterKey(userId, spaceFilter, SpaceType.ACCESSIBLE); // return spacesCountCache.get( new ServiceContext<IntegerData>() { public IntegerData execute() { return new IntegerData(storage.getAccessibleSpacesByFilterCount(userId, spaceFilter)); } }, key) .build(); } /** * {@inheritDoc} */ public List<Space> getAccessibleSpaces(final String userId) throws SpaceStorageException { return storage.getAccessibleSpaces(userId); } /** * {@inheritDoc} */ public List<Space> getAccessibleSpaces(final String userId, final long offset, final long limit) throws SpaceStorageException { // SpaceFilterKey key = new SpaceFilterKey(userId, null, SpaceType.ACCESSIBLE); ListSpacesKey listKey = new ListSpacesKey(key, offset, limit); // ListSpacesData keys = spacesCache.get( new ServiceContext<ListSpacesData>() { public ListSpacesData execute() { List<Space> got = storage.getAccessibleSpaces(userId, offset, limit); return buildIds(got); } }, listKey); // return buildSpaces(keys); } /** * {@inheritDoc} */ public List<Space> getAccessibleSpacesByFilter( final String userId, final SpaceFilter spaceFilter, final long offset, final long limit) { // SpaceFilterKey key = new SpaceFilterKey(userId, spaceFilter, SpaceType.ACCESSIBLE); ListSpacesKey listKey = new ListSpacesKey(key, offset, limit); // ListSpacesData keys = spacesCache.get( new ServiceContext<ListSpacesData>() { public ListSpacesData execute() { List<Space> got = storage.getAccessibleSpacesByFilter(userId, spaceFilter, offset, limit); return buildIds(got); } }, listKey); // return buildSpaces(keys); } /** * {@inheritDoc} */ public int getEditableSpacesCount(final String userId) throws SpaceStorageException { // SpaceFilterKey key = new SpaceFilterKey(userId, null, SpaceType.EDITABLE); // return spacesCountCache.get( new ServiceContext<IntegerData>() { public IntegerData execute() { return new IntegerData(storage.getEditableSpacesCount(userId)); } }, key) .build(); } /** * {@inheritDoc} */ public int getEditableSpacesByFilterCount(final String userId, final SpaceFilter spaceFilter) { // SpaceFilterKey key = new SpaceFilterKey(userId, spaceFilter, SpaceType.EDITABLE); // return spacesCountCache.get( new ServiceContext<IntegerData>() { public IntegerData execute() { return new IntegerData(storage.getEditableSpacesByFilterCount(userId, spaceFilter)); } }, key) .build(); } /** * {@inheritDoc} */ public List<Space> getEditableSpaces(final String userId) throws SpaceStorageException { return storage.getEditableSpaces(userId); } /** * {@inheritDoc} */ public List<Space> getEditableSpaces(final String userId, final long offset, final long limit) throws SpaceStorageException { // SpaceFilterKey key = new SpaceFilterKey(userId, null, SpaceType.EDITABLE); ListSpacesKey listKey = new ListSpacesKey(key, offset, limit); // ListSpacesData keys = spacesCache.get( new ServiceContext<ListSpacesData>() { public ListSpacesData execute() { List<Space> got = storage.getEditableSpaces(userId, offset, limit); return buildIds(got); } }, listKey); // return buildSpaces(keys); } /** * {@inheritDoc} */ public List<Space> getEditableSpacesByFilter( final String userId, final SpaceFilter spaceFilter, final long offset, final long limit) { // SpaceFilterKey key = new SpaceFilterKey(userId, spaceFilter, SpaceType.EDITABLE); ListSpacesKey listKey = new ListSpacesKey(key, offset, limit); // ListSpacesData keys = spacesCache.get( new ServiceContext<ListSpacesData>() { public ListSpacesData execute() { List<Space> got = storage.getEditableSpacesByFilter(userId, spaceFilter, offset, limit); return buildIds(got); } }, listKey); // return buildSpaces(keys); } /** * {@inheritDoc} */ public int getAllSpacesCount() throws SpaceStorageException { return storage.getAllSpacesCount(); } /** * {@inheritDoc} */ public List<Space> getAllSpaces() throws SpaceStorageException { return storage.getAllSpaces(); } /** * {@inheritDoc} */ public int getAllSpacesByFilterCount(final SpaceFilter spaceFilter) { // SpaceFilterKey key = new SpaceFilterKey(null, spaceFilter, null); // return spacesCountCache.get( new ServiceContext<IntegerData>() { public IntegerData execute() { return new IntegerData(storage.getAllSpacesByFilterCount(spaceFilter)); } }, key) .build(); } /** * {@inheritDoc} */ public List<Space> getSpaces(final long offset, final long limit) throws SpaceStorageException { // ListSpacesKey listKey = new ListSpacesKey(null, offset, limit); // ListSpacesData keys = spacesCache.get( new ServiceContext<ListSpacesData>() { public ListSpacesData execute() { List<Space> got = storage.getSpaces(offset, limit); return buildIds(got); } }, listKey); // return buildSpaces(keys); } /** * {@inheritDoc} */ public List<Space> getSpacesByFilter(final SpaceFilter spaceFilter, final long offset, final long limit) { // SpaceFilterKey key = new SpaceFilterKey(null, spaceFilter, null); ListSpacesKey listKey = new ListSpacesKey(key, offset, limit); // ListSpacesData keys = spacesCache.get( new ServiceContext<ListSpacesData>() { public ListSpacesData execute() { List<Space> got = storage.getSpacesByFilter(spaceFilter, offset, limit); return buildIds(got); } }, listKey); // return buildSpaces(keys); } /** * {@inheritDoc} */ public Space getSpaceById(final String id) throws SpaceStorageException { // SpaceKey key = new SpaceKey(id); // SpaceData data = spaceCache.get( new ServiceContext<SpaceData>() { public SpaceData execute() { Space space = storage.getSpaceById(id); if (space != null) { return new SpaceData(space); } else { return null; } } }, key); if (data != null) { return data.build(); } else { return null; } } /** * {@inheritDoc} */ public Space getSpaceByPrettyName(final String spacePrettyName) throws SpaceStorageException { // SpaceRefKey refKey = new SpaceRefKey(null, spacePrettyName); // SpaceKey key = spaceRefCache.get( new ServiceContext<SpaceKey>() { public SpaceKey execute() { Space space = storage.getSpaceByPrettyName(spacePrettyName); if (space != null) { SpaceKey key = new SpaceKey(space.getId()); exoSpaceCache.put(key, new SpaceData(space)); return key; } else { return null; } } }, refKey); // if (key != null) { return getSpaceById(key.getId()); } else { return null; } } /** * {@inheritDoc} */ public Space getSpaceByGroupId(final String groupId) throws SpaceStorageException { // SpaceRefKey refKey = new SpaceRefKey(null, null, groupId); // SpaceKey key = spaceRefCache.get( new ServiceContext<SpaceKey>() { public SpaceKey execute() { Space space = storage.getSpaceByGroupId(groupId); if (space != null) { SpaceKey key = new SpaceKey(space.getId()); exoSpaceCache.put(key, new SpaceData(space)); return key; } else { return null; } } }, refKey); // if (key != null) { return getSpaceById(key.getId()); } else { return null; } } /** * {@inheritDoc} */ public Space getSpaceByUrl(final String url) throws SpaceStorageException { // SpaceRefKey refKey = new SpaceRefKey(null, null, null, url); // SpaceKey key = spaceRefCache.get( new ServiceContext<SpaceKey>() { public SpaceKey execute() { Space space = storage.getSpaceByUrl(url); if (space != null) { SpaceKey key = new SpaceKey(space.getId()); exoSpaceCache.put(key, new SpaceData(space)); return key; } else { return null; } } }, refKey); // if (key != null) { return getSpaceById(key.getId()); } else { return null; } } }