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

File AbstractExtensionRESTResource.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart6.png
69% of files have more coverage

Code metrics

112
349
31
1
871
642
108
0.31
11.26
31
3.48

Classes

Class Line # Actions
AbstractExtensionRESTResource 91 349 0% 108 200
0.593495959.3%
 

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   
21    package org.xwiki.repository.internal.resources;
22   
23    import java.net.URISyntaxException;
24    import java.util.ArrayList;
25    import java.util.Collection;
26    import java.util.HashMap;
27    import java.util.List;
28    import java.util.Map;
29   
30    import javax.inject.Inject;
31    import javax.inject.Named;
32    import javax.ws.rs.WebApplicationException;
33    import javax.ws.rs.core.Response;
34    import javax.ws.rs.core.Response.ResponseBuilder;
35    import javax.ws.rs.core.Response.Status;
36   
37    import org.apache.commons.lang3.StringUtils;
38    import org.apache.commons.lang3.exception.ExceptionUtils;
39    import org.apache.solr.common.SolrDocument;
40    import org.xwiki.component.phase.Initializable;
41    import org.xwiki.component.phase.InitializationException;
42    import org.xwiki.extension.Extension;
43    import org.xwiki.extension.RemoteExtension;
44    import org.xwiki.extension.internal.ExtensionFactory;
45    import org.xwiki.extension.internal.converter.ExtensionIdConverter;
46    import org.xwiki.extension.internal.maven.MavenUtils;
47    import org.xwiki.extension.repository.ExtensionRepositoryDescriptor;
48    import org.xwiki.extension.repository.xwiki.model.jaxb.AbstractExtension;
49    import org.xwiki.extension.repository.xwiki.model.jaxb.ExtensionAuthor;
50    import org.xwiki.extension.repository.xwiki.model.jaxb.ExtensionDependency;
51    import org.xwiki.extension.repository.xwiki.model.jaxb.ExtensionId;
52    import org.xwiki.extension.repository.xwiki.model.jaxb.ExtensionIssueManagement;
53    import org.xwiki.extension.repository.xwiki.model.jaxb.ExtensionRating;
54    import org.xwiki.extension.repository.xwiki.model.jaxb.ExtensionRepository;
55    import org.xwiki.extension.repository.xwiki.model.jaxb.ExtensionScm;
56    import org.xwiki.extension.repository.xwiki.model.jaxb.ExtensionScmConnection;
57    import org.xwiki.extension.repository.xwiki.model.jaxb.ExtensionSummary;
58    import org.xwiki.extension.repository.xwiki.model.jaxb.ExtensionVersion;
59    import org.xwiki.extension.repository.xwiki.model.jaxb.ExtensionVersionSummary;
60    import org.xwiki.extension.repository.xwiki.model.jaxb.License;
61    import org.xwiki.extension.repository.xwiki.model.jaxb.Namespaces;
62    import org.xwiki.extension.repository.xwiki.model.jaxb.ObjectFactory;
63    import org.xwiki.extension.repository.xwiki.model.jaxb.Property;
64    import org.xwiki.model.reference.DocumentReference;
65    import org.xwiki.model.reference.DocumentReferenceResolver;
66    import org.xwiki.query.Query;
67    import org.xwiki.query.QueryException;
68    import org.xwiki.ratings.AverageRatingApi;
69    import org.xwiki.ratings.RatingsManager;
70    import org.xwiki.repository.internal.RepositoryManager;
71    import org.xwiki.repository.internal.XWikiRepositoryModel;
72    import org.xwiki.repository.internal.XWikiRepositoryModel.SolrField;
73    import org.xwiki.rest.XWikiResource;
74    import org.xwiki.security.authorization.ContextualAuthorizationManager;
75    import org.xwiki.security.authorization.Right;
76   
77    import com.xpn.xwiki.XWikiContext;
78    import com.xpn.xwiki.XWikiException;
79    import com.xpn.xwiki.doc.XWikiAttachment;
80    import com.xpn.xwiki.doc.XWikiDocument;
81    import com.xpn.xwiki.objects.BaseObject;
82    import com.xpn.xwiki.objects.BaseProperty;
83    import com.xpn.xwiki.objects.classes.ListClass;
84   
85    /**
86    * Base class for the annotation REST services, to implement common functionality to all annotation REST services.
87    *
88    * @version $Id: d61c401f1b1d41d793642b08bc0ecd578e828e92 $
89    * @since 3.2M3
90    */
 
