View Javadoc
1   /*
2    * Copyright (C) 2003-2008 eXo Platform SAS.
3    *
4    * This program is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Affero General Public License
6    * as published by the Free Software Foundation; either version 3
7    * of the License, or (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 General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program; if not, see<http://www.gnu.org/licenses/>.
16   */
17  package org.exoplatform.services.cms.documents.impl;
18  
19  import java.util.ArrayList;
20  import java.util.HashMap;
21  import java.util.List;
22  import java.util.Map;
23  
24  import javax.jcr.ItemNotFoundException;
25  import javax.jcr.Node;
26  import javax.jcr.NodeIterator;
27  import javax.jcr.PathNotFoundException;
28  import javax.jcr.RepositoryException;
29  
30  import org.exoplatform.services.cms.documents.FavoriteService;
31  import org.exoplatform.services.cms.link.LinkManager;
32  import org.exoplatform.services.jcr.access.PermissionType;
33  import org.exoplatform.services.jcr.core.ExtendedNode;
34  import org.exoplatform.services.jcr.ext.app.SessionProviderService;
35  import org.exoplatform.services.jcr.ext.hierarchy.NodeHierarchyCreator;
36  import org.exoplatform.services.organization.OrganizationService;
37  import org.exoplatform.services.wcm.core.NodetypeConstant;
38  import org.exoplatform.services.wcm.utils.WCMCoreUtils;
39  
40  /**
41   * Created by The eXo Platform SARL
42   * Author : Dang Van Minh
43   *          minh.dang@exoplatform.com
44   * Nov 16, 2009
45   * 10:02:04 AM
46   */
47  public class FavoriteServiceImpl implements FavoriteService {
48  
49    private static final String EXO_PRIVILEGEABLE = "exo:privilegeable";
50    private static final String EXO_FAVORITEFOLDER = "exo:favoriteFolder";
51    private static final String NT_UNSTRUCTURED = "nt:unstructured";
52    private static final String FAVORITE_ALIAS = "userPrivateFavorites";
53  
54    private NodeHierarchyCreator nodeHierarchyCreator;
55    private LinkManager linkManager;
56    private SessionProviderService sessionProviderService;
57  
58    private OrganizationService    organizationService;
59  
60    public FavoriteServiceImpl(NodeHierarchyCreator nodeHierarchyCreator, LinkManager linkManager,
61        SessionProviderService sessionProviderService, OrganizationService organizationService) {
62      this.nodeHierarchyCreator = nodeHierarchyCreator;
63      this.linkManager = linkManager;
64      this.sessionProviderService = sessionProviderService;
65      this.organizationService = organizationService;
66    }
67  
68    /**
69     * {@inheritDoc}
70     */
71    public void addFavorite(Node node, String userName) throws Exception {
72      // check if node is symlink
73      if (linkManager.isLink(node)) return;
74  
75      // check if node has already been favorite node of current user
76      Node userFavoriteNode = null;
77      try {
78        userFavoriteNode = getUserFavoriteFolder(userName);
79        if (userFavoriteNode == null) {
80          return;
81        }
82      } catch (PathNotFoundException e) {
83        userFavoriteNode = createFavoriteFolder(userName);
84      }
85  
86      NodeIterator nodeIter = userFavoriteNode.getNodes();
87      while (nodeIter.hasNext()) {
88        Node childNode = nodeIter.nextNode();
89        if (linkManager.isLink(childNode)) {
90          Node targetNode = getTargetNode(childNode);
91          if (node.isSame(targetNode)) return;
92        }
93      }
94      // add favorite symlink
95      linkManager.createLink(userFavoriteNode, NodetypeConstant.EXO_SYMLINK, node, node.getName() + ".lnk");
96      userFavoriteNode.getSession().save();
97    }
98  
99    /**
100    * {@inheritDoc}
101    */
102   public List<Node> getAllFavoriteNodesByUser(String workspace, String repository, String userName) throws Exception {
103     List<Node> ret = new ArrayList<Node>();
104     Node userFavoriteNode = getUserFavoriteFolder(userName);
105     if (userFavoriteNode != null) {
106       NodeIterator nodeIter = userFavoriteNode.getNodes();
107       while (nodeIter.hasNext()) {
108         Node childNode = nodeIter.nextNode();
109         if (linkManager.isLink(childNode)) {
110           Node targetNode = getTargetNode(childNode);
111           if (targetNode != null)
112             ret.add(targetNode);
113         }
114       }
115     }
116     return ret;
117   }
118 
119   /**
120    * {@inheritDoc}
121    */
122   public void removeFavorite(Node node, String userName) throws Exception {
123     Node targetNode = null;
124 
125     // check if node is symlink
126     if (linkManager.isLink(node)) {
127       targetNode = getTargetNode(node);
128       if (targetNode != null) removeFavorite(targetNode, userName);
129     } else {
130       // remove favorite
131       Node userFavoriteNode = getUserFavoriteFolder(userName);
132       if(userFavoriteNode != null) { // to avoid NPE
133         NodeIterator nodeIter = userFavoriteNode.getNodes();
134         while (nodeIter.hasNext()) {
135           Node childNode = nodeIter.nextNode();
136           if (linkManager.isLink(childNode)) {
137            targetNode = getTargetNode(childNode);
138             if (node.isSame(targetNode)) {
139               childNode.remove();
140               userFavoriteNode.save();
141               return;
142             }
143           }
144         }
145       }
146     }
147   }
148 
149   public boolean isFavoriter(String userName, Node node) throws Exception {
150     LinkManager lnkManager = WCMCoreUtils.getService(LinkManager.class);
151 
152     if (lnkManager.isLink(node) && lnkManager.isTargetReachable(node)) {
153       node = lnkManager.getTarget(node);
154     }
155 
156     Node userFavoriteNode = null;
157     try {
158       userFavoriteNode = getUserFavoriteFolder(userName);
159       if(userFavoriteNode == null) {
160         return false;
161       }
162     } catch (PathNotFoundException e) {
163       return false;
164     }
165 
166     NodeIterator nodeIter = userFavoriteNode.getNodes();
167     while (nodeIter.hasNext()) {
168       Node childNode = nodeIter.nextNode();
169       if (linkManager.isLink(childNode)) {
170         Node targetNode = getTargetNode(childNode);
171         if (node.isSame(targetNode)) {
172           return true;
173         }
174       }
175     }
176     return false;
177   }
178 
179   private Node getUserFavoriteFolder(String userName) throws Exception {
180     if (organizationService.getUserHandler().findUserByName(userName) == null) {
181       return null;
182     }
183     Node userNode =
184       nodeHierarchyCreator.getUserNode(sessionProviderService.getSystemSessionProvider(null), userName);
185     String favoritePath = nodeHierarchyCreator.getJcrPath(FAVORITE_ALIAS);
186     if (favoritePath == null || !userNode.hasNode(favoritePath)) {
187       return null;
188     }
189     return userNode.getNode(favoritePath);
190   }
191 
192   private Node createFavoriteFolder(String userName) throws Exception {
193     // Get default favorite path
194     Node userNode =
195       nodeHierarchyCreator.getUserNode(sessionProviderService.getSystemSessionProvider(null), userName);
196     String userFavoritePath = nodeHierarchyCreator.getJcrPath(FAVORITE_ALIAS);
197 
198     // Create favorite path
199     Node userFavoriteNode = userNode.addNode(userFavoritePath, NT_UNSTRUCTURED);
200 
201     // Add Mixin types
202     userFavoriteNode.addMixin(EXO_PRIVILEGEABLE);
203     userFavoriteNode.addMixin(EXO_FAVORITEFOLDER);
204 
205     // Add permission
206     Map<String, String[]> permissionsMap = new HashMap<String, String[]>();
207     permissionsMap.put(userName, PermissionType.ALL);
208     ((ExtendedNode)userFavoriteNode).setPermissions(permissionsMap);
209     userNode.save();
210 
211     return userFavoriteNode;
212   }
213 
214   /**
215    * Get Target Node
216    * @param linkNode Link Node
217    * @return Real Node
218    */
219   private Node getTargetNode(Node linkNode) {
220     Node targetNode = null;
221     try {
222       targetNode = linkManager.getTarget(linkNode);
223     } catch (ItemNotFoundException e) {
224       targetNode = null;
225     } catch (RepositoryException e) {
226       targetNode = null;
227     }
228     return targetNode;
229   }
230 }