1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.index.tree.internal.nestedpages

File DocumentTreeNode.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart9.png
38% of files have more coverage

Code metrics

32
74
11
1
272
202
28
0.38
6.73
11
2.55

Classes

Class Line # Actions
DocumentTreeNode 62 74 0% 28 12
0.897435989.7%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.index.tree.internal.nestedpages;
21   
22    import java.util.ArrayList;
23    import java.util.Collections;
24    import java.util.LinkedHashMap;
25    import java.util.List;
26    import java.util.Map;
27   
28    import javax.inject.Inject;
29    import javax.inject.Named;
30    import javax.inject.Provider;
31   
32    import org.apache.commons.lang3.StringUtils;
33    import org.xwiki.component.annotation.Component;
34    import org.xwiki.component.annotation.InstantiationStrategy;
35    import org.xwiki.component.descriptor.ComponentInstantiationStrategy;
36    import org.xwiki.component.manager.ComponentLookupException;
37    import org.xwiki.component.manager.ComponentManager;
38    import org.xwiki.component.phase.Initializable;
39    import org.xwiki.component.phase.InitializationException;
40    import org.xwiki.localization.LocalizationContext;
41    import org.xwiki.model.EntityType;
42    import org.xwiki.model.reference.DocumentReference;
43    import org.xwiki.model.reference.EntityReference;
44    import org.xwiki.model.reference.SpaceReference;
45    import org.xwiki.query.Query;
46    import org.xwiki.query.QueryException;
47    import org.xwiki.query.QueryFilter;
48    import org.xwiki.security.authorization.ContextualAuthorizationManager;
49    import org.xwiki.security.authorization.Right;
50    import org.xwiki.tree.TreeNode;
51   
52    /**
53    * The document tree node.
54    *
55    * @version $Id: 9a048a6238ca1d634c7287791bff8d2e7fe519b2 $
56    * @since 8.3M2
57    * @since 7.4.5
58    */
59    @Component
60    @Named("document")
61    @InstantiationStrategy(ComponentInstantiationStrategy.PER_LOOKUP)
 