91    public abstract class AbstractExtensionRESTResource extends XWikiResource implements Initializable
92    {
93    public static final String[] EPROPERTIES_SUMMARY = new String[] { XWikiRepositoryModel.PROP_EXTENSION_ID,
94    XWikiRepositoryModel.PROP_EXTENSION_TYPE, XWikiRepositoryModel.PROP_EXTENSION_NAME };
95   
96    protected static final String DEFAULT_BOOST;
97   
98    protected static final String DEFAULT_FL;
99   
100    protected static Map<String, Integer> EPROPERTIES_INDEX = new HashMap<String, Integer>();
101   
102    protected static String SELECT_EXTENSIONSUMMARY;
103   
 
104  2 toggle static {
105  2 StringBuilder pattern = new StringBuilder();
106   
107  2 int j = 0;
108   
109  2 pattern.append("doc.name");
110  2 EPROPERTIES_INDEX.put("doc.name", j++);
111  2 pattern.append(", ");
112  2 pattern.append("doc.space");
113  2 EPROPERTIES_INDEX.put("doc.space", j++);
114   
115    // Extension summary
116  8 for (int i = 0; i < EPROPERTIES_SUMMARY.length; ++i, ++j) {
117  6 String value = EPROPERTIES_SUMMARY[i];
118  6 pattern.append(", extension.");
119  6 pattern.append(value);
120  6 EPROPERTIES_INDEX.put(value, j);
121    }
122   
123  2 SELECT_EXTENSIONSUMMARY = pattern.toString();
124   
125    // Solr
126   
127  2 StringBuilder boostBuilder = new StringBuilder();
128  2 StringBuilder flBuilder = new StringBuilder("wiki,spaces,name");
129  2 for (SolrField field : XWikiRepositoryModel.SOLR_FIELDS.values()) {
130    // Boost
131  60 if (field.boostValue != null) {
132  16 if (boostBuilder.length() > 0) {
133  14 boostBuilder.append(' ');
134    }
135  16 boostBuilder.append(field.boostName);
136  16 boostBuilder.append('^');
137  16 boostBuilder.append(field.boostValue);
138    }
139   
140    // Fields list
141  60 if (field.name != null) {
142  60 if (flBuilder.length() > 0) {
143  60 flBuilder.append(',');
144    }
145  60 flBuilder.append(field.name);
146    }
147    }
148  2 DEFAULT_BOOST = boostBuilder.toString();
149  2 DEFAULT_FL = flBuilder.toString();
150    }
151   
152    @Inject
153    protected RepositoryManager repositoryManager;
154   
155    @Inject
156    protected ContextualAuthorizationManager authorization;
157   
158    @Inject
159    @Named("separate")
160    protected RatingsManager ratingsManager;
161   
162    /**
163    * Used to extract a document reference from a {@link SolrDocument}.
164    */
165    @Inject
166    protected DocumentReferenceResolver<SolrDocument> solrDocumentReferenceResolver;
167   
168    @Inject
169    protected ExtensionFactory extensionFactory;
170   
171    /**
172    * The object factory for model objects to be used when creating representations.
173    */
174    protected ObjectFactory extensionObjectFactory;
175   
 
176  7 toggle @Override
177    public void initialize() throws InitializationException
178    {
179  7 super.initialize();
180   
181  7 this.extensionObjectFactory = new ObjectFactory();
182    }
183   
 
184  90 toggle public XWikiDocument getExistingExtensionDocumentById(String extensionId) throws QueryException, XWikiException
185    {
186  90 XWikiDocument document = this.repositoryManager.getExistingExtensionDocumentById(extensionId);
187   
188  90 if (document == null) {
189  8 throw new WebApplicationException(Status.NOT_FOUND);
190    }
191   
192  82 return document;
193    }
194   
 
195  0 toggle protected Query createExtensionsCountQuery(String from, String where) throws QueryException
196    {
197    // select
198   
199  0 String select = "count(extension." + XWikiRepositoryModel.PROP_EXTENSION_ID + ")";
200   
201  0 return createExtensionsQuery(select, from, where, 0, -1, false);
202    }
203   
 
204  0 toggle protected long getExtensionsCountResult(Query query) throws QueryException
205    {
206  0 return ((Number) query.execute().get(0)).intValue();
207    }
208   
 
209  0 toggle protected Query createExtensionsSummariesQuery(String from, String where, int offset, int number, boolean versions)
210    throws QueryException
211    {
212  0 String select = SELECT_EXTENSIONSUMMARY;
213   
214  0 return createExtensionsQuery(select, from, where, offset, number, versions);
215    }
216   
 
217  0 toggle private Query createExtensionsQuery(String select, String from, String where, int offset, int number,
218    boolean versions) throws QueryException
219    {
220    // select
221   
222  0 StringBuilder queryStr = new StringBuilder("select ");
223  0 queryStr.append(select);
224   
225  0 if (versions) {
226  0 queryStr.append(", extensionVersion." + XWikiRepositoryModel.PROP_VERSION_VERSION + "");
227    }
228   
229    // from
230   
231  0 queryStr
232    .append(" from Document doc, doc.object(" + XWikiRepositoryModel.EXTENSION_CLASSNAME + ") as extension");
233   
234  0 if (versions) {
235  0 queryStr
236    .append(", doc.object(" + XWikiRepositoryModel.EXTENSIONVERSION_CLASSNAME + ") as extensionVersion");
237    }
238   
239  0 if (from != null) {
240  0 queryStr.append(',');
241  0 queryStr.append(from);
242    }
243   
244    // where
245   
246  0 queryStr.append(" where ");
247  0 if (where != null) {
248  0 queryStr.append('(');
249  0 queryStr.append(where);
250  0 queryStr.append(')');
251  0 queryStr.append(" and ");
252    }
253  0 queryStr.append("extension." + XWikiRepositoryModel.PROP_EXTENSION_VALIDEXTENSION + " = 1");
254   
255  0 Query query = this.queryManager.createQuery(queryStr.toString(), Query.XWQL);
256   
257  0 if (offset > 0) {
258  0 query.setOffset(offset);
259    }
260  0 if (number > 0) {
261  0 query.setLimit(number);
262    }
263   
264  0 return query;
265    }
266   
 
267  82 toggle protected BaseObject getExtensionObject(XWikiDocument extensionDocument)
268    {
269  82 return extensionDocument.getXObject(XWikiRepositoryModel.EXTENSION_CLASSREFERENCE);
270    }
271   
 
272  0 toggle protected BaseObject getExtensionObject(String extensionId) throws XWikiException, QueryException
273    {
274  0 return getExtensionObject(getExistingExtensionDocumentById(extensionId));
275    }
276   
 
277  82 toggle protected BaseObject getExtensionVersionObject(XWikiDocument extensionDocument, String version)
278    {
279  82 if (version == null) {
280  0 List<BaseObject> objects =
281    extensionDocument.getXObjects(XWikiRepositoryModel.EXTENSIONVERSION_CLASSREFERENCE);
282   
283  0 if (objects == null || objects.isEmpty()) {
284  0 return null;
285    } else {
286  0 return objects.get(objects.size() - 1);
287    }
288    }
289   
290  82 return extensionDocument.getObject(XWikiRepositoryModel.EXTENSIONVERSION_CLASSNAME, "version", version, false);
291    }
292   
 
293  0 toggle protected BaseObject getExtensionVersionObject(String extensionId, String version)
294    throws XWikiException, QueryException
295    {
296  0 return getExtensionVersionObject(getExistingExtensionDocumentById(extensionId), version);
297    }
298   
 
299  62 toggle protected <E extends AbstractExtension> E createExtension(XWikiDocument extensionDocument, String version)
300    {
301  62 BaseObject extensionObject = getExtensionObject(extensionDocument);
302  62 DocumentReference extensionDocumentReference = extensionDocument.getDocumentReference();
303   
304  62 if (extensionObject == null) {
305  0 throw new WebApplicationException(Status.NOT_FOUND);
306    }
307   
308  62 AbstractExtension extension;
309  62 ExtensionVersion extensionVersion;
310  62 BaseObject extensionVersionObject;
311  62 if (version == null) {
312  0 extension = this.extensionObjectFactory.createExtension();
313  0 extensionVersion = null;
314  0 extensionVersionObject = null;
315    } else {
316  62 extensionVersionObject = getExtensionVersionObject(extensionDocument, version);
317   
318  62 if (extensionVersionObject == null) {
319  0 throw new WebApplicationException(Status.NOT_FOUND);
320    }
321   
322  62 extensionVersion = this.extensionObjectFactory.createExtensionVersion();
323  62 extension = extensionVersion;
324  62 extensionVersion
325    .setVersion((String) getValue(extensionVersionObject, XWikiRepositoryModel.PROP_VERSION_VERSION));
326    }
327   
328  62 extension.setId((String) getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_ID));
329  62 extension.setType((String) getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_TYPE));
330   
331  62 License license = this.extensionObjectFactory.createLicense();
332  62 license.setName((String) getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_LICENSENAME));
333  62 extension.getLicenses().add(license);
334   
335  62 extension.setRating(getExtensionRating(extensionDocumentReference));
336  62 extension.setSummary((String) getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_SUMMARY));
337  61 extension.setDescription((String) getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_DESCRIPTION));
338  62 extension.setName((String) getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_NAME));
339  61 extension.setCategory((String) getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_CATEGORY));
340  61 extension.setWebsite(
341    StringUtils.defaultIfEmpty((String) getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_WEBSITE),
342    extensionDocument.getExternalURL("view", getXWikiContext())));
343   
344    // Recommended
345  62 Integer recommended = getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_RECOMMENDED, 0);
346  62 extension.setRecommended(recommended.intValue() == 1);
347   
348    // SCM
349  62 ExtensionScm scm = new ExtensionScm();
350  61 scm.setUrl((String) getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_SCMURL));
351  61 scm.setConnection(
352    toScmConnection((String) getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_SCMCONNECTION)));
353  61 scm.setDeveloperConnection(
354    toScmConnection((String) getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_SCMDEVCONNECTION)));
355  62 extension.setScm(scm);
356   
357    // Issue Management
358  62 ExtensionIssueManagement issueManagement = new ExtensionIssueManagement();
359  61 issueManagement
360    .setSystem((String) getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_ISSUEMANAGEMENT_SYSTEM));
361  61 issueManagement
362    .setUrl((String) getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_ISSUEMANAGEMENT_URL));
363  62 if (StringUtils.isNotEmpty(issueManagement.getSystem()) || StringUtils.isNotEmpty(issueManagement.getUrl())) {
364  0 extension.setIssueManagement(issueManagement);
365    }
366   
367    // Authors
368  62 List<String> authors = (List<String>) getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_AUTHORS);
369  62 if (authors != null) {
370  62 for (String authorId : authors) {
371  28 extension.getAuthors().add(resolveExtensionAuthor(authorId));
372    }
373    }
374   
375    // Features
376  62 List<String> features;
377  62 if (extensionVersionObject != null) {
378  61 features = (List<String>) getValue(extensionVersionObject, XWikiRepositoryModel.PROP_VERSION_FEATURES);
379    } else {
380  0 features = (List<String>) getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_FEATURES);
381    }
382  61 if (features != null && !features.isEmpty()) {
383  13 extension.withFeatures(features);
384  13 for (String feature : features) {
385  13 org.xwiki.extension.ExtensionId extensionId = ExtensionIdConverter.toExtensionId(feature, null);
386  13 ExtensionId extensionFeature = this.extensionObjectFactory.createExtensionId();
387  13 extensionFeature.setId(extensionId.getId());
388  13 if (extensionId.getVersion() != null) {
389  13 extensionFeature.setVersion(extensionId.getVersion().getValue());
390    }
391  13 extension.getExtensionFeatures().add(extensionFeature);
392    }
393    }
394   
395    // Allowed namespaces
396  61 List<String> namespaces =
397    (List<String>) getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_ALLOWEDNAMESPACES);
398  62 Integer namespacesEmpty =
399    (Integer) getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_ALLOWEDNAMESPACES_EMPTY);
400  62 if (namespaces != null && (!namespaces.isEmpty() || namespacesEmpty == 1)) {
401  0 Namespaces restNamespaces = this.extensionObjectFactory.createNamespaces();
402  0 restNamespaces.withNamespaces(namespaces);
403  0 extension.setAllowedNamespaces(restNamespaces);
404    }
405   
406    // Repositories
407  62 if (extensionVersionObject != null) {
408  62 List<String> repositories =
409    (List<String>) getValue(extensionVersionObject, XWikiRepositoryModel.PROP_VERSION_REPOSITORIES);
410  62 extensionVersion.withRepositories(toExtensionRepositories(repositories));
411    }
412   
413    // Properties
414  61 addProperties(extension,
415    (List<String>) getValue(extensionObject, XWikiRepositoryModel.PROP_EXTENSION_PROPERTIES));
416   
417    // Dependencies
418  62 if (extensionVersion != null) {
419  61 List<BaseObject> dependencies =
420    extensionDocument.getXObjects(XWikiRepositoryModel.EXTENSIONDEPENDENCY_CLASSREFERENCE);
421  62 if (dependencies != null) {
422  18 for (BaseObject dependencyObject : dependencies) {
423  56 if (dependencyObject != null) {
424  56 if (StringUtils.equals(getValue(dependencyObject,
425    XWikiRepositoryModel.PROP_DEPENDENCY_EXTENSIONVERSION, (String) null), version)) {
426  46 ExtensionDependency dependency = extensionObjectFactory.createExtensionDependency();
427  46 dependency
428    .setId((String) getValue(dependencyObject, XWikiRepositoryModel.PROP_DEPENDENCY_ID));
429  46 dependency.setConstraint(
430    (String) getValue(dependencyObject, XWikiRepositoryModel.PROP_DEPENDENCY_CONSTRAINT));
431  46 List<String> repositories = (List<String>) getValue(dependencyObject,
432    XWikiRepositoryModel.PROP_DEPENDENCY_REPOSITORIES);
433  46 dependency.withRepositories(toExtensionRepositories(repositories));
434   
435  46 extensionVersion.getDependencies().add(dependency);
436    }
437    }
438    }
439    }
440    }
441   
442  62 return (E) extension;
443    }
444   
 
