ClipboardServiceImpl.java
/*
* Copyright (C) 2003-2014 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.services.cms.clipboard.impl;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import org.exoplatform.container.xml.InitParams;
import org.exoplatform.services.cache.CacheService;
import org.exoplatform.services.cache.ExoCache;
import org.exoplatform.services.cms.clipboard.ClipboardService;
import org.exoplatform.services.cms.clipboard.jcr.model.ClipboardCommand;
import org.exoplatform.services.jcr.ext.common.SessionProvider;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.wcm.utils.WCMCoreUtils;
/**
* Created by The eXo Platform SAS
* Author : eXoPlatform
* exo@exoplatform.com
* Jan 28, 2014
*/
public class ClipboardServiceImpl implements ClipboardService {
private static final Log LOG = ExoLogger.getLogger(ClipboardServiceImpl.class.getName());
private static final String CLIPBOARD_CACHE = "ecms.ClipboardServiceCache";
private static final String CLIPBOARD_CACHE_VIRTUAL = "ecms.ClipboardServiceCacheVirtual";
private CacheService cacheService_;
private Map<String, Map<String, ClipboardCommand>> repoLastCommand_;
private int liveTime_;
private int maxSize_;
public ClipboardServiceImpl(CacheService cacheService, InitParams initParams) {
this.cacheService_ = cacheService;
repoLastCommand_ = new HashMap<String, Map<String, ClipboardCommand>>();
liveTime_ = Integer.parseInt(initParams.getValueParam("liveTime").getValue());
maxSize_ = Integer.parseInt(initParams.getValueParam("maxSize").getValue());
}
@Override
public void addClipboardCommand(String userId, ClipboardCommand command, boolean isVirtual) {
ExoCache<String, Set<ClipboardCommand>> virtualCache_ = getVirtualCache();
ExoCache<String, Set<ClipboardCommand>> cache_ = getCache();
Map<String, ClipboardCommand> lastCommand_ = getLastCommandMap();
ExoCache<String, Set<ClipboardCommand>> cache = isVirtual ? virtualCache_ : cache_;
Set<ClipboardCommand> commands = cache.get(userId);
if (commands != null) {
commands.add(command);
} else {
commands = new LinkedHashSet<ClipboardCommand>();
commands.add(command);
cache.put(userId, commands);
}
if (!isVirtual) {
lastCommand_.put(userId, command);
}
}
@Override
public ClipboardCommand getLastClipboard(String userId) {
Map<String, ClipboardCommand> lastCommand_ = getLastCommandMap();
return lastCommand_.get(userId);
}
@Override
public Set<ClipboardCommand> getClipboardList(String userId, boolean isVirtual) {
ExoCache<String, Set<ClipboardCommand>> virtualCache_ = getVirtualCache();
ExoCache<String, Set<ClipboardCommand>> cache_ = getCache();
ExoCache<String, Set<ClipboardCommand>> cache = isVirtual ? virtualCache_ : cache_;
Set<ClipboardCommand> ret = cache.get(userId);
boolean isUpdate = false;
Map<String, ClipboardCommand> lastCommandMap = getLastCommandMap();
ClipboardCommand cmd = lastCommandMap.get(userId);
if (ret != null){
Set<ClipboardCommand> removedCommands = new HashSet<ClipboardCommand>();
for (Iterator<ClipboardCommand> commands = ret.iterator();commands.hasNext();){
ClipboardCommand command = commands.next();
if (!isExistingNode(command)) {
removedCommands.add(command);
if (command.equals(cmd)) {
isUpdate = true;
}
}
}
ret.removeAll(removedCommands);
//update last command if the node in last command was removed
if (isUpdate) {
ClipboardCommand newLastCommand = null;
for (ClipboardCommand command: ret) newLastCommand = command;
lastCommandMap.put(userId, newLastCommand);
}
return new LinkedHashSet<ClipboardCommand>(ret);
} else {
return new LinkedHashSet<ClipboardCommand>();
}
}
@Override
public void clearClipboardList(String userId, boolean isVirtual) {
ExoCache<String, Set<ClipboardCommand>> virtualCache_ = getVirtualCache();
ExoCache<String, Set<ClipboardCommand>> cache_ = getCache();
Map<String, ClipboardCommand> lastCommand_ = getLastCommandMap();
ExoCache<String, Set<ClipboardCommand>> cache = isVirtual ? virtualCache_ : cache_;
Set<ClipboardCommand> commands = cache.get(userId);
if (commands != null) {
commands.clear();
}
lastCommand_.remove(userId);
}
private ExoCache<String, Set<ClipboardCommand>> getVirtualCache() {
ExoCache<String, Set<ClipboardCommand>> ret = cacheService_.getCacheInstance(CLIPBOARD_CACHE_VIRTUAL + getRepoName());
ret.setLiveTime(liveTime_);
ret.setMaxSize(maxSize_);
return ret;
}
private ExoCache<String, Set<ClipboardCommand>> getCache() {
ExoCache<String, Set<ClipboardCommand>> ret = cacheService_.getCacheInstance(CLIPBOARD_CACHE + getRepoName());
ret.setLiveTime(liveTime_);
ret.setMaxSize(maxSize_);
return ret;
}
private Map<String, ClipboardCommand> getLastCommandMap() {
Map<String, ClipboardCommand> ret = repoLastCommand_.get(getRepoName());
if (ret == null) {
ret = new HashMap<String, ClipboardCommand>();
repoLastCommand_.put(getRepoName(), ret);
}
return ret;
}
private String getRepoName() {
return WCMCoreUtils.getRepository().getConfiguration().getName();
}
/**
* check the node in a ClipboardComand is existing or not
* @param ClipboardCommand
* @return true if the node exist else false ( node was deleted)
*/
private boolean isExistingNode(ClipboardCommand command) {
SessionProvider sessionProvider = SessionProvider.createSystemProvider();
String wsName = command.getWorkspace();
String nodePath = command.getSrcPath();
try {
sessionProvider.getSession(wsName,WCMCoreUtils.getRepository()).getItem(nodePath);
} catch(PathNotFoundException e) {
return false;
} catch (RepositoryException re) {
LOG.debug("problem while checking the existing of Node");
} finally {
sessionProvider.close();
}
return true;
}
@Override
public void removeClipboardCommand(String userId, ClipboardCommand command) {
ExoCache<String, Set<ClipboardCommand>> virtualCache_ = getVirtualCache();
ExoCache<String, Set<ClipboardCommand>> cache_ = getCache();
// ExoCache<String, Set<ClipboardCommand>> cache = isVirtual ? virtualCache_ : cache_;
Set<ClipboardCommand> allCommands = cache_.get(userId);
Set<ClipboardCommand> virtualCommands = virtualCache_.get(userId);
Map<String, ClipboardCommand> lastCommand_ = getLastCommandMap();
if (allCommands != null) {
allCommands.remove(command);
}
// remove virtual command if is multiple copy
if (virtualCommands != null) {
virtualCommands.remove(command);
}
// if removed command is last command, update last command
Set<ClipboardCommand> commands = getClipboardList(userId, false);
if (lastCommand_.containsValue(command)) {
ClipboardCommand newLastCommand = null;
for (ClipboardCommand cmd : commands) newLastCommand = cmd;
lastCommand_.put(userId, newLastCommand);
}
}
}