]> source.dussan.org Git - archiva.git/blob
d797c072cbdf8868446eb19e09d170a299f6e604
[archiva.git] /
1 package org.apache.maven.archiva.web.action;
2
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements.  See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership.  The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License.  You may obtain a copy of the License at
11  *
12  *   http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied.  See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */
21
22 import java.net.MalformedURLException;
23 import java.util.Collections;
24 import java.util.List;
25
26 import com.opensymphony.xwork.ActionContext;
27 import org.apache.commons.collections.CollectionUtils;
28 import org.apache.commons.lang.StringUtils;
29 import org.apache.maven.archiva.database.ArchivaDAO;
30 import org.apache.maven.archiva.database.Constraint;
31 import org.apache.maven.archiva.database.constraints.ArtifactsByChecksumConstraint;
32 import org.apache.maven.archiva.indexer.RepositoryIndexException;
33 import org.apache.maven.archiva.indexer.RepositoryIndexSearchException;
34 import org.apache.maven.archiva.indexer.search.CrossRepositorySearch;
35 import org.apache.maven.archiva.indexer.search.SearchResultLimits;
36 import org.apache.maven.archiva.indexer.search.SearchResults;
37 import org.apache.maven.archiva.security.AccessDeniedException;
38 import org.apache.maven.archiva.security.ArchivaSecurityException;
39 import org.apache.maven.archiva.security.ArchivaXworkUser;
40 import org.apache.maven.archiva.security.PrincipalNotFoundException;
41 import org.apache.maven.archiva.security.UserRepositories;
42 import org.codehaus.plexus.xwork.action.PlexusActionSupport;
43
44 /**
45  * Search all indexed fields by the given criteria.
46  *
47  * @plexus.component role="com.opensymphony.xwork.Action" role-hint="searchAction"
48  */
49 public class SearchAction
50     extends PlexusActionSupport
51 {           
52     /**
53      * Query string.
54      */
55     private String q;
56
57     /**
58      * @plexus.requirement role-hint="jdo"
59      */
60     private ArchivaDAO dao;
61
62     /**
63      * The Search Results.
64      */
65     private SearchResults results;
66
67     /**
68      * @plexus.requirement role-hint="default"
69      */
70     private CrossRepositorySearch crossRepoSearch;
71     
72     /**
73      * @plexus.requirement
74      */
75     private UserRepositories userRepositories;
76     
77     private static final String RESULTS = "results";
78
79     private static final String ARTIFACT = "artifact";
80
81     private List databaseResults;
82     
83     private int currentPage = 0;
84     
85     private int totalPages;
86
87     public String quickSearch()
88         throws MalformedURLException, RepositoryIndexException, RepositoryIndexSearchException
89     {
90         /* TODO: give action message if indexing is in progress.
91          * This should be based off a count of 'unprocessed' artifacts.
92          * This (yet to be written) routine could tell the user that X (unprocessed) artifacts are not yet 
93          * present in the full text search.
94          */
95
96         assert q != null && q.length() != 0;
97         
98         SearchResultLimits limits = new SearchResultLimits( currentPage );
99         
100         List<String> selectedRepos = getObservableRepos();
101         if ( CollectionUtils.isEmpty( selectedRepos ) )
102         {
103             return GlobalResults.ACCESS_TO_NO_REPOS;
104         }
105
106         results = crossRepoSearch.searchForTerm( getPrincipal(), selectedRepos, q, limits );
107         
108         if ( results.isEmpty() )
109         {
110             addActionError( "No results found" );
111             return INPUT;
112         }
113         
114         totalPages = results.getTotalHits() / limits.getPageSize();
115         
116         if( (results.getTotalHits() % limits.getPageSize()) != 0 )
117         {
118             totalPages = totalPages + 1;
119         }
120         // TODO: filter / combine the artifacts by version? (is that even possible with non-artifact hits?)
121
122         /* I don't think that we should, as I expect us to utilize the 'score' system in lucene in 
123          * the future to return relevant links better.
124          * I expect the lucene scoring system to take multiple hits on different areas of a single document
125          * to result in a higher score. 
126          *   - Joakim
127          */
128
129         return SUCCESS;
130     }
131
132     public String findArtifact()
133         throws Exception
134     {
135         // TODO: give action message if indexing is in progress
136
137         if ( StringUtils.isBlank( q ) )
138         {
139             addActionError( "Unable to search for a blank checksum" );
140             return INPUT;
141         }
142
143         Constraint constraint = new ArtifactsByChecksumConstraint( q );
144         databaseResults = dao.getArtifactDAO().queryArtifacts( constraint );
145
146         if ( databaseResults.isEmpty() )
147         {
148             addActionError( "No results found" );
149             return INPUT;
150         }
151
152         if ( databaseResults.size() == 1 )
153         {
154             // 1 hit? return it's information directly!            
155             return ARTIFACT;
156         }
157         
158         return RESULTS;
159     }
160
161     @Override
162     public String doInput()
163     {
164         return INPUT;
165     }
166     
167     private String getPrincipal()
168     {
169         return ArchivaXworkUser.getActivePrincipal( ActionContext.getContext().getSession() );
170     }
171     
172     private List<String> getObservableRepos()
173     {
174         try
175         {
176             return userRepositories.getObservableRepositoryIds( getPrincipal() );
177         }
178         catch ( PrincipalNotFoundException e )
179         {
180             getLogger().warn( e.getMessage(), e );
181         }
182         catch ( AccessDeniedException e )
183         {
184             getLogger().warn( e.getMessage(), e );
185             // TODO: pass this onto the screen.
186         }
187         catch ( ArchivaSecurityException e )
188         {
189             getLogger().warn( e.getMessage(), e );
190         }
191         return Collections.emptyList();
192     }
193
194     public String getQ()
195     {
196         return q;
197     }
198
199     public void setQ( String q )
200     {
201         this.q = q;
202     }
203
204     public SearchResults getResults()
205     {
206         return results;
207     }
208
209     public List getDatabaseResults()
210     {
211         return databaseResults;
212     }
213     
214     public void setCurrentPage( int page )
215     {
216         this.currentPage = page;
217     }
218     
219     public int getCurrentPage()
220     {
221         return currentPage;
222     }
223
224     public int getTotalPages()
225     {
226         return totalPages;
227     }
228
229     public void setTotalPages( int totalPages )
230     {
231         this.totalPages = totalPages;
232     }
233 }