445  150 toggle protected ExtensionScmConnection toScmConnection(String connectionString)
446    {
447  150 if (connectionString != null) {
448  0 org.xwiki.extension.ExtensionScmConnection connection =
449    MavenUtils.toExtensionScmConnection(connectionString);
450   
451  0 ExtensionScmConnection restConnection = new ExtensionScmConnection();
452  0 restConnection.setPath(connection.getPath());
453  0 restConnection.setSystem(connection.getSystem());
454   
455  0 return restConnection;
456    }
457   
458  149 return null;
459    }
460   
 
461  107 toggle protected List<ExtensionRepository> toExtensionRepositories(List<String> repositories)
462    {
463  108 if (repositories != null) {
464  67 List<ExtensionRepository> restRepositories = new ArrayList<>(repositories.size());
465   
466  67 for (String repositoryString : repositories) {
467  6 try {
468  6 restRepositories.add(toExtensionRepository(repositoryString));
469    } catch (URISyntaxException e) {
470  0 this.slf4Jlogger.warn("Failed to parse repository descriptor [{}]", repositoryString,
471    ExceptionUtils.getRootCauseMessage(e));
472    }
473    }
474   
475  66 return restRepositories;
476    }
477   
478  41 return null;
479    }
480   
 
481  6 toggle protected ExtensionRepository toExtensionRepository(String repositoryString) throws URISyntaxException
482    {
483  6 if (repositoryString != null) {
484  6 ExtensionRepositoryDescriptor descriptor =
485    XWikiRepositoryModel.toRepositoryDescriptor(repositoryString, extensionFactory);
486   
487  6 ExtensionRepository restRepository = new ExtensionRepository();
488  6 restRepository.setId(descriptor.getId());
489  6 restRepository.setType(descriptor.getType());
490  6 restRepository.setUri(descriptor.getURI().toString());
491   
492  6 return restRepository;
493    }
494   
495  0 return null;
496    }
497   
 
