View Javadoc
1   /*
2    * Copyright (C) 2003-2012 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.ecm.webui.component.admin.unlock;
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.Node;
25  import javax.jcr.NodeIterator;
26  import javax.jcr.Session;
27  import javax.jcr.query.Query;
28  
29  import org.exoplatform.commons.exception.ExoMessageException;
30  import org.exoplatform.commons.utils.PageList;
31  import org.exoplatform.services.jcr.RepositoryService;
32  import org.exoplatform.services.jcr.core.ManageableRepository;
33  import org.exoplatform.services.jcr.impl.core.query.QueryImpl;
34  import org.exoplatform.services.log.ExoLogger;
35  import org.exoplatform.services.log.Log;
36  import org.exoplatform.services.wcm.core.NodeLocation;
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   * May 23, 2012  
44   */
45  public class UILockedNodePageList extends PageList<NodeLocation> {
46    
47    private static final Log LOG  = ExoLogger.getLogger(UILockedNodePageList.class);
48  
49    private static final int QUERY_SIZE = 200;
50    
51    private String query;
52    private Map<String, Integer> workspaceNodeMap;
53    private String[] workspaceNameList;
54    private List<NodeLocation> buffer;
55  
56    public UILockedNodePageList(int pageSize) {
57      super(pageSize);
58    }
59    
60    public UILockedNodePageList(String query, int pageSize, int currentPage) {
61      super(pageSize);
62      this.query = query;
63      workspaceNameList = getWorkSpaceNameList();
64      workspaceNodeMap = new HashMap<String, Integer>();
65      buffer = this.getData(0, Math.max(QUERY_SIZE, (currentPage + 10) * pageSize));
66      this.setAvailablePage(buffer.size());
67    }
68  
69    /**
70     * gets list of workspace name in repository
71     * @return
72     */
73    private String[] getWorkSpaceNameList() {
74      RepositoryService repoService = WCMCoreUtils.getService(RepositoryService.class);
75      String[] ret = new String[]{};
76      try {
77        ret = repoService.getCurrentRepository().getWorkspaceNames();
78      } catch (Exception e) {
79        if (LOG.isErrorEnabled()) {
80          LOG.error(e);
81        }
82      }
83      return ret;
84    }
85  
86    @Override
87    protected void populateCurrentPage(int page) throws Exception {
88      currentListPage_ = buffer.subList(getFrom(), getTo());
89    }
90  
91    @Override
92    protected void checkAndSetPage(int page) throws Exception
93    {
94      if (page + 10 > availablePage_) {
95        buffer.addAll(getData(buffer.size(), (page + 10) * getPageSize() - availablePage_ + QUERY_SIZE));
96        setAvailablePage(buffer.size());
97      }
98      if (page < 1 || page > availablePage_) {
99        Object[] args = {Integer.toString(page), Integer.toString(availablePage_)};
100       throw new ExoMessageException("PageList.page-out-of-range", args);
101     }
102     currentPage_ = page;
103   }
104 
105   private List<NodeLocation> getData(int from, int count) {
106 //    int count = this.getTo() - this.getFrom();//number of node need to query
107 //    int delta = this.getFrom();
108     int delta = from;
109     List<NodeLocation> ret = new ArrayList<NodeLocation>();//data will be filled to this list
110     //iterate through all workspaces
111     for (String workspace : workspaceNameList) {
112       Integer lockedNodeCount = workspaceNodeMap.get(workspace);
113       if (lockedNodeCount != null) {
114         if (lockedNodeCount <= delta) {//(1.1)
115           delta -= lockedNodeCount;
116         } else if (delta < lockedNodeCount && lockedNodeCount <= delta + count) { //(1.2)
117           ret.addAll(queryNodes(workspace, delta, lockedNodeCount - delta));
118           delta = 0;
119           count -= (lockedNodeCount - delta);
120         } else if (delta + count < lockedNodeCount) {
121           ret = queryNodes(workspace, delta, count);
122           break;//delta = 0; count = 0;
123         }
124       } else { //lockedNodeCount==null
125         List<NodeLocation> queryNodeData = queryNodes(workspace, delta, count);
126         if (queryNodeData.size() == 0) {//(2.1), as (1.1) : lockedNodeCount <= delta
127           lockedNodeCount = queryNodes(workspace, 0, count).size();
128           delta -= lockedNodeCount;
129           workspaceNodeMap.put(workspace, lockedNodeCount);
130         } else if (0 < queryNodeData.size() && queryNodeData.size() < count) {
131           //(2.2), as (1.2) : delta < lockedNodeCount && lockedNodeCount <= delta + count
132           ret.addAll(queryNodeData);
133           delta = 0;
134           count -= queryNodeData.size();
135         } else if (queryNodeData.size() == count) {//(2.3), as (1.3) : delta + count < lockedNodeCount
136           ret = queryNodeData;
137           break;//delta = 0; count = 0;
138         }
139       }
140       if (count == 0) {
141         break;
142       }
143     }
144     return ret;
145   }
146 
147   /**
148    * gets all nodes by this.query, in given workspace, from offset to (offset + limit)
149    * @throws Exception
150    */
151   private List<NodeLocation> queryNodes(String workspace, int offset, int limit) {
152     List<NodeLocation> ret = new ArrayList<NodeLocation>();
153     try {
154       ManageableRepository repo = WCMCoreUtils.getService(RepositoryService.class).getCurrentRepository();
155       Session session = WCMCoreUtils.getSystemSessionProvider().getSession(workspace, 
156                                                                            repo);
157       Query query = session.getWorkspace().getQueryManager().createQuery(this.query, Query.SQL);
158       ((QueryImpl)query).setOffset(offset);
159       ((QueryImpl)query).setLimit(limit);
160       
161       for (NodeIterator iter = query.execute().getNodes(); iter.hasNext();) {
162         Node node = iter.nextNode();
163         if (node.isLocked()) {
164           ret.add(NodeLocation.getNodeLocationByNode(node));
165         }
166       }
167     } catch (Exception e) {
168       if (LOG.isErrorEnabled()) {
169         LOG.error(e);
170       }
171     }
172     
173     return ret;
174   }
175   @Override
176   public List getAll() throws Exception {
177     return buffer;
178   }
179   
180 }