1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.wiki.internal.descriptor

File DefaultWikiDescriptorManager.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

32
59
11
1
246
155
32
0.54
5.36
11
2.91

Classes

Class Line # Actions
DefaultWikiDescriptorManager 54 59 0% 32 5
0.9509803795.1%
 

Contributing tests

This file is covered by 16 tests. .

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.wiki.internal.descriptor;
21   
22    import java.util.ArrayList;
23    import java.util.Collection;
24    import java.util.Collections;
25    import java.util.HashSet;
26    import java.util.List;
27   
28    import javax.inject.Inject;
29    import javax.inject.Named;
30    import javax.inject.Provider;
31    import javax.inject.Singleton;
32   
33    import org.xwiki.component.annotation.Component;
34    import org.xwiki.wiki.descriptor.WikiDescriptor;
35    import org.xwiki.wiki.descriptor.WikiDescriptorManager;
36    import org.xwiki.wiki.internal.descriptor.builder.WikiDescriptorBuilder;
37    import org.xwiki.wiki.internal.descriptor.builder.WikiDescriptorBuilderException;
38    import org.xwiki.wiki.internal.descriptor.document.WikiDescriptorDocumentHelper;
39    import org.xwiki.wiki.internal.manager.WikiDescriptorCache;
40    import org.xwiki.wiki.manager.WikiManagerException;
41   
42    import com.xpn.xwiki.XWikiContext;
43    import com.xpn.xwiki.doc.XWikiDocument;
44    import com.xpn.xwiki.objects.BaseObject;
45   
46    /**
47    * Default implementation for {@link WikiDescriptorManager}.
48    *
49    * @version $Id: e9f93f5598a5e0c76f3f49d328254d2064f64e17 $
50    * @since 6.0M1
51    */
52    @Component
53    @Singleton
 