498  30 toggle protected ExtensionAuthor resolveExtensionAuthor(String authorId)
499    {
500  30 ExtensionAuthor author = new ExtensionAuthor();
501   
502  30 XWikiContext xcontext = getXWikiContext();
503   
504  30 XWikiDocument document;
505  30 try {
506  30 document = xcontext.getWiki().getDocument(authorId, xcontext);
507    } catch (XWikiException e) {
508  0 document = null;
509    }
510   
511  30 if (document != null && !document.isNew()) {
512  8 author.setName(xcontext.getWiki().getPlainUserName(document.getDocumentReference(), xcontext));
513  8 author.setUrl(document.getExternalURL("view", xcontext));
514    } else {
515  22 author.setName(authorId);
516    }
517   
518  30 return author;
519    }
520   
 
521  0 toggle protected void getExtensions(List<ExtensionVersion> extensions, Query query) throws QueryException
522    {
523  0 List<Object[]> entries = query.execute();
524   
525  0 for (Object[] entry : entries) {
526  0 extensions.add(createExtensionVersionFromQueryResult(entry));
527    }
528    }
529   
 
530  156 toggle protected <T> T getSolrValue(SolrDocument document, String property, boolean emptyIsNull)
531    {
532  156 return getSolrValue(document, property, emptyIsNull, null);
533    }
534   
 
