View Javadoc
1   /*
2    * Copyright (C) 2003-2014 eXo Platform SAS.
3    *
4    * This program is free software: you can redistribute it and/or modify
5    * it under the terms of the GNU Affero General Public License as published by
6    * the Free Software Foundation, either version 3 of the License, or
7    * (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU Affero General Public License for more details.
13   *
14   * You should have received a copy of the GNU Affero General Public License
15   * along with this program. If not, see <http://www.gnu.org/licenses/>.
16   */
17  package org.exoplatform.services.cms.clipboard.impl;
18  
19  import java.util.HashMap;
20  import java.util.HashSet;
21  import java.util.Iterator;
22  import java.util.LinkedHashSet;
23  import java.util.Map;
24  import java.util.Set;
25  
26  import javax.jcr.PathNotFoundException;
27  import javax.jcr.RepositoryException;
28  
29  import org.exoplatform.container.xml.InitParams;
30  import org.exoplatform.services.cache.CacheService;
31  import org.exoplatform.services.cache.ExoCache;
32  import org.exoplatform.services.cms.clipboard.ClipboardService;
33  import org.exoplatform.services.cms.clipboard.jcr.model.ClipboardCommand;
34  import org.exoplatform.services.jcr.ext.common.SessionProvider;
35  import org.exoplatform.services.log.ExoLogger;
36  import org.exoplatform.services.log.Log;
37  import org.exoplatform.services.wcm.utils.WCMCoreUtils;
38  
39  /**
40   * Created by The eXo Platform SAS
41   * Author : eXoPlatform
42   *          exo@exoplatform.com
43   * Jan 28, 2014  
44   */
45  public class ClipboardServiceImpl implements ClipboardService {
46    
47    private static final Log       LOG  = ExoLogger.getLogger(ClipboardServiceImpl.class.getName());
48    private static final String CLIPBOARD_CACHE = "ecms.ClipboardServiceCache";
49    private static final String CLIPBOARD_CACHE_VIRTUAL = "ecms.ClipboardServiceCacheVirtual";
50    
51    private CacheService cacheService_;
52    
53    private Map<String, Map<String, ClipboardCommand>> repoLastCommand_;
54    
55    private int liveTime_;
56    private int maxSize_;
57  
58    public ClipboardServiceImpl(CacheService cacheService, InitParams initParams) {
59      this.cacheService_ = cacheService;
60      repoLastCommand_ = new HashMap<String, Map<String, ClipboardCommand>>();
61      liveTime_ = Integer.parseInt(initParams.getValueParam("liveTime").getValue());
62      maxSize_ = Integer.parseInt(initParams.getValueParam("maxSize").getValue());
63    }
64    
65    @Override
66    public void addClipboardCommand(String userId, ClipboardCommand command, boolean isVirtual) {
67      ExoCache<String, Set<ClipboardCommand>> virtualCache_ = getVirtualCache();
68      ExoCache<String, Set<ClipboardCommand>> cache_ = getCache();
69      Map<String, ClipboardCommand> lastCommand_ = getLastCommandMap();
70      ExoCache<String, Set<ClipboardCommand>> cache = isVirtual ? virtualCache_ : cache_;
71      Set<ClipboardCommand> commands = cache.get(userId);
72      if (commands != null) {
73        commands.add(command);
74      } else {
75        commands = new LinkedHashSet<ClipboardCommand>();
76        commands.add(command);
77        cache.put(userId, commands);
78      }
79      if (!isVirtual) {
80        lastCommand_.put(userId, command);
81      }
82    }
83  
84    @Override
85    public ClipboardCommand getLastClipboard(String userId) {
86      Map<String, ClipboardCommand> lastCommand_ = getLastCommandMap();
87      return lastCommand_.get(userId);
88    }
89  
90    @Override
91    public Set<ClipboardCommand> getClipboardList(String userId, boolean isVirtual) {
92      ExoCache<String, Set<ClipboardCommand>> virtualCache_ = getVirtualCache();
93      ExoCache<String, Set<ClipboardCommand>> cache_ = getCache();
94      
95      ExoCache<String, Set<ClipboardCommand>> cache = isVirtual ? virtualCache_ : cache_;
96      Set<ClipboardCommand> ret = cache.get(userId);
97      boolean isUpdate = false;
98      Map<String, ClipboardCommand> lastCommandMap = getLastCommandMap();
99      ClipboardCommand cmd = lastCommandMap.get(userId);
100     if (ret != null){
101       Set<ClipboardCommand> removedCommands = new HashSet<ClipboardCommand>();
102       for (Iterator<ClipboardCommand> commands = ret.iterator();commands.hasNext();){
103         ClipboardCommand command = commands.next();
104         if (!isExistingNode(command)) {
105           removedCommands.add(command);
106           if (command.equals(cmd)) {
107             isUpdate = true;
108           }
109         }
110       }
111       ret.removeAll(removedCommands);
112       //update last command if the node in last command was removed
113       if (isUpdate) {
114       ClipboardCommand newLastCommand = null;
115       for (ClipboardCommand command: ret) newLastCommand = command;
116       lastCommandMap.put(userId, newLastCommand);
117       }
118       return new LinkedHashSet<ClipboardCommand>(ret);
119     } else {
120       return new LinkedHashSet<ClipboardCommand>();
121     } 
122   }
123 
124   @Override
125   public void clearClipboardList(String userId, boolean isVirtual) {
126     ExoCache<String, Set<ClipboardCommand>> virtualCache_ = getVirtualCache();
127     ExoCache<String, Set<ClipboardCommand>> cache_ = getCache();
128     Map<String, ClipboardCommand> lastCommand_ = getLastCommandMap();
129     
130     ExoCache<String, Set<ClipboardCommand>> cache = isVirtual ? virtualCache_ : cache_;
131     Set<ClipboardCommand> commands = cache.get(userId);
132     if (commands != null) {
133       commands.clear();
134     }
135     lastCommand_.remove(userId);
136   }
137   
138   private ExoCache<String, Set<ClipboardCommand>> getVirtualCache() {
139     ExoCache<String, Set<ClipboardCommand>> ret = cacheService_.getCacheInstance(CLIPBOARD_CACHE_VIRTUAL + getRepoName());
140     ret.setLiveTime(liveTime_);
141     ret.setMaxSize(maxSize_);
142     return ret;
143   }
144   
145   private ExoCache<String, Set<ClipboardCommand>> getCache() {
146     ExoCache<String, Set<ClipboardCommand>> ret = cacheService_.getCacheInstance(CLIPBOARD_CACHE + getRepoName());
147     ret.setLiveTime(liveTime_);
148     ret.setMaxSize(maxSize_);
149     return ret;
150   }
151   
152   private Map<String, ClipboardCommand> getLastCommandMap() {
153     Map<String, ClipboardCommand> ret = repoLastCommand_.get(getRepoName());
154     if (ret == null) {
155       ret = new HashMap<String, ClipboardCommand>();
156       repoLastCommand_.put(getRepoName(), ret);
157     }
158     return ret;
159   }
160   
161   private String getRepoName() {
162     return WCMCoreUtils.getRepository().getConfiguration().getName();
163   }
164   /**
165    * check the node in a ClipboardComand is existing or not
166    * @param ClipboardCommand
167    * @return true if the node exist else false ( node was deleted)
168    */
169   private boolean isExistingNode(ClipboardCommand command) {
170     SessionProvider sessionProvider = SessionProvider.createSystemProvider();
171     String wsName = command.getWorkspace();
172     String nodePath = command.getSrcPath();
173     try {
174       sessionProvider.getSession(wsName,WCMCoreUtils.getRepository()).getItem(nodePath);
175     } catch(PathNotFoundException e) {
176       return false;
177     } catch (RepositoryException re) {
178       LOG.debug("problem while checking the existing of Node");
179     } finally {
180       sessionProvider.close();
181     }
182     return true;
183   }
184 
185   @Override
186   public void removeClipboardCommand(String userId, ClipboardCommand command) {
187     ExoCache<String, Set<ClipboardCommand>> virtualCache_ = getVirtualCache();
188     ExoCache<String, Set<ClipboardCommand>> cache_ = getCache();
189 //    ExoCache<String, Set<ClipboardCommand>> cache = isVirtual ? virtualCache_ : cache_;
190     Set<ClipboardCommand> allCommands = cache_.get(userId);
191     Set<ClipboardCommand> virtualCommands = virtualCache_.get(userId);
192     Map<String, ClipboardCommand> lastCommand_ = getLastCommandMap();
193     if (allCommands != null) {
194       allCommands.remove(command);
195     }
196     // remove virtual command if is multiple copy
197     if (virtualCommands != null) {
198       virtualCommands.remove(command);
199     }
200     // if removed command is last command, update last command
201     Set<ClipboardCommand> commands = getClipboardList(userId, false);
202     if (lastCommand_.containsValue(command)) {
203       ClipboardCommand newLastCommand = null;
204       for (ClipboardCommand cmd : commands) newLastCommand = cmd;
205       lastCommand_.put(userId, newLastCommand);
206     }
207   }
208 }