mirror of https://github.com/apache/archiva.git
[MRM-90]
submitted by Gwen Harold Autencio -filtered/advanced search additional changes to patch: -applied formatting -removed unused methods and imports git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@696137 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
dbc8a0f7d9
commit
d0771be563
|
@ -69,4 +69,21 @@ public interface CrossRepositorySearch
|
||||||
* @return the results.
|
* @return the results.
|
||||||
*/
|
*/
|
||||||
public SearchResults searchForChecksum( String principal, List<String> selectedRepos, String checksum, SearchResultLimits limits );
|
public SearchResults searchForChecksum( String principal, List<String> selectedRepos, String checksum, SearchResultLimits limits );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search for a specific artifact matching the given field values. The search is performed on the bytecode
|
||||||
|
* index/indices.
|
||||||
|
*
|
||||||
|
* @param principal
|
||||||
|
* @param selectedRepos repository to be searched
|
||||||
|
* @param groupId groupId to be matched
|
||||||
|
* @param artifactId artifactId to be matched
|
||||||
|
* @param version version to be matched
|
||||||
|
* @param className Java class or package name to be matched
|
||||||
|
* @param limits the limits to apply to the search results
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public SearchResults executeFilteredSearch( String principal, List<String> selectedRepos, String groupId,
|
||||||
|
String artifactId, String version, String className,
|
||||||
|
SearchResultLimits limits );
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.lucene.document.Document;
|
import org.apache.lucene.document.Document;
|
||||||
|
import org.apache.lucene.index.Term;
|
||||||
import org.apache.lucene.queryParser.MultiFieldQueryParser;
|
import org.apache.lucene.queryParser.MultiFieldQueryParser;
|
||||||
import org.apache.lucene.queryParser.ParseException;
|
import org.apache.lucene.queryParser.ParseException;
|
||||||
import org.apache.lucene.queryParser.QueryParser;
|
import org.apache.lucene.queryParser.QueryParser;
|
||||||
|
@ -32,16 +33,20 @@ import org.apache.lucene.search.BooleanQuery;
|
||||||
import org.apache.lucene.search.Filter;
|
import org.apache.lucene.search.Filter;
|
||||||
import org.apache.lucene.search.Hits;
|
import org.apache.lucene.search.Hits;
|
||||||
import org.apache.lucene.search.MultiSearcher;
|
import org.apache.lucene.search.MultiSearcher;
|
||||||
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.QueryWrapperFilter;
|
import org.apache.lucene.search.QueryWrapperFilter;
|
||||||
import org.apache.lucene.search.Searchable;
|
import org.apache.lucene.search.Searchable;
|
||||||
|
import org.apache.lucene.search.TermQuery;
|
||||||
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
|
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
|
||||||
import org.apache.maven.archiva.configuration.ConfigurationNames;
|
import org.apache.maven.archiva.configuration.ConfigurationNames;
|
||||||
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
|
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
|
||||||
|
import org.apache.maven.archiva.indexer.ArtifactKeys;
|
||||||
import org.apache.maven.archiva.indexer.RepositoryContentIndex;
|
import org.apache.maven.archiva.indexer.RepositoryContentIndex;
|
||||||
import org.apache.maven.archiva.indexer.RepositoryContentIndexFactory;
|
import org.apache.maven.archiva.indexer.RepositoryContentIndexFactory;
|
||||||
import org.apache.maven.archiva.indexer.RepositoryIndexException;
|
import org.apache.maven.archiva.indexer.RepositoryIndexException;
|
||||||
import org.apache.maven.archiva.indexer.RepositoryIndexSearchException;
|
import org.apache.maven.archiva.indexer.RepositoryIndexSearchException;
|
||||||
import org.apache.maven.archiva.indexer.bytecode.BytecodeHandlers;
|
import org.apache.maven.archiva.indexer.bytecode.BytecodeHandlers;
|
||||||
|
import org.apache.maven.archiva.indexer.bytecode.BytecodeKeys;
|
||||||
import org.apache.maven.archiva.indexer.filecontent.FileContentHandlers;
|
import org.apache.maven.archiva.indexer.filecontent.FileContentHandlers;
|
||||||
import org.apache.maven.archiva.indexer.hashcodes.HashcodesHandlers;
|
import org.apache.maven.archiva.indexer.hashcodes.HashcodesHandlers;
|
||||||
import org.apache.maven.archiva.indexer.hashcodes.HashcodesKeys;
|
import org.apache.maven.archiva.indexer.hashcodes.HashcodesKeys;
|
||||||
|
@ -57,7 +62,7 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DefaultCrossRepositorySearch
|
* DefaultCrossRepositorySearch
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
|
* @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
* @plexus.component role="org.apache.maven.archiva.indexer.search.CrossRepositorySearch" role-hint="default"
|
* @plexus.component role="org.apache.maven.archiva.indexer.search.CrossRepositorySearch" role-hint="default"
|
||||||
|
@ -66,12 +71,12 @@ public class DefaultCrossRepositorySearch
|
||||||
implements CrossRepositorySearch, RegistryListener, Initializable
|
implements CrossRepositorySearch, RegistryListener, Initializable
|
||||||
{
|
{
|
||||||
private Logger log = LoggerFactory.getLogger( DefaultCrossRepositorySearch.class );
|
private Logger log = LoggerFactory.getLogger( DefaultCrossRepositorySearch.class );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @plexus.requirement role-hint="lucene"
|
* @plexus.requirement role-hint="lucene"
|
||||||
*/
|
*/
|
||||||
private RepositoryContentIndexFactory indexFactory;
|
private RepositoryContentIndexFactory indexFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @plexus.requirement
|
* @plexus.requirement
|
||||||
*/
|
*/
|
||||||
|
@ -79,14 +84,61 @@ public class DefaultCrossRepositorySearch
|
||||||
|
|
||||||
private List<ManagedRepositoryConfiguration> localIndexedRepositories = new ArrayList<ManagedRepositoryConfiguration>();
|
private List<ManagedRepositoryConfiguration> localIndexedRepositories = new ArrayList<ManagedRepositoryConfiguration>();
|
||||||
|
|
||||||
public SearchResults searchForChecksum( String principal, List<String> selectedRepos, String checksum, SearchResultLimits limits )
|
public SearchResults executeFilteredSearch( String principal, List<String> selectedRepos, String groupId,
|
||||||
|
String artifactId, String version, String className,
|
||||||
|
SearchResultLimits limits )
|
||||||
|
{
|
||||||
|
List<RepositoryContentIndex> indexes = getBytecodeIndexes( principal, selectedRepos );
|
||||||
|
SearchResults results = new SearchResults();
|
||||||
|
BooleanQuery booleanQuery = new BooleanQuery();
|
||||||
|
|
||||||
|
if ( groupId != null && groupId.length() > 0 )
|
||||||
|
{
|
||||||
|
parseAndAdd( booleanQuery, ArtifactKeys.GROUPID, groupId, "\\.|-" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( artifactId != null && artifactId.length() > 0 )
|
||||||
|
{
|
||||||
|
parseAndAdd( booleanQuery, ArtifactKeys.ARTIFACTID, artifactId, "\\.|-" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( version != null && version.length() > 0 )
|
||||||
|
{
|
||||||
|
parseAndAdd( booleanQuery, ArtifactKeys.VERSION, version, "\\.|-" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( className != null && className.length() > 0 )
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
QueryParser parser =
|
||||||
|
new MultiFieldQueryParser( new String[] { BytecodeKeys.CLASSES, BytecodeKeys.FILES,
|
||||||
|
BytecodeKeys.METHODS }, new BytecodeHandlers().getAnalyzer() );
|
||||||
|
booleanQuery.add( parser.parse( className ), BooleanClause.Occur.MUST );
|
||||||
|
}
|
||||||
|
catch ( ParseException e )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LuceneQuery query = new LuceneQuery( booleanQuery );
|
||||||
|
results = searchAll( query, limits, indexes, null );
|
||||||
|
results.getRepositories().add( this.localIndexedRepositories );
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SearchResults searchForChecksum( String principal, List<String> selectedRepos, String checksum,
|
||||||
|
SearchResultLimits limits )
|
||||||
{
|
{
|
||||||
List<RepositoryContentIndex> indexes = getHashcodeIndexes( principal, selectedRepos );
|
List<RepositoryContentIndex> indexes = getHashcodeIndexes( principal, selectedRepos );
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
QueryParser parser = new MultiFieldQueryParser( new String[]{HashcodesKeys.MD5, HashcodesKeys.SHA1},
|
QueryParser parser = new MultiFieldQueryParser( new String[]{HashcodesKeys.MD5, HashcodesKeys.SHA1},
|
||||||
new HashcodesHandlers().getAnalyzer() );
|
new HashcodesHandlers().getAnalyzer() );
|
||||||
LuceneQuery query = new LuceneQuery( parser.parse( checksum ) );
|
LuceneQuery query = new LuceneQuery( parser.parse( checksum ) );
|
||||||
SearchResults results = searchAll( query, limits, indexes, null );
|
SearchResults results = searchAll( query, limits, indexes, null );
|
||||||
results.getRepositories().addAll( this.localIndexedRepositories );
|
results.getRepositories().addAll( this.localIndexedRepositories );
|
||||||
|
@ -124,23 +176,22 @@ public class DefaultCrossRepositorySearch
|
||||||
return new SearchResults();
|
return new SearchResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SearchResults searchForTerm( String principal, List<String> selectedRepos, String term, SearchResultLimits limits )
|
public SearchResults searchForTerm( String principal, List<String> selectedRepos, String term, SearchResultLimits limits )
|
||||||
{
|
{
|
||||||
return searchForTerm( principal, selectedRepos, term, limits, null );
|
return searchForTerm( principal, selectedRepos, term, limits, null );
|
||||||
}
|
}
|
||||||
|
|
||||||
public SearchResults searchForTerm( String principal, List<String> selectedRepos, String term,
|
public SearchResults searchForTerm( String principal, List<String> selectedRepos, String term,
|
||||||
SearchResultLimits limits, List<String> previousSearchTerms )
|
SearchResultLimits limits, List<String> previousSearchTerms )
|
||||||
{
|
{
|
||||||
List<RepositoryContentIndex> indexes = getFileContentIndexes( principal, selectedRepos );
|
List<RepositoryContentIndex> indexes = getFileContentIndexes( principal, selectedRepos );
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
QueryParser parser = new FileContentHandlers().getQueryParser();
|
QueryParser parser = new FileContentHandlers().getQueryParser();
|
||||||
LuceneQuery query = null;
|
LuceneQuery query = null;
|
||||||
SearchResults results = null;
|
SearchResults results = null;
|
||||||
if( previousSearchTerms == null || previousSearchTerms.isEmpty() )
|
if ( previousSearchTerms == null || previousSearchTerms.isEmpty() )
|
||||||
{
|
{
|
||||||
query = new LuceneQuery( parser.parse( term ) );
|
query = new LuceneQuery( parser.parse( term ) );
|
||||||
results = searchAll( query, limits, indexes, null );
|
results = searchAll( query, limits, indexes, null );
|
||||||
|
@ -149,17 +200,17 @@ public class DefaultCrossRepositorySearch
|
||||||
{
|
{
|
||||||
// AND the previous search terms
|
// AND the previous search terms
|
||||||
BooleanQuery booleanQuery = new BooleanQuery();
|
BooleanQuery booleanQuery = new BooleanQuery();
|
||||||
for( String previousSearchTerm : previousSearchTerms )
|
for ( String previousSearchTerm : previousSearchTerms )
|
||||||
{
|
{
|
||||||
booleanQuery.add( parser.parse( previousSearchTerm ), BooleanClause.Occur.MUST );
|
booleanQuery.add( parser.parse( previousSearchTerm ), BooleanClause.Occur.MUST );
|
||||||
}
|
}
|
||||||
|
|
||||||
query = new LuceneQuery( booleanQuery );
|
query = new LuceneQuery( booleanQuery );
|
||||||
Filter filter = new QueryWrapperFilter( parser.parse( term ) );
|
Filter filter = new QueryWrapperFilter( parser.parse( term ) );
|
||||||
results = searchAll( query, limits, indexes, filter );
|
results = searchAll( query, limits, indexes, filter );
|
||||||
}
|
}
|
||||||
results.getRepositories().addAll( this.localIndexedRepositories );
|
results.getRepositories().addAll( this.localIndexedRepositories );
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
catch ( ParseException e )
|
catch ( ParseException e )
|
||||||
|
@ -168,9 +219,9 @@ public class DefaultCrossRepositorySearch
|
||||||
}
|
}
|
||||||
|
|
||||||
// empty results.
|
// empty results.
|
||||||
return new SearchResults();
|
return new SearchResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
private SearchResults searchAll( LuceneQuery luceneQuery, SearchResultLimits limits, List<RepositoryContentIndex> indexes, Filter filter )
|
private SearchResults searchAll( LuceneQuery luceneQuery, SearchResultLimits limits, List<RepositoryContentIndex> indexes, Filter filter )
|
||||||
{
|
{
|
||||||
org.apache.lucene.search.Query specificQuery = luceneQuery.getLuceneQuery();
|
org.apache.lucene.search.Query specificQuery = luceneQuery.getLuceneQuery();
|
||||||
|
@ -203,7 +254,7 @@ public class DefaultCrossRepositorySearch
|
||||||
|
|
||||||
// Perform the search.
|
// Perform the search.
|
||||||
Hits hits = null;
|
Hits hits = null;
|
||||||
if( filter != null )
|
if ( filter != null )
|
||||||
{
|
{
|
||||||
hits = searcher.search( specificQuery, filter );
|
hits = searcher.search( specificQuery, filter );
|
||||||
}
|
}
|
||||||
|
@ -355,7 +406,7 @@ public class DefaultCrossRepositorySearch
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean indexExists( RepositoryContentIndex index )
|
private boolean indexExists( RepositoryContentIndex index )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -402,6 +453,26 @@ public class DefaultCrossRepositorySearch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void parseAndAdd( BooleanQuery query, String key, String value, String delimiter )
|
||||||
|
{
|
||||||
|
if ( value != null && value.length() > 0 )
|
||||||
|
{
|
||||||
|
String[] terms = value.split( delimiter );
|
||||||
|
for ( int i = 0; i < terms.length; i++ )
|
||||||
|
{
|
||||||
|
Term valueTerm = new Term( key, terms[i] );
|
||||||
|
Query valueQuery = new TermQuery( valueTerm );
|
||||||
|
query.add( valueQuery, BooleanClause.Occur.MUST );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Term valueTerm = new Term( key, value );
|
||||||
|
Query valueQuery = new TermQuery( valueTerm );
|
||||||
|
query.add( valueQuery, BooleanClause.Occur.MUST );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void initialize()
|
public void initialize()
|
||||||
throws InitializationException
|
throws InitializationException
|
||||||
{
|
{
|
||||||
|
|
|
@ -242,6 +242,51 @@ public class DefaultCrossRepositorySearchTest
|
||||||
"org.apache.maven.continuum.web.action.BuildDefinitionAction.isBuildFresh", null, true );
|
"org.apache.maven.continuum.web.action.BuildDefinitionAction.isBuildFresh", null, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testExecuteFilteredSearch()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
CrossRepositorySearch search = lookupCrossRepositorySearch();
|
||||||
|
|
||||||
|
String expectedRepos[] = new String[] { TEST_DEFAULT_REPO_ID };
|
||||||
|
|
||||||
|
String expectedResults[] = new String[] { "org1", "org2", "org3", "org4", "org5", "org6", "org7", "org8" };
|
||||||
|
|
||||||
|
String secondExpectedResults[] = new String[] { "continuum-webapp" };
|
||||||
|
|
||||||
|
String thirdExpectedResults[] = new String[] { "archiva-common" };
|
||||||
|
|
||||||
|
// search for groupId
|
||||||
|
assertFilteredSearchResults( expectedRepos, expectedResults, search, "org", null, null, null, 30 );
|
||||||
|
|
||||||
|
// search for groupId and artifactId
|
||||||
|
assertFilteredSearchResults( expectedRepos, secondExpectedResults, search, "org.apache.maven",
|
||||||
|
"continuum-webapp", null, null, 30 );
|
||||||
|
|
||||||
|
// search for groupId , artifactId and version
|
||||||
|
assertFilteredSearchResults( expectedRepos, thirdExpectedResults, search, "org.apache.maven.archiva",
|
||||||
|
"archiva-common", "1.0", null, 30 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertFilteredSearchResults ( String expectedRepos[], String expectedResults[], CrossRepositorySearch search,
|
||||||
|
String groupId, String artifactId, String version, String className , int rowCount )
|
||||||
|
{
|
||||||
|
SearchResultLimits limits = new SearchResultLimits( 0 );
|
||||||
|
limits.setPageSize( rowCount );
|
||||||
|
|
||||||
|
List<String> selectedRepos = new ArrayList<String>();
|
||||||
|
selectedRepos.addAll( Arrays.asList( expectedRepos ) );
|
||||||
|
|
||||||
|
SearchResults results = null;
|
||||||
|
|
||||||
|
results = search.executeFilteredSearch( "guest" , selectedRepos, groupId, artifactId, version, className, limits );
|
||||||
|
|
||||||
|
assertNotNull( "Search Results should not be null.", results );
|
||||||
|
assertEquals( "Repository Hits", expectedRepos.length, results.getRepositories().size() );
|
||||||
|
assertEquals( expectedRepos.length, 1);
|
||||||
|
assertEquals( TEST_DEFAULT_REPO_ID , selectedRepos.get( 0 ) );
|
||||||
|
assertEquals( "Search Result Hits", expectedResults.length, results.getHits().size() );
|
||||||
|
}
|
||||||
|
|
||||||
private void assertSearchResults( String expectedRepos[], String expectedResults[], CrossRepositorySearch search,
|
private void assertSearchResults( String expectedRepos[], String expectedResults[], CrossRepositorySearch search,
|
||||||
String term, List<String> previousSearchTerms, boolean bytecode )
|
String term, List<String> previousSearchTerms, boolean bytecode )
|
||||||
throws Exception
|
throws Exception
|
||||||
|
@ -251,11 +296,12 @@ public class DefaultCrossRepositorySearchTest
|
||||||
|
|
||||||
List<String> selectedRepos = new ArrayList<String>();
|
List<String> selectedRepos = new ArrayList<String>();
|
||||||
selectedRepos.addAll( Arrays.asList( expectedRepos ) );
|
selectedRepos.addAll( Arrays.asList( expectedRepos ) );
|
||||||
|
|
||||||
SearchResults results = null;
|
SearchResults results = null;
|
||||||
|
|
||||||
if( previousSearchTerms == null )
|
if( previousSearchTerms == null )
|
||||||
{
|
{
|
||||||
if( bytecode )
|
if( bytecode )
|
||||||
{
|
{
|
||||||
results = search.searchForBytecode( "guest", selectedRepos, term, limits );
|
results = search.searchForBytecode( "guest", selectedRepos, term, limits );
|
||||||
}
|
}
|
||||||
|
@ -268,16 +314,18 @@ public class DefaultCrossRepositorySearchTest
|
||||||
{
|
{
|
||||||
results = search.searchForTerm( "guest", selectedRepos, term, limits, previousSearchTerms );
|
results = search.searchForTerm( "guest", selectedRepos, term, limits, previousSearchTerms );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
assertNotNull( "Search Results should not be null.", results );
|
assertNotNull( "Search Results should not be null.", results );
|
||||||
assertEquals( "Repository Hits", expectedRepos.length, results.getRepositories().size() );
|
assertEquals( "Repository Hits", expectedRepos.length, results.getRepositories().size() );
|
||||||
|
|
||||||
// TODO: test the repository ids returned.
|
// TODO: test the repository ids returned.
|
||||||
|
|
||||||
assertEquals( "Search Result Hits", expectedResults.length, results.getHits().size() );
|
assertEquals( "Search Result Hits", expectedResults.length, results.getHits().size() );
|
||||||
// TODO: test the order of hits.
|
// TODO: test the order of hits.
|
||||||
// TODO: test the value of the hits.
|
// TODO: test the value of the hits.
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ManagedRepositoryConfiguration createRepository( String id, String name, File location )
|
protected ManagedRepositoryConfiguration createRepository( String id, String name, File location )
|
||||||
{
|
{
|
||||||
ManagedRepositoryConfiguration repo = new ManagedRepositoryConfiguration();
|
ManagedRepositoryConfiguration repo = new ManagedRepositoryConfiguration();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
package org.apache.maven.archiva.web.action;
|
package org.apache.maven.archiva.web.action;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
* or more contributor license agreements. See the NOTICE file
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
@ -23,10 +23,12 @@ import java.net.MalformedURLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import com.opensymphony.xwork.ActionContext;
|
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
|
||||||
|
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
|
||||||
import org.apache.maven.archiva.database.ArchivaDAO;
|
import org.apache.maven.archiva.database.ArchivaDAO;
|
||||||
import org.apache.maven.archiva.database.Constraint;
|
import org.apache.maven.archiva.database.Constraint;
|
||||||
import org.apache.maven.archiva.database.constraints.ArtifactsByChecksumConstraint;
|
import org.apache.maven.archiva.database.constraints.ArtifactsByChecksumConstraint;
|
||||||
|
@ -42,6 +44,9 @@ import org.apache.maven.archiva.security.PrincipalNotFoundException;
|
||||||
import org.apache.maven.archiva.security.UserRepositories;
|
import org.apache.maven.archiva.security.UserRepositories;
|
||||||
import org.codehaus.plexus.xwork.action.PlexusActionSupport;
|
import org.codehaus.plexus.xwork.action.PlexusActionSupport;
|
||||||
|
|
||||||
|
import com.opensymphony.xwork.ActionContext;
|
||||||
|
import com.opensymphony.xwork.Preparable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search all indexed fields by the given criteria.
|
* Search all indexed fields by the given criteria.
|
||||||
*
|
*
|
||||||
|
@ -49,10 +54,16 @@ import org.codehaus.plexus.xwork.action.PlexusActionSupport;
|
||||||
*/
|
*/
|
||||||
public class SearchAction
|
public class SearchAction
|
||||||
extends PlexusActionSupport
|
extends PlexusActionSupport
|
||||||
{
|
implements Preparable
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Query string.
|
* Query string.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
private ArchivaConfiguration archivaConfiguration;
|
||||||
|
|
||||||
|
private Map<String, ManagedRepositoryConfiguration> managedRepositories;
|
||||||
|
|
||||||
private String q;
|
private String q;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,27 +101,132 @@ public class SearchAction
|
||||||
|
|
||||||
private int totalPages;
|
private int totalPages;
|
||||||
|
|
||||||
private boolean searchResultsOnly;
|
private boolean searchResultsOnly;
|
||||||
|
|
||||||
private String completeQueryString;
|
private String completeQueryString;
|
||||||
|
|
||||||
private static final String COMPLETE_QUERY_STRING_SEPARATOR = ";";
|
private static final String COMPLETE_QUERY_STRING_SEPARATOR = ";";
|
||||||
|
|
||||||
private static final String BYTECODE_KEYWORD = "bytecode:";
|
private static final String BYTECODE_KEYWORD = "bytecode:";
|
||||||
|
|
||||||
|
private List<String> managedRepositoryList;
|
||||||
|
|
||||||
|
private String groupId;
|
||||||
|
|
||||||
|
private String artifactId;
|
||||||
|
|
||||||
|
private String version;
|
||||||
|
|
||||||
|
private String className;
|
||||||
|
|
||||||
|
private int rowCount = 30;
|
||||||
|
|
||||||
|
private String repositoryId;
|
||||||
|
|
||||||
|
private boolean fromFilterSearch;
|
||||||
|
|
||||||
|
private boolean filterSearch = false;
|
||||||
|
|
||||||
|
private boolean fromResultsPage;
|
||||||
|
|
||||||
|
private int num;
|
||||||
|
|
||||||
|
public boolean isFromResultsPage()
|
||||||
|
{
|
||||||
|
return fromResultsPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFromResultsPage( boolean fromResultsPage )
|
||||||
|
{
|
||||||
|
this.fromResultsPage = fromResultsPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFromFilterSearch()
|
||||||
|
{
|
||||||
|
return fromFilterSearch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFromFilterSearch( boolean fromFilterSearch )
|
||||||
|
{
|
||||||
|
this.fromFilterSearch = fromFilterSearch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void prepare()
|
||||||
|
{
|
||||||
|
managedRepositoryList = new ArrayList<String>();
|
||||||
|
managedRepositoryList = getObservableRepos();
|
||||||
|
|
||||||
|
if ( managedRepositoryList.size() > 0 )
|
||||||
|
{
|
||||||
|
managedRepositoryList.add( "all" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// advanced search MRM-90 -- filtered search
|
||||||
|
public String filteredSearch()
|
||||||
|
throws MalformedURLException, RepositoryIndexException, RepositoryIndexSearchException
|
||||||
|
{
|
||||||
|
fromFilterSearch = true;
|
||||||
|
|
||||||
|
if ( CollectionUtils.isEmpty( managedRepositoryList ) )
|
||||||
|
{
|
||||||
|
return GlobalResults.ACCESS_TO_NO_REPOS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchResultLimits limits = new SearchResultLimits( currentPage );
|
||||||
|
|
||||||
|
limits.setPageSize( rowCount );
|
||||||
|
List<String> selectedRepos = new ArrayList<String>();
|
||||||
|
|
||||||
|
if ( repositoryId.equals( "all" ) )
|
||||||
|
{
|
||||||
|
selectedRepos = getObservableRepos();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
selectedRepos.add( repositoryId );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( CollectionUtils.isEmpty( selectedRepos ) )
|
||||||
|
{
|
||||||
|
return GlobalResults.ACCESS_TO_NO_REPOS;
|
||||||
|
}
|
||||||
|
|
||||||
|
results =
|
||||||
|
crossRepoSearch.executeFilteredSearch( getPrincipal(), selectedRepos, groupId, artifactId, version,
|
||||||
|
className, limits );
|
||||||
|
|
||||||
|
if ( results.isEmpty() )
|
||||||
|
{
|
||||||
|
addActionError( "No results found" );
|
||||||
|
return INPUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
totalPages = results.getTotalHits() / limits.getPageSize();
|
||||||
|
|
||||||
|
if ( ( results.getTotalHits() % limits.getPageSize() ) != 0 )
|
||||||
|
{
|
||||||
|
totalPages = totalPages + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
public String quickSearch()
|
public String quickSearch()
|
||||||
throws MalformedURLException, RepositoryIndexException, RepositoryIndexSearchException
|
throws MalformedURLException, RepositoryIndexException, RepositoryIndexSearchException
|
||||||
{
|
{
|
||||||
/* TODO: give action message if indexing is in progress.
|
/* TODO: give action message if indexing is in progress.
|
||||||
* This should be based off a count of 'unprocessed' artifacts.
|
* This should be based off a count of 'unprocessed' artifacts.
|
||||||
* This (yet to be written) routine could tell the user that X (unprocessed) artifacts are not yet
|
* This (yet to be written) routine could tell the user that X (unprocessed) artifacts are not yet
|
||||||
* present in the full text search.
|
* present in the full text search.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
assert q != null && q.length() != 0;
|
assert q != null && q.length() != 0;
|
||||||
|
|
||||||
|
fromFilterSearch = false;
|
||||||
|
|
||||||
SearchResultLimits limits = new SearchResultLimits( currentPage );
|
SearchResultLimits limits = new SearchResultLimits( currentPage );
|
||||||
|
|
||||||
List<String> selectedRepos = getObservableRepos();
|
List<String> selectedRepos = getObservableRepos();
|
||||||
if ( CollectionUtils.isEmpty( selectedRepos ) )
|
if ( CollectionUtils.isEmpty( selectedRepos ) )
|
||||||
{
|
{
|
||||||
|
@ -118,13 +234,13 @@ public class SearchAction
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isBytecodeSearch( q ) )
|
if( isBytecodeSearch( q ) )
|
||||||
{
|
{
|
||||||
results = crossRepoSearch.searchForBytecode( getPrincipal(), selectedRepos, removeKeyword( q ), limits );
|
results = crossRepoSearch.searchForBytecode( getPrincipal(), selectedRepos, removeKeyword( q ), limits );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( searchResultsOnly && !completeQueryString.equals( "" ) )
|
if( searchResultsOnly && !completeQueryString.equals( "" ) )
|
||||||
{
|
{
|
||||||
results = crossRepoSearch.searchForTerm( getPrincipal(), selectedRepos, q, limits, parseCompleteQueryString() );
|
results = crossRepoSearch.searchForTerm( getPrincipal(), selectedRepos, q, limits, parseCompleteQueryString() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -133,33 +249,33 @@ public class SearchAction
|
||||||
results = crossRepoSearch.searchForTerm( getPrincipal(), selectedRepos, q, limits );
|
results = crossRepoSearch.searchForTerm( getPrincipal(), selectedRepos, q, limits );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( results.isEmpty() )
|
if ( results.isEmpty() )
|
||||||
{
|
{
|
||||||
addActionError( "No results found" );
|
addActionError( "No results found" );
|
||||||
return INPUT;
|
return INPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
totalPages = results.getTotalHits() / limits.getPageSize();
|
totalPages = results.getTotalHits() / limits.getPageSize();
|
||||||
|
|
||||||
if( (results.getTotalHits() % limits.getPageSize()) != 0 )
|
if( (results.getTotalHits() % limits.getPageSize()) != 0 )
|
||||||
{
|
{
|
||||||
totalPages = totalPages + 1;
|
totalPages = totalPages + 1;
|
||||||
}
|
}
|
||||||
// TODO: filter / combine the artifacts by version? (is that even possible with non-artifact hits?)
|
// TODO: filter / combine the artifacts by version? (is that even possible with non-artifact hits?)
|
||||||
|
|
||||||
/* I don't think that we should, as I expect us to utilize the 'score' system in lucene in
|
/* I don't think that we should, as I expect us to utilize the 'score' system in lucene in
|
||||||
* the future to return relevant links better.
|
* the future to return relevant links better.
|
||||||
* I expect the lucene scoring system to take multiple hits on different areas of a single document
|
* I expect the lucene scoring system to take multiple hits on different areas of a single document
|
||||||
* to result in a higher score.
|
* to result in a higher score.
|
||||||
* - Joakim
|
* - Joakim
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if( !isEqualToPreviousSearchTerm( q ) )
|
if( !isEqualToPreviousSearchTerm( q ) )
|
||||||
{
|
{
|
||||||
buildCompleteQueryString( q );
|
buildCompleteQueryString( q );
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,10 +301,10 @@ public class SearchAction
|
||||||
|
|
||||||
if ( databaseResults.size() == 1 )
|
if ( databaseResults.size() == 1 )
|
||||||
{
|
{
|
||||||
// 1 hit? return it's information directly!
|
// 1 hit? return it's information directly!
|
||||||
return ARTIFACT;
|
return ARTIFACT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RESULTS;
|
return RESULTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,12 +313,12 @@ public class SearchAction
|
||||||
{
|
{
|
||||||
return INPUT;
|
return INPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getPrincipal()
|
private String getPrincipal()
|
||||||
{
|
{
|
||||||
return archivaXworkUser.getActivePrincipal( ActionContext.getContext().getSession() );
|
return archivaXworkUser.getActivePrincipal( ActionContext.getContext().getSession() );
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> getObservableRepos()
|
private List<String> getObservableRepos()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -227,44 +343,44 @@ public class SearchAction
|
||||||
|
|
||||||
private void buildCompleteQueryString( String searchTerm )
|
private void buildCompleteQueryString( String searchTerm )
|
||||||
{
|
{
|
||||||
if( searchTerm.indexOf( COMPLETE_QUERY_STRING_SEPARATOR ) != -1 )
|
if ( searchTerm.indexOf( COMPLETE_QUERY_STRING_SEPARATOR ) != -1 )
|
||||||
{
|
{
|
||||||
searchTerm = StringUtils.remove( searchTerm, COMPLETE_QUERY_STRING_SEPARATOR );
|
searchTerm = StringUtils.remove( searchTerm, COMPLETE_QUERY_STRING_SEPARATOR );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( completeQueryString == null || "".equals( completeQueryString ) )
|
if ( completeQueryString == null || "".equals( completeQueryString ) )
|
||||||
{
|
{
|
||||||
completeQueryString = searchTerm;
|
completeQueryString = searchTerm;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
completeQueryString = completeQueryString + COMPLETE_QUERY_STRING_SEPARATOR + searchTerm;
|
completeQueryString = completeQueryString + COMPLETE_QUERY_STRING_SEPARATOR + searchTerm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> parseCompleteQueryString()
|
private List<String> parseCompleteQueryString()
|
||||||
{
|
{
|
||||||
List<String> parsedCompleteQueryString = new ArrayList<String>();
|
List<String> parsedCompleteQueryString = new ArrayList<String>();
|
||||||
String[] parsed = StringUtils.split( completeQueryString, COMPLETE_QUERY_STRING_SEPARATOR );
|
String[] parsed = StringUtils.split( completeQueryString, COMPLETE_QUERY_STRING_SEPARATOR );
|
||||||
CollectionUtils.addAll( parsedCompleteQueryString, parsed );
|
CollectionUtils.addAll( parsedCompleteQueryString, parsed );
|
||||||
|
|
||||||
return parsedCompleteQueryString;
|
return parsedCompleteQueryString;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEqualToPreviousSearchTerm( String searchTerm )
|
private boolean isEqualToPreviousSearchTerm( String searchTerm )
|
||||||
{
|
{
|
||||||
if( !"".equals( completeQueryString ) )
|
if ( !"".equals( completeQueryString ) )
|
||||||
{
|
{
|
||||||
String[] parsed = StringUtils.split( completeQueryString, COMPLETE_QUERY_STRING_SEPARATOR );
|
String[] parsed = StringUtils.split( completeQueryString, COMPLETE_QUERY_STRING_SEPARATOR );
|
||||||
if( StringUtils.equalsIgnoreCase( searchTerm, parsed[ parsed.length - 1 ] ) )
|
if ( StringUtils.equalsIgnoreCase( searchTerm, parsed[parsed.length - 1] ) )
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getQ()
|
public String getQ()
|
||||||
{
|
{
|
||||||
return q;
|
return q;
|
||||||
|
@ -284,12 +400,12 @@ public class SearchAction
|
||||||
{
|
{
|
||||||
return databaseResults;
|
return databaseResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCurrentPage( int page )
|
public void setCurrentPage( int page )
|
||||||
{
|
{
|
||||||
this.currentPage = page;
|
this.currentPage = page;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCurrentPage()
|
public int getCurrentPage()
|
||||||
{
|
{
|
||||||
return currentPage;
|
return currentPage;
|
||||||
|
@ -323,23 +439,123 @@ public class SearchAction
|
||||||
public void setCompleteQueryString( String completeQueryString )
|
public void setCompleteQueryString( String completeQueryString )
|
||||||
{
|
{
|
||||||
this.completeQueryString = completeQueryString;
|
this.completeQueryString = completeQueryString;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBytecodeSearch( String queryString )
|
private boolean isBytecodeSearch( String queryString )
|
||||||
{
|
{
|
||||||
if( queryString.startsWith( BYTECODE_KEYWORD ) )
|
if ( queryString.startsWith( BYTECODE_KEYWORD ) )
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String removeKeyword( String queryString )
|
private String removeKeyword( String queryString )
|
||||||
{
|
{
|
||||||
String qString = StringUtils.uncapitalize( queryString );
|
String qString = StringUtils.uncapitalize( queryString );
|
||||||
qString= StringUtils.remove( queryString, BYTECODE_KEYWORD );
|
qString = StringUtils.remove( queryString, BYTECODE_KEYWORD );
|
||||||
|
|
||||||
return qString;
|
return qString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ArchivaConfiguration getArchivaConfiguration()
|
||||||
|
{
|
||||||
|
return archivaConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArchivaConfiguration( ArchivaConfiguration archivaConfiguration )
|
||||||
|
{
|
||||||
|
this.archivaConfiguration = archivaConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, ManagedRepositoryConfiguration> getManagedRepositories()
|
||||||
|
{
|
||||||
|
return getArchivaConfiguration().getConfiguration().getManagedRepositoriesAsMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setManagedRepositories( Map<String, ManagedRepositoryConfiguration> managedRepositories )
|
||||||
|
{
|
||||||
|
this.managedRepositories = managedRepositories;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGroupId()
|
||||||
|
{
|
||||||
|
return groupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGroupId( String groupId )
|
||||||
|
{
|
||||||
|
this.groupId = groupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getArtifactId()
|
||||||
|
{
|
||||||
|
return artifactId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArtifactId( String artifactId )
|
||||||
|
{
|
||||||
|
this.artifactId = artifactId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion()
|
||||||
|
{
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion( String version )
|
||||||
|
{
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRowCount()
|
||||||
|
{
|
||||||
|
return rowCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRowCount( int rowCount )
|
||||||
|
{
|
||||||
|
this.rowCount = rowCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFilterSearch()
|
||||||
|
{
|
||||||
|
return filterSearch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFilterSearch( boolean filterSearch )
|
||||||
|
{
|
||||||
|
this.filterSearch = filterSearch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRepositoryId()
|
||||||
|
{
|
||||||
|
return repositoryId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRepositoryId( String repositoryId )
|
||||||
|
{
|
||||||
|
this.repositoryId = repositoryId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getManagedRepositoryList()
|
||||||
|
{
|
||||||
|
return managedRepositoryList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setManagedRepositoryList( List<String> managedRepositoryList )
|
||||||
|
{
|
||||||
|
this.managedRepositoryList = managedRepositoryList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClassName()
|
||||||
|
{
|
||||||
|
return className;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClassName( String className )
|
||||||
|
{
|
||||||
|
this.className = className;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
<!--
|
||||||
|
~ Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
~ or more contributor license agreements. See the NOTICE file
|
||||||
|
~ distributed with this work for additional information
|
||||||
|
~ regarding copyright ownership. The ASF licenses this file
|
||||||
|
~ to you under the Apache License, Version 2.0 (the
|
||||||
|
~ "License"); you may not use this file except in compliance
|
||||||
|
~ with the License. You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing,
|
||||||
|
~ software distributed under the License is distributed on an
|
||||||
|
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
~ KIND, either express or implied. See the License for the
|
||||||
|
~ specific language governing permissions and limitations
|
||||||
|
~ under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
|
||||||
|
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
|
||||||
|
|
||||||
|
<validators>
|
||||||
|
<field name="rowCount">
|
||||||
|
<field-validator type="int">
|
||||||
|
<message>Invalid entry</message>
|
||||||
|
</field-validator>
|
||||||
|
<field-validator type="int">
|
||||||
|
<param name="min">1</param>
|
||||||
|
<message>Row count must be larger than ${min}.</message>
|
||||||
|
</field-validator>
|
||||||
|
</field>
|
||||||
|
</validators>
|
|
@ -143,6 +143,16 @@
|
||||||
<action name="index" class="searchAction" method="input">
|
<action name="index" class="searchAction" method="input">
|
||||||
<result name="input">/WEB-INF/jsp/quickSearch.jsp</result>
|
<result name="input">/WEB-INF/jsp/quickSearch.jsp</result>
|
||||||
</action>
|
</action>
|
||||||
|
|
||||||
|
<action name="advancedSearch" class="searchAction" method="input">
|
||||||
|
<result name="input">/WEB-INF/jsp/advancedSearch.jsp</result>
|
||||||
|
</action>
|
||||||
|
|
||||||
|
<action name="filteredSearch" class="searchAction" method="filteredSearch">
|
||||||
|
<result name="input">/WEB-INF/jsp/advancedSearch.jsp</result>
|
||||||
|
<result>/WEB-INF/jsp/results.jsp</result>
|
||||||
|
<result name="error">/WEB-INF/jsp/quickSearch.jsp</result>
|
||||||
|
</action>
|
||||||
|
|
||||||
<action name="quickSearch" class="searchAction" method="quickSearch">
|
<action name="quickSearch" class="searchAction" method="quickSearch">
|
||||||
<result name="input">/WEB-INF/jsp/quickSearch.jsp</result>
|
<result name="input">/WEB-INF/jsp/quickSearch.jsp</result>
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
<%--
|
||||||
|
~ Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
~ or more contributor license agreements. See the NOTICE file
|
||||||
|
~ distributed with this work for additional information
|
||||||
|
~ regarding copyright ownership. The ASF licenses this file
|
||||||
|
~ to you under the Apache License, Version 2.0 (the
|
||||||
|
~ "License"); you may not use this file except in compliance
|
||||||
|
~ with the License. You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing,
|
||||||
|
~ software distributed under the License is distributed on an
|
||||||
|
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
~ KIND, either express or implied. See the License for the
|
||||||
|
~ specific language governing permissions and limitations
|
||||||
|
~ under the License.
|
||||||
|
--%>
|
||||||
|
|
||||||
|
<%@ taglib prefix="ww" uri="/webwork" %>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Advanced Search</title>
|
||||||
|
<ww:head/>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<ww:if test="%{infoMessage != null}">
|
||||||
|
<p>${infoMessage}</p>
|
||||||
|
</ww:if>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>Advanced Search</h1>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="contentArea">
|
||||||
|
|
||||||
|
<div id="searchBox">
|
||||||
|
|
||||||
|
<ww:form method="get" action="filteredSearch" validate="true">
|
||||||
|
<ww:textfield label="Row Count" size="50" name="rowCount"/>
|
||||||
|
<ww:textfield label="Group Id" size="50" name="groupId"/>
|
||||||
|
<ww:textfield label="Artifact Id" size="50" name="artifactId"/>
|
||||||
|
<ww:textfield label="Version" size="50" name="version"/>
|
||||||
|
<ww:textfield label="Class / Package" size="50" name="className"/>
|
||||||
|
<ww:select name="repositoryId" label="Repository ID" list="managedRepositoryList"/>
|
||||||
|
<ww:hidden name="completeQueryString" value="${completeQueryString}"/>
|
||||||
|
<ww:hidden name="fromFilterSearch" value="${fromFilterSearch}"/>
|
||||||
|
<ww:submit label="Go!"/>
|
||||||
|
</ww:form>
|
||||||
|
|
||||||
|
<ww:url id="indexUrl" action="index"/>
|
||||||
|
<ww:a href="%{indexUrl}">
|
||||||
|
Quick Search Page
|
||||||
|
</ww:a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
document.getElementById("filteredSearch_groupId").focus();
|
||||||
|
</script>
|
||||||
|
<ww:actionerror/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -44,6 +44,11 @@
|
||||||
document.getElementById("quickSearch_q").focus();
|
document.getElementById("quickSearch_q").focus();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<ww:url id="filteredSearchUrl" action="advancedSearch"/>
|
||||||
|
<ww:a href="%{filteredSearchUrl}">
|
||||||
|
Advanced Search
|
||||||
|
</ww:a>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<ww:actionerror/>
|
<ww:actionerror/>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -30,7 +30,12 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<h1>Search</h1>
|
<c:if test="${fromFilterSearch == true}">
|
||||||
|
<h1>Advanced Search</h1>
|
||||||
|
</c:if>
|
||||||
|
<c:if test="${fromFilterSearch == false}">
|
||||||
|
<h1>Search</h1>
|
||||||
|
</c:if>
|
||||||
|
|
||||||
<c:url var="imgNextPageUrl" value="/images/icon_next_page.gif"/>
|
<c:url var="imgNextPageUrl" value="/images/icon_next_page.gif"/>
|
||||||
<c:url var="imgPrevPageUrl" value="/images/icon_prev_page.gif"/>
|
<c:url var="imgPrevPageUrl" value="/images/icon_prev_page.gif"/>
|
||||||
|
@ -39,20 +44,44 @@
|
||||||
|
|
||||||
<div id="contentArea">
|
<div id="contentArea">
|
||||||
<div id="searchBox">
|
<div id="searchBox">
|
||||||
<ww:form method="get" action="quickSearch" validate="true">
|
|
||||||
<ww:textfield label="Search for" size="50" name="q"/>
|
|
||||||
<ww:checkbox label="Search within results" name="searchResultsOnly"/>
|
|
||||||
<ww:hidden name="completeQueryString" value="${completeQueryString}"/>
|
|
||||||
<ww:submit label="Go!"/>
|
|
||||||
</ww:form>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
<c:if test="${fromFilterSearch == true}">
|
||||||
document.getElementById("quickSearch_q").focus();
|
<ww:form method="get" action="filteredSearch" validate="true">
|
||||||
</script>
|
<ww:textfield label="Row Count" size="50" name="rowCount"/>
|
||||||
|
<ww:textfield label="Group Id" size="50" name="groupId"/>
|
||||||
|
<ww:textfield label="Artifact Id" size="50" name="artifactId"/>
|
||||||
|
<ww:textfield label="Version" size="50" name="version"/>
|
||||||
|
<ww:textfield label="Class / Package" size="50" name="className"/>
|
||||||
|
<ww:select name="repositoryId" label="Repository ID" list="managedRepositoryList"/>
|
||||||
|
<ww:hidden name="completeQueryString" value="${completeQueryString}"/>
|
||||||
|
<ww:hidden name="fromFilterSearch" value="${fromFilterSearch}"/>
|
||||||
|
<ww:submit label="Go!"/>
|
||||||
|
</ww:form>
|
||||||
|
|
||||||
|
<ww:url id="indexUrl" action="index"/>
|
||||||
|
<ww:a href="%{indexUrl}">
|
||||||
|
Quick Search Page
|
||||||
|
</ww:a>
|
||||||
|
<script type="text/javascript">
|
||||||
|
document.getElementById("filteredSearch_groupId").focus();
|
||||||
|
</script>
|
||||||
|
</c:if>
|
||||||
|
<c:if test="${fromFilterSearch == false}">
|
||||||
|
<ww:form method="get" action="quickSearch" validate="true">
|
||||||
|
<ww:textfield label="Search for" size="50" name="q"/>
|
||||||
|
<ww:checkbox label="Search within results" name="searchResultsOnly"/>
|
||||||
|
<ww:hidden name="completeQueryString" value="${completeQueryString}"/>
|
||||||
|
<ww:submit label="Go!"/>
|
||||||
|
</ww:form>
|
||||||
|
<script type="text/javascript">
|
||||||
|
document.getElementById("quickSearch_q").focus();
|
||||||
|
</script>
|
||||||
|
</c:if>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<ww:actionerror/>
|
<ww:actionerror/>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1>Results</h1>
|
<h1>Results</h1>
|
||||||
|
@ -62,10 +91,10 @@
|
||||||
|
|
||||||
<%-- search was made from the indices --%>
|
<%-- search was made from the indices --%>
|
||||||
<c:when test="${databaseResults == null}">
|
<c:when test="${databaseResults == null}">
|
||||||
<c:set var="hitsNum">${fn:length(results.hits) + (currentPage * results.limits.pageSize)}</c:set>
|
<c:set var="hitsNum">${fn:length(results.hits) + (currentPage * results.limits.pageSize)}</c:set>
|
||||||
<c:choose>
|
<c:choose>
|
||||||
<c:when test="${results.totalHits > results.limits.pageSize}">
|
<c:when test="${results.totalHits > results.limits.pageSize}">
|
||||||
<p>Hits: ${(hitsNum - results.limits.pageSize) + 1} to ${hitsNum} of ${results.totalHits}</p>
|
<p>Hits: ${(hitsNum - results.limits.pageSize) + 1} to ${hitsNum} of ${results.totalHits}</p>
|
||||||
</c:when>
|
</c:when>
|
||||||
<c:otherwise>
|
<c:otherwise>
|
||||||
<p>Hits: 1 to ${hitsNum} of ${results.totalHits}</p>
|
<p>Hits: 1 to ${hitsNum} of ${results.totalHits}</p>
|
||||||
|
@ -80,22 +109,55 @@
|
||||||
<%-- Pagination start --%>
|
<%-- Pagination start --%>
|
||||||
<p>
|
<p>
|
||||||
<%-- Prev & Next icons --%>
|
<%-- Prev & Next icons --%>
|
||||||
<c:set var="prevPageUrl">
|
<c:if test="${fromFilterSearch == false}">
|
||||||
<ww:url action="quickSearch" namespace="/">
|
<c:set var="prevPageUrl">
|
||||||
<ww:param name="q" value="%{'${q}'}"/>
|
<ww:url action="quickSearch" namespace="/">
|
||||||
<ww:param name="searchResultsOnly" value="%{'${searchResultsOnly}'}"/>
|
<ww:param name="q" value="%{'${q}'}"/>
|
||||||
<ww:param name="completeQueryString" value="%{'${completeQueryString}'}"/>
|
<ww:param name="currentPage" value="%{'${currentPage - 1}'}"/>
|
||||||
<ww:param name="currentPage" value="%{'${currentPage - 1}'}"/>
|
</ww:url>
|
||||||
</ww:url>
|
</c:set>
|
||||||
</c:set>
|
<c:set var="nextPageUrl">
|
||||||
<c:set var="nextPageUrl">
|
<ww:url action="quickSearch" namespace="/">
|
||||||
<ww:url action="quickSearch" namespace="/">
|
<ww:param name="q" value="%{'${q}'}"/>
|
||||||
<ww:param name="q" value="%{'${q}'}"/>
|
<ww:param name="currentPage" value="%{'${currentPage + 1}'}"/>
|
||||||
<ww:param name="searchResultsOnly" value="%{'${searchResultsOnly}'}"/>
|
</ww:url>
|
||||||
<ww:param name="completeQueryString" value="%{'${completeQueryString}'}"/>
|
</c:set>
|
||||||
<ww:param name="currentPage" value="%{'${currentPage + 1}'}"/>
|
</c:if>
|
||||||
</ww:url>
|
|
||||||
</c:set>
|
<c:if test="${fromFilterSearch == true}">
|
||||||
|
<c:set var="prevPageUrl">
|
||||||
|
<ww:url action="filteredSearch" namespace="/">
|
||||||
|
<%-- <ww:param name="q" value="%{'${q}'}"/> --%>
|
||||||
|
<ww:param name="rowCount" value="%{'${rowCount}'}"/>
|
||||||
|
<ww:param name="groupId" value="%{'${groupId}'}"/>
|
||||||
|
<ww:param name="artifactId" value="%{'${artifactId}'}"/>
|
||||||
|
<ww:param name="version" value="%{'${version}'}"/>
|
||||||
|
<ww:param name="className" value="%{'${className}'}"/>
|
||||||
|
<ww:param name="repositoryId" value="%{'${repositoryId}'}"/>
|
||||||
|
<ww:param name="filterSearch" value="%{'${filterSearch}'}"/>
|
||||||
|
<ww:param name="fromResultsPage" value="true"/>
|
||||||
|
<ww:param name="currentPage" value="%{'${currentPage - 1}'}"/>
|
||||||
|
<ww:param name="searchResultsOnly" value="%{'${searchResultsOnly}'}"/>
|
||||||
|
<ww:param name="completeQueryString" value="%{'${completeQueryString}'}"/>
|
||||||
|
</ww:url>
|
||||||
|
</c:set>
|
||||||
|
<c:set var="nextPageUrl">
|
||||||
|
<ww:url action="filteredSearch" namespace="/">
|
||||||
|
<%-- <ww:param name="q" value="%{'${q}'}"/> --%>
|
||||||
|
<ww:param name="rowCount" value="%{'${rowCount}'}"/>
|
||||||
|
<ww:param name="groupId" value="%{'${groupId}'}"/>
|
||||||
|
<ww:param name="artifactId" value="%{'${artifactId}'}"/>
|
||||||
|
<ww:param name="version" value="%{'${version}'}"/>
|
||||||
|
<ww:param name="className" value="%{'${className}'}"/>
|
||||||
|
<ww:param name="repositoryId" value="%{'${repositoryId}'}"/>
|
||||||
|
<ww:param name="filterSearch" value="%{'${filterSearch}'}"/>
|
||||||
|
<ww:param name="fromResultsPage" value="true"/>
|
||||||
|
<ww:param name="currentPage" value="%{'${currentPage + 1}'}"/>
|
||||||
|
<ww:param name="searchResultsOnly" value="%{'${searchResultsOnly}'}"/>
|
||||||
|
<ww:param name="completeQueryString" value="%{'${completeQueryString}'}"/>
|
||||||
|
</ww:url>
|
||||||
|
</c:set>
|
||||||
|
</c:if>
|
||||||
|
|
||||||
<c:choose>
|
<c:choose>
|
||||||
<c:when test="${currentPage == 0}">
|
<c:when test="${currentPage == 0}">
|
||||||
|
@ -133,25 +195,54 @@
|
||||||
</c:choose>
|
</c:choose>
|
||||||
|
|
||||||
<c:forEach var="i" begin="${beginVal}" end="${endVal}">
|
<c:forEach var="i" begin="${beginVal}" end="${endVal}">
|
||||||
<c:choose>
|
<c:if test="${fromFilterSearch == false}">
|
||||||
<c:when test="${i != currentPage}">
|
<c:choose>
|
||||||
<c:set var="specificPageUrl">
|
<c:when test="${i != currentPage}">
|
||||||
<ww:url action="quickSearch" namespace="/">
|
<c:set var="specificPageUrl">
|
||||||
<ww:param name="q" value="%{'${q}'}"/>
|
<ww:url action="quickSearch" namespace="/">
|
||||||
<ww:param name="currentPage" value="%{'${i}'}"/>
|
<ww:param name="q" value="%{'${q}'}"/>
|
||||||
<ww:param name="searchResultsOnly" value="%{'${searchResultsOnly}'}"/>
|
<ww:param name="currentPage" value="%{'${i}'}"/>
|
||||||
<ww:param name="completeQueryString" value="%{'${completeQueryString}'}"/>
|
<ww:param name="searchResultsOnly" value="%{'${searchResultsOnly}'}"/>
|
||||||
</ww:url>
|
<ww:param name="completeQueryString" value="%{'${completeQueryString}'}"/>
|
||||||
</c:set>
|
</ww:url>
|
||||||
<a href="${specificPageUrl}">${i + 1}</a>
|
</c:set>
|
||||||
</c:when>
|
<a href="${specificPageUrl}">${i + 1}</a>
|
||||||
<c:otherwise>
|
</c:when>
|
||||||
<b>${i + 1}</b>
|
<c:otherwise>
|
||||||
</c:otherwise>
|
<b>${i + 1}</b>
|
||||||
</c:choose>
|
</c:otherwise>
|
||||||
|
</c:choose>
|
||||||
|
</c:if>
|
||||||
|
|
||||||
|
<c:if test="${fromFilterSearch == true}">
|
||||||
|
<c:choose>
|
||||||
|
<c:when test="${i != currentPage}">
|
||||||
|
<c:set var="specificPageUrl">
|
||||||
|
<ww:url action="filteredSearch" namespace="/">
|
||||||
|
<%-- <ww:param name="q" value="%{'${q}'}"/> --%>
|
||||||
|
<ww:param name="rowCount" value="%{'${rowCount}'}"/>
|
||||||
|
<ww:param name="groupId" value="%{'${groupId}'}"/>
|
||||||
|
<ww:param name="artifactId" value="%{'${artifactId}'}"/>
|
||||||
|
<ww:param name="version" value="%{'${version}'}"/>
|
||||||
|
<ww:param name="className" value="%{'${className}'}"/>
|
||||||
|
<ww:param name="repositoryId" value="%{'${repositoryId}'}"/>
|
||||||
|
<ww:param name="filterSearch" value="%{'${filterSearch}'}"/>
|
||||||
|
<ww:param name="fromResultsPage" value="true"/>
|
||||||
|
<ww:param name="currentPage" value="%{'${i}'}"/>
|
||||||
|
<ww:param name="searchResultsOnly" value="%{'${searchResultsOnly}'}"/>
|
||||||
|
<ww:param name="completeQueryString" value="%{'${completeQueryString}'}"/>
|
||||||
|
</ww:url>
|
||||||
|
</c:set>
|
||||||
|
<a href="${specificPageUrl}">${i + 1}</a>
|
||||||
|
</c:when>
|
||||||
|
<c:otherwise>
|
||||||
|
<b>${i + 1}</b>
|
||||||
|
</c:otherwise>
|
||||||
|
</c:choose>
|
||||||
|
</c:if>
|
||||||
</c:forEach>
|
</c:forEach>
|
||||||
|
|
||||||
<c:choose>
|
<c:choose>
|
||||||
<c:when test="${currentPage == (totalPages - 1)}">
|
<c:when test="${currentPage == (totalPages - 1)}">
|
||||||
<img src="${imgNextPageDisabledUrl}"/>
|
<img src="${imgNextPageDisabledUrl}"/>
|
||||||
</c:when>
|
</c:when>
|
||||||
|
|
Loading…
Reference in New Issue