535  195 toggle protected <T> T getSolrValue(SolrDocument document, String property, boolean emptyIsNull, T def)
536    {
537  195 Object value = document.getFieldValue(XWikiRepositoryModel.toSolrField(property));
538   
539  195 if (value instanceof Collection) {
540  93 Collection collectionValue = (Collection) value;
541  93 value = collectionValue.size() > 0 ? collectionValue.iterator().next() : null;
542    }
543   
544  195 if (value == null || (emptyIsNull && value instanceof String && ((String) value).isEmpty())) {
545  115 value = def;
546    }
547   
548  195 return (T) value;
549    }
550   
 
551  52 toggle protected <T> Collection<T> getSolrValues(SolrDocument document, String property)
552    {
553  52 return (Collection) document.getFieldValues(XWikiRepositoryModel.toSolrField(property));
554    }
555   
 
556  0 toggle protected <T> T getQueryValue(Object[] entry, String property)
557    {
558  0 return (T) entry[EPROPERTIES_INDEX.get(property)];
559    }
560   
 
561  0 toggle protected ExtensionVersion createExtensionVersionFromQueryResult(Object[] entry)
562    {
563  0 XWikiContext xcontext = getXWikiContext();
564   
565  0 String documentName = (String) entry[0];
566  0 String documentSpace = (String) entry[1];
567   
568  0 ExtensionVersion extension = this.extensionObjectFactory.createExtensionVersion();
569   
570  0 extension.setId(this.<String>getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_ID));
571  0 extension.setType(this.<String>getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_TYPE));
572  0 extension.setName(this.<String>getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_NAME));
573  0 extension.setSummary(this.<String>getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_SUMMARY));
574   
575    // Recommended
576  0 Integer recommended = this.<Integer>getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_RECOMMENDED);
577  0 extension.setRecommended(recommended != null && recommended.intValue() == 1);
578   
579    // SCM
580  0 ExtensionScm scm = new ExtensionScm();
581  0 scm.setUrl(this.<String>getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_SCMURL));
582  0 scm.setConnection(
583    toScmConnection(this.<String>getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_SCMCONNECTION)));
584  0 scm.setDeveloperConnection(
585    toScmConnection(this.<String>getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_SCMDEVCONNECTION)));
586  0 extension.setScm(scm);
587   
588    // Issue Management
589  0 ExtensionIssueManagement issueManagement = new ExtensionIssueManagement();
590  0 issueManagement
591    .setSystem(this.<String>getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_ISSUEMANAGEMENT_SYSTEM));
592  0 issueManagement
593    .setUrl(this.<String>getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_ISSUEMANAGEMENT_URL));
594  0 if (StringUtils.isNotEmpty(issueManagement.getSystem()) || StringUtils.isNotEmpty(issueManagement.getUrl())) {
595  0 extension.setIssueManagement(issueManagement);
596    }
597   
598    // Rating
599  0 DocumentReference extensionDocumentReference =
600    new DocumentReference(xcontext.getWikiId(), documentSpace, documentName);
601    // FIXME: this adds potentially tons of new request to what used to be carefully crafted to produce a single
602    // request for the whole search... Should be cached in a filed of the document (like the last version is for
603    // example).
604  0 extension.setRating(getExtensionRating(extensionDocumentReference));
605   
606    // Website
607  0 extension.setWebsite(this.<String>getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_WEBSITE));
608  0 if (StringUtils.isBlank(extension.getWebsite())) {
609  0 extension.setWebsite(xcontext.getWiki()
610    .getURL(new DocumentReference(xcontext.getWikiId(), documentSpace, documentName), "view", xcontext));
611    }
612   
613    // Authors
614  0 for (String authorId : ListClass.getListFromString(
615    this.<String>getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_AUTHORS), "|", false)) {
616  0 extension.getAuthors().add(resolveExtensionAuthor(authorId));
617    }
618   
619    // Features
620  0 List<String> features = ListClass.getListFromString(
621    this.<String>getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_FEATURES), "|", false);
622  0 if (features != null && !features.isEmpty()) {
623  0 extension.withFeatures(features);
624  0 for (String feature : features) {
625  0 org.xwiki.extension.ExtensionId extensionId = ExtensionIdConverter.toExtensionId(feature, null);
626  0 ExtensionId extensionFeature = this.extensionObjectFactory.createExtensionId();
627  0 extensionFeature.setId(extensionId.getId());
628  0 if (extensionId.getVersion() != null) {
629  0 extensionFeature.setVersion(extensionId.getVersion().getValue());
630    }
631  0 extension.getExtensionFeatures().add(extensionFeature);
632    }
633    }
634   
635    // Allowed namespaces
636  0 String namespacesString =
637    this.<String>getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_ALLOWEDNAMESPACES);
638  0 Integer namespacesEmpty =
639    (Integer) getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_ALLOWEDNAMESPACES_EMPTY);
640  0 if (namespacesString != null && (!namespacesString.isEmpty() || namespacesEmpty == 1)) {
641  0 List<String> namespaces = ListClass.getListFromString(namespacesString, "|", false);
642  0 Namespaces restNamespaces = this.extensionObjectFactory.createNamespaces();
643  0 restNamespaces.withNamespaces(namespaces);
644  0 extension.setAllowedNamespaces(restNamespaces);
645    }
646   
647    // License
648  0 License license = this.extensionObjectFactory.createLicense();
649  0 license.setName(this.<String>getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_LICENSENAME));
650  0 extension.getLicenses().add(license);
651   
652    // Version
653  0 extension.setVersion((String) entry[EPROPERTIES_INDEX.size()]);
654   
655    // TODO: add support for
656    // * description
657    // * dependencies
658   
659  0 return extension;
660    }
661   
 