62    public class DocumentTreeNode extends AbstractDocumentTreeNode implements Initializable
63    {
64    private static final String FIELD_TITLE = "title";
65   
66    private static final String PARAMETER_LOCALE = "locale";
67   
68    @Inject
69    @Named("count")
70    protected QueryFilter countQueryFilter;
71   
72    @Inject
73    @Named("hidden/document")
74    protected QueryFilter hiddenDocumentQueryFilter;
75   
76    @Inject
77    private LocalizationContext localizationContext;
78   
79    @Inject
80    private ContextualAuthorizationManager authorization;
81   
82    @Inject
83    @Named("context")
84    private Provider<ComponentManager> contextComponentManagerProvider;
85   
86    @Inject
87    @Named("childPage/nestedPages")
88    private QueryFilter childPageFilter;
89   
90    @Inject
91    @Named("hiddenPage/nestedPages")
92    private QueryFilter hiddenPageFilter;
93   
94    @Inject
95    @Named("documentReferenceResolver/nestedPages")
96    private QueryFilter documentReferenceResolverFilter;
97   
98    /**
99    * We use a {@link LinkedHashMap} because the order of the key is important.
100    */
101    private Map<String, TreeNode> nonLeafChildNodes = new LinkedHashMap<String, TreeNode>();
102   
103    /**
104    * Default constructor.
105    */
 
106  64 toggle public DocumentTreeNode()
107    {
108  64 super("document");
109    }
110   
 
111  64 toggle @Override
112    public void initialize() throws InitializationException
113    {
114  64 String[] nonLeafChildNodeTypes = new String[] {"translations", "attachments", "classProperties", "objects"};
115  64 ComponentManager contextComponentManager = this.contextComponentManagerProvider.get();
116  64 try {
117  64 for (String nonLeafChildNodeType : nonLeafChildNodeTypes) {
118  256 TreeNode treeNode = contextComponentManager.getInstance(TreeNode.class, nonLeafChildNodeType);
119  256 this.nonLeafChildNodes.put(nonLeafChildNodeType, treeNode);
120    }
121    } catch (ComponentLookupException e) {
122  0 throw new InitializationException("Failed to lookup the child components.", e);
123    }
124    }
125   
 
126  9 toggle @Override
127    protected List<String> getChildren(DocumentReference documentReference, int offset, int limit) throws Exception
128    {
129  9 List<String> children = new ArrayList<String>();
130  9 String serializedDocRef = this.defaultEntityReferenceSerializer.serialize(documentReference);
131   
132  9 if (offset == 0) {
133  9 for (Map.Entry<String, TreeNode> entry : this.nonLeafChildNodes.entrySet()) {
134  36 if (hasChild(entry.getKey(), entry.getValue(), documentReference)) {
135  1 children.add(entry.getKey() + ':' + serializedDocRef);
136    }
137    }
138   
139  9 if (showAddDocument(documentReference)) {
140  0 children.add("addDocument:" + serializedDocRef);
141    }
142    }
143   
144  9 children.addAll(serialize(getChildDocuments(documentReference, offset, limit)));
145   
146  9 return children;
147    }
148   
 
149  9 toggle protected List<DocumentReference> getChildDocuments(DocumentReference documentReference, int offset, int limit)
150    throws QueryException
151    {
152  9 if (!getDefaultDocumentName().equals(documentReference.getName())) {
153  1 return Collections.emptyList();
154    }
155   
156  8 String orderBy = getOrderBy();
157  8 Query query;
158  8 if (areTerminalDocumentsShown()) {
159  7 if (FIELD_TITLE.equals(orderBy)) {
160  7 query = this.queryManager.getNamedQuery("nestedPagesOrderedByTitle");
161  7 query.bindValue(PARAMETER_LOCALE, this.localizationContext.getCurrentLocale().toString());
162    } else {
163  0 query = this.queryManager.getNamedQuery("nestedPagesOrderedByName");
164    }
165    } else {
166  1 if (FIELD_TITLE.equals(orderBy)) {
167  1 query = this.queryManager.getNamedQuery("nonTerminalPagesOrderedByTitle");
168  1 query.bindValue(PARAMETER_LOCALE, this.localizationContext.getCurrentLocale().toString());
169    } else {
170    // Query only the spaces table.
171  0 query = this.queryManager.createQuery(
172    "select reference, 0 as terminal from XWikiSpace page order by lower(name), name", Query.HQL);
173    }
174    }
175   
176  8 query.setWiki(documentReference.getWikiReference().getName());
177  8 query.setOffset(offset);
178  8 query.setLimit(limit);
179   
180  8 query.addFilter(this.childPageFilter);
181  8 query.bindValue("parent", this.localEntityReferenceSerializer.serialize(documentReference.getParent()));
182   
183  8 if (!areHiddenEntitiesShown()) {
184  8 query.addFilter(this.hiddenPageFilter);
185    }
186   
187  8 return query.addFilter(this.documentReferenceResolverFilter).execute();
188    }
189   
 
190  70 toggle @Override
191    protected int getChildCount(DocumentReference documentReference) throws Exception
192    {
193  70 int count = 0;
194  70 for (Map.Entry<String, TreeNode> entry : this.nonLeafChildNodes.entrySet()) {
195  280 if (hasChild(entry.getKey(), entry.getValue(), documentReference)) {
196  1 count++;
197    }
198    }
199   
200  70 if (showAddDocument(documentReference)) {
201  0 count++;
202    }
203   
204  70 return count + getChildDocumentsCount(documentReference);
205    }
206   
 
207  70 toggle protected int getChildDocumentsCount(DocumentReference documentReference) throws QueryException
208    {
209  70 if (!getDefaultDocumentName().equals(documentReference.getName())) {
210  3 return 0;
211    }
212   
213  67 int count = getChildSpacesCount(documentReference);
214  67 if (areTerminalDocumentsShown()) {
215  63 count += getChildTerminalPagesCount(documentReference);
216    }
217  67 return count;
218    }
219   
 
220  63 toggle private int getChildTerminalPagesCount(DocumentReference documentReference) throws QueryException
221    {
222  63 Query query = this.queryManager
223    .createQuery("where doc.translation = 0 and doc.space = :space and doc.name <> :defaultDocName", Query.HQL);
224  63 query.addFilter(this.countQueryFilter);
225  63 if (Boolean.TRUE.equals(getProperties().get("filterHiddenDocuments"))) {
226  63 query.addFilter(this.hiddenDocumentQueryFilter);
227    }
228  63 query.setWiki(documentReference.getWikiReference().getName());
229  63 query.bindValue("space", this.localEntityReferenceSerializer.serialize(documentReference.getParent()));
230  63 query.bindValue("defaultDocName", getDefaultDocumentName());
231  63 return ((Long) query.execute().get(0)).intValue();
232    }
233   
 
234  5 toggle @Override
235    protected EntityReference getParent(DocumentReference documentReference) throws Exception
236    {
237  5 if (getDefaultDocumentName().equals(documentReference.getName())) {
238  4 EntityReference parentReference = documentReference.getParent().getParent();
239  4 if (parentReference.getType() == EntityType.SPACE) {
240  3 return new DocumentReference(getDefaultDocumentName(), new SpaceReference(parentReference));
241    } else {
242  1 return parentReference;
243    }
244    } else {
245  1 return new DocumentReference(getDefaultDocumentName(), documentReference.getLastSpaceReference());
246    }
247    }
248   
 
249  79 toggle private boolean showAddDocument(DocumentReference documentReference)
250    {
251  79 return Boolean.TRUE.equals(getProperties().get("showAddDocument"))
252    && "reference".equals(getProperties().get("hierarchyMode"))
253    && getDefaultDocumentName().equals(documentReference.getName())
254    && this.authorization.hasAccess(Right.EDIT, documentReference.getParent());
255    }
256   
 
257  316 toggle private boolean hasChild(String nodeType, TreeNode childNode, DocumentReference documentReference)
258    {
259  316 return hasChild(nodeType, childNode, this.defaultEntityReferenceSerializer.serialize(documentReference));
260    }
261   
 
262  316 toggle private boolean hasChild(String nodeType, TreeNode childNode, String serializedDocumentReference)
263    {
264  316 String showChild = "show" + StringUtils.capitalize(nodeType);
265  316 if (Boolean.TRUE.equals(getProperties().get(showChild))) {
266  48 String nodeId = nodeType + ':' + serializedDocumentReference;
267  48 childNode.getProperties().putAll(getProperties());
268  48 return childNode.getChildCount(nodeId) > 0;
269    }
270  268 return false;
271    }
272    }