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.wcm.ext.component.document.service;
18  
19  import org.exoplatform.ecm.utils.permission.PermissionUtil;
20  import org.exoplatform.services.cms.BasePath;
21  import org.exoplatform.services.cms.link.LinkManager;
22  import org.exoplatform.services.jcr.RepositoryService;
23  import org.exoplatform.services.jcr.access.PermissionType;
24  import org.exoplatform.services.jcr.core.ExtendedNode;
25  import org.exoplatform.services.jcr.core.ManageableRepository;
26  import org.exoplatform.services.jcr.ext.app.SessionProviderService;
27  import org.exoplatform.services.jcr.ext.common.SessionProvider;
28  import org.exoplatform.services.jcr.ext.hierarchy.NodeHierarchyCreator;
29  import org.exoplatform.services.log.ExoLogger;
30  import org.exoplatform.services.log.Log;
31  import org.exoplatform.services.wcm.core.NodetypeConstant;
32  import org.exoplatform.services.wcm.utils.WCMCoreUtils;
33  import org.exoplatform.social.core.activity.model.ExoSocialActivity;
34  import org.exoplatform.wcm.ext.component.activity.listener.Utils;
35  
36  import javax.jcr.*;
37  
38  import org.picocontainer.Startable;
39  
40  
41  /**
42   * Created by The eXo Platform SAS
43   * Author : eXoPlatform
44   *          exo@exoplatform.com
45   * Nov 19, 2014  
46   */
47  public class ShareDocumentService implements IShareDocumentService, Startable{
48    private static final Log    LOG                 = ExoLogger.getLogger(ShareDocumentService.class);
49  
50    public static final String MIX_PRIVILEGEABLE          = "exo:privilegeable";
51    private RepositoryService repoService;
52    private SessionProviderService sessionProviderService;
53    private LinkManager linkManager;
54    public ShareDocumentService(RepositoryService _repoService,
55                                LinkManager _linkManager,
56                                //IdentityManager _identityManager,
57                                SessionProviderService _sessionProviderService){
58      this.repoService = _repoService;
59      this.sessionProviderService = _sessionProviderService;
60      this.linkManager = _linkManager;
61  
62    }
63  
64    /* (non-Javadoc)
65     * @see org.exoplatform.ecm.webui.component.explorer.popup.service.IShareDocumentService#publishDocumentToSpace(java.lang.String, javax.jcr.Node, java.lang.String, java.lang.String)
66     */
67    @Override
68    public String publishDocumentToSpace(String space, Node currentNode, String comment,String perm) {
69      Node rootSpace = null;
70      Node shared = null;
71      try {
72        SessionProvider sessionProvider = sessionProviderService.getSystemSessionProvider(null);
73        ManageableRepository repository = repoService.getCurrentRepository();
74        Session session = sessionProvider.getSession(repository.getConfiguration().getDefaultWorkspaceName(), repository);
75        //add symlink to destination space
76        NodeHierarchyCreator nodeCreator = WCMCoreUtils.getService(NodeHierarchyCreator.class);
77        nodeCreator.getJcrPath(BasePath.CMS_GROUPS_PATH);
78  
79        rootSpace = (Node) session.getItem(nodeCreator.getJcrPath(BasePath.CMS_GROUPS_PATH) + space);
80        rootSpace = rootSpace.getNode("Documents");
81        if(!rootSpace.hasNode("Shared")){
82          shared = rootSpace.addNode("Shared");
83        }else{
84          shared = rootSpace.getNode("Shared");
85        }
86        if(currentNode.isNodeType(NodetypeConstant.EXO_SYMLINK)) currentNode = linkManager.getTarget(currentNode);
87        //Update permission
88        String tempPerms = perm.toString();//Avoid ref back to UIFormSelectBox options
89        if(!tempPerms.equals(PermissionType.READ)) tempPerms = PermissionType.READ+","+PermissionType.ADD_NODE+","+PermissionType.SET_PROPERTY+","+PermissionType.REMOVE;
90        if(PermissionUtil.canChangePermission(currentNode)){
91          setSpacePermission(currentNode, space, tempPerms.split(","));
92        }else if(PermissionUtil.canRead(currentNode)){
93          SessionProvider systemSessionProvider = SessionProvider.createSystemProvider();
94          Session systemSession = systemSessionProvider.getSession(session.getWorkspace().getName(), repository);
95          Node _node= (Node)systemSession.getItem(currentNode.getPath());
96          setSpacePermission(_node, space, tempPerms.split(","));
97        }
98        currentNode.getSession().save();
99        Node link = linkManager.createLink(shared, currentNode);
100       rootSpace.save();
101       //Share activity
102       try {
103         ExoSocialActivity activity = null;
104         if(currentNode.getPrimaryNodeType().getName().equals(NodetypeConstant.NT_FILE)){
105           activity = Utils.createShareActivity(link, "", Utils.SHARE_FILE, comment, perm);
106         }else{
107           activity = Utils.createShareActivity(link,"", Utils.SHARE_CONTENT,comment, perm);
108         }
109         link.save();
110         return activity.getId();
111       } catch (Exception e1) {
112         if(LOG.isErrorEnabled())
113           LOG.error(e1.getMessage(), e1);
114       }
115     } catch (RepositoryException e) {
116       if(LOG.isErrorEnabled())
117         LOG.error(e.getMessage(), e);
118     } catch (Exception e) {
119       if(LOG.isErrorEnabled())
120         LOG.error(e.getMessage(), e);
121     }
122     return "";
123   }
124 
125   /* (non-Javadoc)
126    * @see org.exoplatform.ecm.webui.component.explorer.popup.service.IShareDocumentService#publishDocumentToUser(java.lang.String, javax.jcr.Node, java.lang.String, java.lang.String)
127    */
128   @Override
129   public void publishDocumentToUser(String user, Node currentNode, String comment,String perm) {
130     Node userPrivateNode = null;
131     Node shared = null;
132     try {
133       SessionProvider sessionProvider = sessionProviderService.getSystemSessionProvider(null);
134       ManageableRepository repository = repoService.getCurrentRepository();
135       Session session = sessionProvider.getSession(repository.getConfiguration().getDefaultWorkspaceName(), repository);
136       //add symlink to destination user
137       userPrivateNode = getPrivateUserNode(sessionProvider, user);
138       userPrivateNode = userPrivateNode.getNode("Documents");
139       if(!userPrivateNode.hasNode("Shared")){
140         shared = userPrivateNode.addNode("Shared");
141       }else{
142         shared = userPrivateNode.getNode("Shared");
143       }
144       if(currentNode.isNodeType(NodetypeConstant.EXO_SYMLINK)) currentNode = linkManager.getTarget(currentNode);
145       //Update permission
146       String tempPerms = perm.toString();//Avoid ref back to UIFormSelectBox options
147       if(!tempPerms.equals(PermissionType.READ)) tempPerms = PermissionType.READ+","+PermissionType.ADD_NODE+","+PermissionType.SET_PROPERTY+","+PermissionType.REMOVE;
148       if(PermissionUtil.canChangePermission(currentNode)){
149         setUserPermission(currentNode, user, tempPerms.split(","));
150       }else if(PermissionUtil.canRead(currentNode)){
151         SessionProvider systemSessionProvider = SessionProvider.createSystemProvider();
152         Session systemSession = systemSessionProvider.getSession(session.getWorkspace().getName(), repository);
153         Node _node= (Node)systemSession.getItem(currentNode.getPath());
154         setUserPermission(_node, user, tempPerms.split(","));
155       }
156       currentNode.getSession().save();
157       Node link = linkManager.createLink(shared, currentNode);
158       userPrivateNode.save();
159     } catch (RepositoryException e) {
160       if(LOG.isErrorEnabled())
161         LOG.error(e.getMessage(), e);
162     } catch (Exception e) {
163       if(LOG.isErrorEnabled())
164         LOG.error(e.getMessage(), e);
165     }
166   }
167 
168   private Node getPrivateUserNode(SessionProvider sessionProvider, String user) throws Exception,
169                                                                                 PathNotFoundException,
170                                                                                 RepositoryException {
171     NodeHierarchyCreator nodeCreator = WCMCoreUtils.getService(NodeHierarchyCreator.class);
172     String privateRelativePath = nodeCreator.getJcrPath("userPrivate");
173     Node userNode = nodeCreator.getUserNode(sessionProvider, user);
174     return userNode.getNode(privateRelativePath);
175   }
176 
177   /* (non-Javadoc)
178    * @see org.exoplatform.ecm.webui.component.explorer.popup.service.IShareDocumentService#unpublishDocumentToUser(java.lang.String, javax.jcr.ExtendedNode)
179    */
180   @Override
181   public void unpublishDocumentToUser(String user, ExtendedNode node) {
182     Node userPrivateNode = null;
183     Node sharedNode = null;
184     try {
185       SessionProvider sessionProvider = sessionProviderService.getSystemSessionProvider(null);
186       //remove symlink from destination user
187       userPrivateNode = getPrivateUserNode(sessionProvider, user);
188       userPrivateNode = userPrivateNode.getNode("Documents");
189       sharedNode = userPrivateNode.getNode("Shared");
190       sharedNode.getNode(node.getName()).remove();
191 
192       removeUserPermission(node, user);
193 
194       node.getSession().save();
195       userPrivateNode.save();
196 
197       }  catch (RepositoryException e) {
198       if (LOG.isErrorEnabled())
199         LOG.error(e.getMessage(), e);
200     } catch (Exception e) {
201       if(LOG.isErrorEnabled())
202         LOG.error(e.getMessage(), e);
203     }
204   }
205 
206   /* (non-Javadoc)
207    * @see org.exoplatform.ecm.webui.component.explorer.popup.service.IShareDocumentService#unpublishDocumentToSpace(java.lang.String, javax.jcr.ExtendedNode)
208    */
209   @Override
210   public void unpublishDocumentToSpace(String space, ExtendedNode node) {
211     Node rootSpace = null;
212     Node sharedNode = null;
213     try {
214       SessionProvider sessionProvider = sessionProviderService.getSystemSessionProvider(null);
215       ManageableRepository repository = repoService.getCurrentRepository();
216       Session session = sessionProvider.getSession(repository.getConfiguration().getDefaultWorkspaceName(), repository);
217       //remove symlink to destination space
218       NodeHierarchyCreator nodeCreator = WCMCoreUtils.getService(NodeHierarchyCreator.class);
219 
220       rootSpace = (Node) session.getItem(nodeCreator.getJcrPath(BasePath.CMS_GROUPS_PATH) + space);
221       rootSpace = rootSpace.getNode("Documents");
222       if (rootSpace.hasNode("Shared")) {
223         sharedNode = rootSpace.getNode("Shared");
224         sharedNode.getNode(node.getName()).remove();
225         rootSpace.save();
226       }
227 
228       removeSpacePermission(node, space);
229       node.getSession().save();
230     } catch (RepositoryException e) {
231       if(LOG.isErrorEnabled())
232         LOG.error(e.getMessage(), e);
233     } catch (Exception e) {
234       if(LOG.isErrorEnabled())
235         LOG.error(e.getMessage(), e);
236     }
237   }
238 
239   private void removeSpacePermission(ExtendedNode node, String space) {
240     try {
241       node.removePermission("*:" + space);
242       node.save();
243     } catch (RepositoryException e) {
244       if(LOG.isErrorEnabled())
245         LOG.error(e.getMessage(), e);
246     }
247   }
248 
249   private void removeUserPermission(ExtendedNode node, String user) {
250     try {
251       node.removePermission(user);
252       node.save();
253     } catch (RepositoryException e) {
254       if(LOG.isErrorEnabled())
255         LOG.error(e.getMessage(), e);
256     }
257   }
258 
259   private String getMimeType(Node node) {
260     try {
261       if (node.getPrimaryNodeType().getName().equals(NodetypeConstant.NT_FILE)) {
262         if (node.hasNode(NodetypeConstant.JCR_CONTENT))
263           return node.getNode(NodetypeConstant.JCR_CONTENT)
264               .getProperty(NodetypeConstant.JCR_MIME_TYPE)
265               .getString();
266       }
267     } catch (RepositoryException e) {
268       if(LOG.isErrorEnabled())
269         LOG.error(e.getMessage(), e);
270     }
271     return "";
272   }
273 
274   /**
275    * Grant view for parent folder when share a document
276    * We need grant assess right for parent in case editing the shared documents
277    * @param currentNode
278    * @param memberShip
279    * @param permissions
280    * @throws Exception
281    */
282   private void setSpacePermission(Node currentNode, String memberShip, String[] permissions) throws Exception{
283     ExtendedNode node = (ExtendedNode) currentNode;
284     if(node.canAddMixin(MIX_PRIVILEGEABLE))node.addMixin(MIX_PRIVILEGEABLE);
285     node.setPermission("*:" + memberShip, permissions);
286     node.save();
287   }
288 
289   /**
290    * Grant view for parent folder when share a document
291    * We need grant assess right for parent in case editing the shared documents
292    * @param currentNode
293    * @param username
294    * @param permissions
295    * @throws Exception
296    */
297   private void setUserPermission(Node currentNode, String username, String[] permissions) throws Exception{
298     ExtendedNode node = (ExtendedNode) currentNode;
299     if(node.canAddMixin(MIX_PRIVILEGEABLE))node.addMixin(MIX_PRIVILEGEABLE);
300     node.setPermission(username, permissions);
301     node.save();
302   }
303 
304   @Override
305   public void start() {
306     // TODO Auto-generated method stub
307 
308   }
309 
310   @Override
311   public void stop() {
312     // TODO Auto-generated method stub
313 
314   }
315 }