662  13 toggle protected ExtensionVersion createExtensionVersionFromSolrDocument(SolrDocument document)
663    {
664  13 XWikiContext xcontext = getXWikiContext();
665   
666  13 ExtensionVersion extension = this.extensionObjectFactory.createExtensionVersion();
667   
668  13 extension.setId(this.<String>getSolrValue(document, Extension.FIELD_ID, true));
669  13 extension.setType(this.<String>getSolrValue(document, Extension.FIELD_TYPE, true));
670  13 extension.setName(this.<String>getSolrValue(document, Extension.FIELD_NAME, false));
671  13 extension.setSummary(this.<String>getSolrValue(document, Extension.FIELD_SUMMARY, false));
672   
673    // Recommended
674  13 Boolean recommended = this.<Boolean>getSolrValue(document, RemoteExtension.FIELD_RECOMMENDED, false, false);
675  13 if (recommended == Boolean.TRUE) {
676  2 extension.setRecommended(recommended);
677    }
678   
679    // SCM
680  13 ExtensionScm scm = new ExtensionScm();
681  13 scm.setUrl(this.<String>getSolrValue(document, Extension.FIELD_SCM, true));
682  13 scm.setConnection(toScmConnection(
683    this.<String>getSolrValue(document, XWikiRepositoryModel.PROP_EXTENSION_SCMCONNECTION, true)));
684  13 scm.setDeveloperConnection(toScmConnection(
685    this.<String>getSolrValue(document, XWikiRepositoryModel.PROP_EXTENSION_SCMDEVCONNECTION, true)));
686  13 if (scm.getUrl() != null || scm.getConnection() != null || scm.getDeveloperConnection() != null) {
687  2 extension.setScm(scm);
688    }
689   
690    // Issue Management
691  13 ExtensionIssueManagement issueManagement = new ExtensionIssueManagement();
692  13 issueManagement.setSystem(
693    this.<String>getSolrValue(document, XWikiRepositoryModel.PROP_EXTENSION_ISSUEMANAGEMENT_SYSTEM, true));
694  13 issueManagement
695    .setUrl(this.<String>getSolrValue(document, XWikiRepositoryModel.PROP_EXTENSION_ISSUEMANAGEMENT_URL, true));
696  13 if (issueManagement.getSystem() != null || issueManagement.getUrl() != null) {
697  0 extension.setIssueManagement(issueManagement);
698    }
699   
700    // Rating
701  13 ExtensionRating extensionRating = this.extensionObjectFactory.createExtensionRating();
702  13 extensionRating.setTotalVotes(getSolrValue(document, XWikiRepositoryModel.PROP_RATING_TOTALVOTES, false, 0));
703  13 extensionRating
704    .setAverageVote(getSolrValue(document, XWikiRepositoryModel.PROP_RATING_AVERAGEVOTE, false, 0.0f));
705  13 extension.setRating(extensionRating);
706   
707    // Website
708  13 extension.setWebsite(this.<String>getSolrValue(document, Extension.FIELD_WEBSITE, true));
709  13 if (extension.getWebsite() == null) {
710  13 DocumentReference extensionDocumentReference = this.solrDocumentReferenceResolver.resolve(document);
711  13 extension.setWebsite(xcontext.getWiki().getURL(extensionDocumentReference, xcontext));
712    }
713   
714    // Authors
715  13 Collection<String> authors = this.<String>getSolrValues(document, Extension.FIELD_AUTHORS);
716  13 if (authors != null) {
717  2 for (String authorId : authors) {
718  2 extension.getAuthors().add(resolveExtensionAuthor(authorId));
719    }
720    }
721   
722    // Features
723  13 Collection<String> features = this.<String>getSolrValues(document, Extension.FIELD_FEATURES);
724  13 if (features != null && !features.isEmpty()) {
725  0 extension.withFeatures(features);
726  0 for (String feature : features) {
727  0 org.xwiki.extension.ExtensionId extensionId = ExtensionIdConverter.toExtensionId(feature, null);
728  0 ExtensionId extensionFeature = this.extensionObjectFactory.createExtensionId();
729  0 extensionFeature.setId(extensionId.getId());
730  0 if (extensionId.getVersion() != null) {
731  0 extensionFeature.setVersion(extensionId.getVersion().getValue());
732    }
733  0 extension.getExtensionFeatures().add(extensionFeature);
734    }
735    }
736   
737    // License
738  13 String licenseName = this.<String>getSolrValue(document, Extension.FIELD_LICENSE, true);
739  13 if (licenseName != null) {
740  2 License license = this.extensionObjectFactory.createLicense();
741  2 license.setName(licenseName);
742  2 extension.getLicenses().add(license);
743    }
744   
745    // Allowed namespaces
746  13 Collection<String> namespaces = this.<String>getSolrValues(document, Extension.FIELD_ALLOWEDNAMESPACES);
747  13 if (namespaces != null && !namespaces.isEmpty()) {
748  0 Namespaces restNamespaces = this.extensionObjectFactory.createNamespaces();
749  0 restNamespaces.withNamespaces(namespaces);
750  0 extension.setAllowedNamespaces(restNamespaces);
751    }
752   
753    // Version
754  13 extension.setVersion(this.<String>getSolrValue(document, Extension.FIELD_VERSION, true));
755   
756    // Properties
757  13 addProperties(extension, this.<String>getSolrValues(document, Extension.FIELD_PROPERTIES));
758   
759    // TODO: add support for
760    // * dependencies
761   
762  13 return extension;
763    }
764   
 