54    public class DefaultWikiDescriptorManager implements WikiDescriptorManager
55    {
56    @Inject
57    @Named("readonly")
58    private Provider<XWikiContext> xcontextProvider;
59   
60    @Inject
61    private WikiDescriptorCache cache;
62   
63    @Inject
64    private Provider<WikiDescriptorDocumentHelper> descriptorDocumentHelperProvider;
65   
66    @Inject
67    private Provider<WikiDescriptorBuilder> wikiDescriptorBuilderProvider;
68   
 
69  49 toggle @Override
70    public Collection<WikiDescriptor> getAll() throws WikiManagerException
71    {
72    // Note: Ideally to improve performance we could imagine loading all XWikiServerClasses at initialization time
73    // (in initialize()) and thereafter only use the cache. The problem with this approach is that our Cache will
74    // need to be unbounded which is not the case right now. This would mean being able to put all descriptors in
75    // the cache and thus it might not scale if there were a very large number of wikis.
76    // Note that the full list of ids is cached since it takes a lot less memory that descriptors.
77   
78  49 Collection<String> wikiIds = getAllIds();
79   
80  49 List<WikiDescriptor> result = new ArrayList<WikiDescriptor>(wikiIds.size());
81   
82  49 for (String wikiId : wikiIds) {
83    // Get the descriptor
84  68 WikiDescriptor descriptor = getById(wikiId);
85   
86    // Add it to the result list
87  68 if (descriptor != null) {
88  68 result.add(descriptor);
89    }
90    }
91   
92  49 return result;
93    }
94   
 
95  417 toggle @Override
96    public Collection<String> getAllIds() throws WikiManagerException
97    {
98  417 Collection<String> wikiIds = this.cache.getWikiIds();
99   
100  418 if (wikiIds == null) {
101  51 List<String> documentNames;
102  51 try {
103  51 documentNames = this.descriptorDocumentHelperProvider.get().getAllXWikiServerClassDocumentNames();
104    } catch (Exception e) {
105  0 throw new WikiManagerException("Failed to get wiki ids", e);
106    }
107   
108  51 wikiIds = new HashSet<String>(documentNames.size());
109   
110  51 boolean foundMainWiki = false;
111   
112  51 XWikiContext xcontext = this.xcontextProvider.get();
113   
114  51 for (String documentName : documentNames) {
115  61 String wikId = this.descriptorDocumentHelperProvider.get().getWikiIdFromDocumentFullname(documentName);
116   
117  61 wikiIds.add(wikId);
118   
119  61 foundMainWiki |= xcontext.isMainWiki(wikId);
120    }
121   
122    // Make sure we always return a descriptor for main wiki, even a virtual one
123  51 if (!foundMainWiki) {
124  7 wikiIds.add(getMainWikiId());
125    }
126   
127  51 this.cache.setWikiIds(Collections.unmodifiableCollection(wikiIds));
128    }
129   
130  418 return wikiIds;
131    }
132   
 
133  11593 toggle @Override
134    public WikiDescriptor getByAlias(String wikiAlias) throws WikiManagerException
135    {
136  11593 WikiDescriptor descriptor = cache.getFromAlias(wikiAlias);
137   
138    // If not found in the cache then query the wiki and add to the cache if found.
139    //
140    // Note that an alternative implementation would have been to find all Wiki Descriptors at startup but this
141    // would have meant keeping them all in memory at once. Since we want to be able to scale to any number of
142    // subwikis we only cache the most used one. This allows inactive wikis to not take up any memory for example.
143    // Note that In order for performance to be maximum it also means we need to have a cache size at least as
144    // large as the max # of wikis being used at once.
145  11593 if (descriptor == null) {
146  2 XWikiDocument document = descriptorDocumentHelperProvider.get().findXWikiServerClassDocument(wikiAlias);
147  2 if (document != null) {
148    // Build the descriptor
149  1 descriptor = buildDescriptorFromDocument(document);
150    }
151   
152  2 if (descriptor == null) {
153    // Cache the fact that no descriptor is available for this alias
154  1 cache.addFromAlias(wikiAlias, DefaultWikiDescriptor.VOID);
155    }
156    }
157   
158  11592 return descriptor != DefaultWikiDescriptor.VOID && descriptor != null ? descriptor.clone() : null;
159    }
160   
 
161  8144 toggle @Override
162    public WikiDescriptor getById(String wikiId) throws WikiManagerException
163    {
164  8145 WikiDescriptor descriptor = cache.getFromId(wikiId);
165   
166  8148 if (descriptor == null) {
167    // Try to load a page named XWiki.XWikiServer<wikiId>
168  5 XWikiDocument document = descriptorDocumentHelperProvider.get().getDocumentFromWikiId(wikiId);
169   
170  5 if (!document.isNew()) {
171    // Build the descriptor
172  3 descriptor = buildDescriptorFromDocument(document);
173  2 } else if (getMainWikiId().equals(wikiId)) {
174    // Return a "virtual" descriptor if main wiki does not yet have a descriptor document
175  1 descriptor = new WikiDescriptor(wikiId, "localhost");
176    }
177   
178  5 if (descriptor == null) {
179    // Cache the fact that no descriptor is available for this alias
180  1 cache.addFromId(wikiId, DefaultWikiDescriptor.VOID);
181    }
182    }
183   
184  8147 return descriptor != DefaultWikiDescriptor.VOID && descriptor != null ? descriptor.clone() : null;
185    }
186   
 
187  38 toggle @Override
188    public boolean exists(String wikiId) throws WikiManagerException
189    {
190  38 return getAllIds().contains(wikiId);
191    }
192   
 
193  4 toggle @Override
194    public void saveDescriptor(WikiDescriptor descriptor) throws WikiManagerException
195    {
196  4 try {
197  4 this.wikiDescriptorBuilderProvider.get().save(descriptor);
198    } catch (WikiDescriptorBuilderException e) {
199  0 throw new WikiManagerException(
200    String.format("Unable to save wiki descriptor for [%s].", descriptor.getId()), e);
201    }
202    }
203   
 
204  5 toggle @Override
205    public WikiDescriptor getMainWikiDescriptor() throws WikiManagerException
206    {
207  5 return getById(getMainWikiId());
208    }
209   
 
210  10327 toggle @Override
211    public String getMainWikiId()
212    {
213  10320 XWikiContext xcontext = this.xcontextProvider.get();
214   
215  10308 return xcontext != null ? xcontext.getMainXWiki() : "xwiki";
216    }
217   
 
218  3634124 toggle @Override
219    public String getCurrentWikiId()
220    {
221  3634119 XWikiContext xcontext = this.xcontextProvider.get();
222   
223  3634224 return xcontext != null ? xcontext.getWikiId() : null;
224    }
225   
 
226  3382 toggle @Override
227    public WikiDescriptor getCurrentWikiDescriptor() throws WikiManagerException
228    {
229  3382 return getById(getCurrentWikiId());
230    }
231   
 
232  4 toggle private DefaultWikiDescriptor buildDescriptorFromDocument(XWikiDocument document)
233    {
234  4 DefaultWikiDescriptor descriptor = null;
235  4 List<BaseObject> serverClassObjects = document.getXObjects(DefaultWikiDescriptor.SERVER_CLASS);
236  4 if (serverClassObjects != null && !serverClassObjects.isEmpty()) {
237  4 descriptor = this.wikiDescriptorBuilderProvider.get().buildDescriptorObject(serverClassObjects, document);
238    // Add to the cache
239  4 if (descriptor != null) {
240  4 cache.add(descriptor);
241    }
242    }
243   
244  4 return descriptor;
245    }
246    }