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

File SearchRESTResource.java

 

Coverage histogram

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

Code metrics

16
50
3
1
212
110
11
0.22
16.67
3
3.67

Classes

Class Line # Actions
SearchRESTResource 59 50 0% 11 12
0.8260869482.6%
 

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.util.ArrayList;
24    import java.util.List;
25   
26    import javax.inject.Named;
27    import javax.inject.Singleton;
28    import javax.ws.rs.DefaultValue;
29    import javax.ws.rs.GET;
30    import javax.ws.rs.POST;
31    import javax.ws.rs.Path;
32    import javax.ws.rs.QueryParam;
33   
34    import org.apache.commons.lang3.StringUtils;
35    import org.apache.solr.client.solrj.response.QueryResponse;
36    import org.apache.solr.common.SolrDocument;
37    import org.apache.solr.common.SolrDocumentList;
38    import org.xwiki.component.annotation.Component;
39    import org.xwiki.extension.rating.RatingExtension;
40    import org.xwiki.extension.repository.xwiki.model.jaxb.COMPARISON;
41    import org.xwiki.extension.repository.xwiki.model.jaxb.ExtensionQuery;
42    import org.xwiki.extension.repository.xwiki.model.jaxb.ExtensionsSearchResult;
43    import org.xwiki.extension.repository.xwiki.model.jaxb.Filter;
44    import org.xwiki.extension.repository.xwiki.model.jaxb.SortClause;
45    import org.xwiki.query.Query;
46    import org.xwiki.query.QueryException;
47    import org.xwiki.query.SecureQuery;
48    import org.xwiki.repository.Resources;
49    import org.xwiki.repository.internal.XWikiRepositoryModel;
50   
51    /**
52    * @version $Id: 27d301df657f1738245f68a136a32e80d3aaa0f6 $
53    * @since 3.2M3
54    */
55    @Component
56    @Named("org.xwiki.repository.internal.resources.SearchRESTResource")
57    @Path(Resources.SEARCH)
58    @Singleton
 
59    public class SearchRESTResource extends AbstractExtensionRESTResource
60    {
61    /**
62    * @since 3.3M2
63    */
 
64  20 toggle @GET
65    public ExtensionsSearchResult searchGet(@QueryParam(Resources.QPARAM_SEARCH_QUERY) @DefaultValue("") String pattern,
66    @QueryParam(Resources.QPARAM_LIST_START) @DefaultValue("0") int offset,
67    @QueryParam(Resources.QPARAM_LIST_NUMBER) @DefaultValue("-1") int number,
68    @QueryParam(Resources.QPARAM_LIST_REQUIRETOTALHITS) @DefaultValue("true") boolean requireTotalHits)
69    throws QueryException
70    {
71  20 ExtensionQuery query = this.extensionObjectFactory.createExtensionQuery();
72   
73  20 query.setQuery(pattern);
74  20 query.setOffset(offset);
75  20 query.setLimit(number);
76   
77  20 return searchPost(query);
78    }
79   
80    // TODO: automatically replace Extension fields names with the actual Solr properties names (so that it's possible
81    // to write query like type:jar)
 
82  48 toggle private String toSolrStatement(String query)
83    {
84  48 if (StringUtils.isBlank(query)) {
85  37 return "*";
86  11 } else if (StringUtils.containsNone(query, ' ', ':')) {
87  11 return "*" + query + "*";
88    }
89   
90  0 return query;
91    }
92   
 
93  48 toggle @POST
94    public ExtensionsSearchResult searchPost(ExtensionQuery query) throws QueryException
95    {
96  48 ExtensionsSearchResult result = this.extensionObjectFactory.createExtensionsSearchResult();
97   
98  48 Query solrQuery = this.queryManager.createQuery(toSolrStatement(query.getQuery()), "solr");
99   
100    // /////////////////
101    // Search only in the current wiki
102    // /////////////////
103   
104  48 solrQuery.setWiki(this.xcontextProvider.get().getWikiId());
105   
106    // /////////////////
107    // Limit and offset
108    // /////////////////
109   
110  48 solrQuery.setLimit(query.getLimit());
111  48 solrQuery.setOffset(query.getOffset());
112   
113    // /////////////////
114    // Rights
115    // /////////////////
116   
117  48 if (query instanceof SecureQuery) {
118    // Show only what the current user has the right to see
119  0 ((SecureQuery) query).checkCurrentUser(true);
120    }
121   
122    // /////////////////
123    // Boost
124    // /////////////////
125   
126  48 solrQuery.bindValue("qf", DEFAULT_BOOST);
127   
128    // /////////////////
129    // Fields
130    // /////////////////
131   
132  48 solrQuery.bindValue("fl", DEFAULT_FL);
133   
134    // /////////////////
135    // Ordering
136    // /////////////////
137   
138    // Convert extension ordering into solr ordering
139  48 List<String> sortClauses = new ArrayList<>(query.getSortClauses().size() + 1);
140  48 for (SortClause sortClause : query.getSortClauses()) {
141  0 String solrField = XWikiRepositoryModel.toSolrField(sortClause.getField());
142  0 if (solrField != null) {
143  0 sortClauses.add(solrField + ' ' + sortClause.getOrder().name().toLowerCase());
144    }
145    }
146   
147    // Set default ordering
148  48 if (StringUtils.isEmpty(query.getQuery())) {
149    // Sort by rating by default when search query is empty
150  37 sortClauses.add(XWikiRepositoryModel.toSolrOrderField(RatingExtension.FIELD_AVERAGE_VOTE) + " desc");
151  37 sortClauses.add(XWikiRepositoryModel.toSolrOrderField(RatingExtension.FIELD_TOTAL_VOTES) + " desc");
152    } else {
153    // Sort by score by default when search query is not empty
154  11 sortClauses.add("score desc");
155    }
156   
157  48 solrQuery.bindValue("sort", sortClauses);
158   
159    // /////////////////
160    // Filtering
161    // /////////////////
162   
163  48 List<String> fq = new ArrayList<>(query.getFilters().size() + 1);
164   
165    // TODO: should be filter only on current wiki ?
166   
167    // We want only valid extensions documents
168  48 fq.add(XWikiRepositoryModel.SOLRPROP_EXTENSION_VALIDEXTENSION + ":true");
169   
170    // Request filters
171  48 for (Filter fiter : query.getFilters()) {
172  13 String solrField = XWikiRepositoryModel.toSolrField(fiter.getField());
173  13 if (solrField != null) {
174  13 StringBuilder builder = new StringBuilder();
175   
176  13 builder.append(solrField);
177  13 builder.append(':');
178   
179  13 if (fiter.getComparison() == COMPARISON.EQUAL) {
180  13 builder.append(fiter.getValueString());
181    } else {
182  0 builder.append('*' + fiter.getValueString() + '*');
183    }
184   
185  13 fq.add(builder.toString());
186    }
187    }
188   
189  48 solrQuery.bindValue("fq", fq);
190   
191    // /////////////////
192    // Execute
193    // /////////////////
194   
195  48 QueryResponse response = (QueryResponse) solrQuery.execute().get(0);
196   
197  48 SolrDocumentList documents = response.getResults();
198   
199  48 result.setOffset((int) documents.getStart());
200  48 result.setTotalHits((int) documents.getNumFound());
201   
202    // O means unset for solr but we want it to be literally interpreted to be consistent with previous behavior and
203    // other searches behavior
204  48 if (query.getLimit() != 0) {
205  47 for (SolrDocument document : documents) {
206  13 result.getExtensions().add(createExtensionVersionFromSolrDocument(document));
207    }
208    }
209   
210  48 return result;
211    }
212    }