765  74 toggle protected Map<String, String> addProperties(AbstractExtension extension, Collection<String> properties)
766    {
767  75 Map<String, String> map = null;
768   
769  75 if (properties != null) {
770  3 map = new HashMap<>();
771   
772  3 for (String stringProperty : properties) {
773  9 int index = stringProperty.indexOf('=');
774  9 if (index > 0) {
775  9 Property property = new Property();
776  9 property.setKey(stringProperty.substring(0, index));
777  9 property.setStringValue(
778  9 (index + 1) < stringProperty.length() ? stringProperty.substring(index + 1) : "");
779  9 extension.getProperties().add(property);
780    }
781    }
782    }
783   
784  75 return map;
785    }
786   
 
787  62 toggle protected ExtensionRating getExtensionRating(DocumentReference extensionDocumentReference)
788    {
789  62 ExtensionRating extensionRating = this.extensionObjectFactory.createExtensionRating();
790   
791  62 try {
792  62 AverageRatingApi averageRating =
793    new AverageRatingApi(ratingsManager.getAverageRating(extensionDocumentReference));
794  62 extensionRating.setTotalVotes(averageRating.getNbVotes());
795  62 extensionRating.setAverageVote(averageRating.getAverageVote());
796    } catch (XWikiException e) {
797  0 extensionRating.setTotalVotes(0);
798  0 extensionRating.setAverageVote(0);
799    }
800   
801  62 return extensionRating;
802    }
803   
 
804  0 toggle protected <E extends ExtensionSummary> void getExtensionSummaries(List<E> extensions, Query query)
805    throws QueryException
806    {
807  0 List<Object[]> entries = query.execute();
808   
809  0 for (Object[] entry : entries) {
810  0 extensions.add((E) createExtensionSummaryFromQueryResult(entry));
811    }
812    }
813   
 
814  0 toggle protected ExtensionSummary createExtensionSummaryFromQueryResult(Object[] entry)
815    {
816  0 ExtensionSummary extension;
817  0 ExtensionVersionSummary extensionVersion;
818  0 int versionIndex = EPROPERTIES_INDEX.get(EPROPERTIES_SUMMARY[EPROPERTIES_SUMMARY.length - 1]) + 1;
819  0 if (entry.length == versionIndex) {
820    // It's a extension summary without version
821  0 extension = this.extensionObjectFactory.createExtensionSummary();
822  0 extensionVersion = null;
823    } else {
824  0 extension = extensionVersion = this.extensionObjectFactory.createExtensionVersionSummary();
825  0 extensionVersion.setVersion((String) entry[versionIndex]);
826    }
827   
828  0 extension.setId(this.<String>getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_ID));
829  0 extension.setType(this.<String>getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_TYPE));
830  0 extension.setName(this.<String>getQueryValue(entry, XWikiRepositoryModel.PROP_EXTENSION_NAME));
831   
832  0 return extension;
833    }
834   
 
835  1371 toggle protected <T> T getValue(BaseObject object, String field)
836    {
837  1371 return getValue(object, field, (T) null);
838    }
839   
 
840  1489 toggle protected <T> T getValue(BaseObject object, String field, T def)
841    {
842  1488 BaseProperty<?> property = (BaseProperty<?>) object.safeget(field);
843   
844  1492 return property != null ? (T) property.getValue() : def;
845    }
846   
 
847  17 toggle protected ResponseBuilder getAttachmentResponse(XWikiAttachment xwikiAttachment) throws XWikiException
848    {
849  17 if (xwikiAttachment == null) {
850  0 throw new WebApplicationException(Status.NOT_FOUND);
851    }
852   
853  17 ResponseBuilder response = Response.ok();
854   
855  17 XWikiContext xcontext = getXWikiContext();
856   
857  17 response = response.type(xwikiAttachment.getMimeType(xcontext));
858  17 response = response.entity(xwikiAttachment.getContent(xcontext));
859  17 response =
860    response.header("content-disposition", "attachment; filename=\"" + xwikiAttachment.getFilename() + "\"");
861   
862  17 return response;
863    }
864   
 
865  99 toggle protected void checkRights(XWikiDocument document) throws XWikiException
866    {
867  99 if (!this.authorization.hasAccess(Right.VIEW, document.getDocumentReference())) {
868  0 throw new WebApplicationException(Status.FORBIDDEN);
869    }
870    }
871    }