2013-03-01 03:04:29 +06:00
using System ;
using System.Collections.Generic ;
2013-02-27 05:24:45 +06:00
using System.Linq ;
2013-02-28 05:05:06 +06:00
using System.Net ;
using System.Net.Http ;
using System.Web.Http ;
2013-02-27 05:24:45 +06:00
using Examine ;
2013-03-01 03:04:29 +06:00
using Examine.LuceneEngine ;
2013-02-27 05:24:45 +06:00
using Examine.LuceneEngine.Providers ;
2013-02-27 06:50:26 +06:00
using Examine.Providers ;
2013-02-28 05:05:06 +06:00
using Lucene.Net.Search ;
2013-02-27 05:24:45 +06:00
using Umbraco.Core ;
using Umbraco.Web.Search ;
using Umbraco.Web.WebApi ;
namespace Umbraco.Web.WebServices
{
public class ExamineManagementApiController : UmbracoAuthorizedApiController
{
/// <summary>
2013-02-27 06:50:26 +06:00
/// Get the details for indexers
2013-02-27 05:24:45 +06:00
/// </summary>
/// <returns></returns>
public IEnumerable < ExamineIndexerModel > GetIndexerDetails ( )
{
2013-02-28 05:05:06 +06:00
return ExamineManager . Instance . IndexProviderCollection . Select ( CreateModel ) ;
2013-02-27 05:24:45 +06:00
}
2013-02-27 06:50:26 +06:00
/// <summary>
/// Get the details for searchers
/// </summary>
/// <returns></returns>
public IEnumerable < ExamineSearcherModel > GetSearcherDetails ( )
{
var model = new List < ExamineSearcherModel > (
ExamineManager . Instance . SearchProviderCollection . Cast < BaseSearchProvider > ( ) . Select ( searcher = >
{
var indexerModel = new ExamineIndexerModel ( )
{
Name = searcher . Name
} ;
var props = TypeHelper . CachedDiscoverableProperties ( searcher . GetType ( ) , mustWrite : false )
2013-02-27 06:53:18 +06:00
//ignore these properties
2013-02-28 05:05:06 +06:00
. Where ( x = > ! new [ ] { "Description" } . InvariantContains ( x . Name ) )
2013-02-27 06:50:26 +06:00
. OrderBy ( x = > x . Name ) ;
foreach ( var p in props )
{
indexerModel . ProviderProperties . Add ( p . Name , p . GetValue ( searcher , null ) . ToString ( ) ) ;
}
return indexerModel ;
} ) ) ;
return model ;
}
2013-02-27 05:24:45 +06:00
2013-03-01 03:04:29 +06:00
public ISearchResults GetSearchResults ( string searcherName , string query , string queryType )
{
if ( queryType = = null )
throw new HttpResponseException ( new HttpResponseMessage ( HttpStatusCode . NotFound ) ) ;
if ( query . IsNullOrWhiteSpace ( ) )
return SearchResults . Empty ( ) ;
LuceneSearcher searcher ;
var msg = ValidateLuceneSearcher ( searcherName , out searcher ) ;
if ( msg . IsSuccessStatusCode )
{
if ( queryType . InvariantEquals ( "text" ) )
{
return searcher . Search ( query , false ) ;
}
if ( queryType . InvariantEquals ( "lucene" ) )
{
return searcher . Search ( searcher . CreateSearchCriteria ( ) . RawQuery ( query ) ) ;
}
throw new HttpResponseException ( new HttpResponseMessage ( HttpStatusCode . NotFound ) ) ;
}
throw new HttpResponseException ( msg ) ;
}
2013-02-28 05:05:06 +06:00
/// <summary>
/// Optimizes an index
/// </summary>
public HttpResponseMessage PostOptimizeIndex ( string indexerName )
{
LuceneIndexer indexer ;
var msg = ValidateLuceneIndexer ( indexerName , out indexer ) ;
if ( msg . IsSuccessStatusCode )
{
try
{
indexer . OptimizeIndex ( ) ;
}
catch ( System . Exception ex )
{
return new HttpResponseMessage ( HttpStatusCode . Conflict )
{
Content = new StringContent ( string . Format ( "The index could not be optimized, most likely there is another thread currently writing to the index. Error: {0}" , ex ) ) ,
ReasonPhrase = "Could Not Optimize"
} ;
}
}
return msg ;
}
2013-02-27 05:24:45 +06:00
2013-03-01 03:04:29 +06:00
/// <summary>
/// Rebuilds the index
/// </summary>
/// <param name="indexerName"></param>
/// <returns></returns>
public HttpResponseMessage PostRebuildIndex ( string indexerName )
{
LuceneIndexer indexer ;
var msg = ValidateLuceneIndexer ( indexerName , out indexer ) ;
if ( msg . IsSuccessStatusCode )
{
try
{
indexer . RebuildIndex ( ) ;
}
catch ( System . Exception ex )
{
return new HttpResponseMessage ( HttpStatusCode . Conflict )
{
Content = new StringContent ( string . Format ( "The index could not be rebuilt at this time, most likely there is another thread currently writing to the index. Error: {0}" , ex ) ) ,
ReasonPhrase = "Could Not Rebuild"
} ;
}
}
return msg ;
}
/// <summary>
/// Check if the index has been rebuilt
/// </summary>
/// <param name="indexerName"></param>
/// <returns></returns>
/// <remarks>
/// This is kind of rudementary since there's no way we can know that the index has rebuilt, we'll just check
/// if the index is locked based on Lucene apis
/// </remarks>
public ExamineIndexerModel PostCheckRebuildIndex ( string indexerName )
{
LuceneIndexer indexer ;
var msg = ValidateLuceneIndexer ( indexerName , out indexer ) ;
if ( msg . IsSuccessStatusCode )
{
var isLocked = indexer . IsIndexLocked ( ) ;
return isLocked
? null
: CreateModel ( indexer ) ;
}
throw new HttpResponseException ( msg ) ;
}
2013-02-28 05:05:06 +06:00
/// <summary>
/// Checks if the index is optimized
/// </summary>
/// <param name="indexerName"></param>
/// <returns></returns>
public ExamineIndexerModel PostCheckOptimizeIndex ( string indexerName )
{
LuceneIndexer indexer ;
var msg = ValidateLuceneIndexer ( indexerName , out indexer ) ;
if ( msg . IsSuccessStatusCode )
{
var isOptimized = indexer . IsIndexOptimized ( ) ;
return ! isOptimized
? null
: CreateModel ( indexer ) ;
}
throw new HttpResponseException ( msg ) ;
}
private ExamineIndexerModel CreateModel ( BaseIndexProvider indexer )
{
var indexerModel = new ExamineIndexerModel ( )
{
IndexCriteria = indexer . IndexerData ,
Name = indexer . Name
} ;
var props = TypeHelper . CachedDiscoverableProperties ( indexer . GetType ( ) , mustWrite : false )
//ignore these properties
. Where ( x = > ! new [ ] { "IndexerData" , "Description" , "WorkingFolder" } . InvariantContains ( x . Name ) )
. OrderBy ( x = > x . Name ) ;
foreach ( var p in props )
{
indexerModel . ProviderProperties . Add ( p . Name , p . GetValue ( indexer , null ) . ToString ( ) ) ;
}
var luceneIndexer = indexer as LuceneIndexer ;
if ( luceneIndexer ! = null & & luceneIndexer . IndexExists ( ) )
{
indexerModel . IsLuceneIndex = true ;
indexerModel . DocumentCount = luceneIndexer . GetIndexDocumentCount ( ) ;
indexerModel . FieldCount = luceneIndexer . GetIndexDocumentCount ( ) ;
indexerModel . IsOptimized = luceneIndexer . IsIndexOptimized ( ) ;
indexerModel . DeletionCount = luceneIndexer . GetDeletedDocumentsCount ( ) ;
}
return indexerModel ;
}
2013-02-27 22:21:58 +06:00
2013-03-01 03:04:29 +06:00
private HttpResponseMessage ValidateLuceneSearcher ( string searcherName , out LuceneSearcher searcher )
{
if ( ExamineManager . Instance . SearchProviderCollection . Cast < BaseSearchProvider > ( ) . Any ( x = > x . Name = = searcherName ) )
{
searcher = ExamineManager . Instance . SearchProviderCollection [ searcherName ] as LuceneSearcher ;
if ( searcher = = null )
{
return new HttpResponseMessage ( HttpStatusCode . BadRequest )
{
Content = new StringContent ( string . Format ( "The searcher {0} is not of type {1}" , searcherName , typeof ( LuceneSearcher ) ) ) ,
ReasonPhrase = "Wrong Searcher Type"
} ;
}
//return Ok!
return Request . CreateResponse ( HttpStatusCode . OK ) ;
}
searcher = null ;
return new HttpResponseMessage ( HttpStatusCode . BadRequest )
{
Content = new StringContent ( string . Format ( "No searcher found with name = {0}" , searcherName ) ) ,
ReasonPhrase = "Searcher Not Found"
} ;
}
2013-02-28 05:05:06 +06:00
private HttpResponseMessage ValidateLuceneIndexer ( string indexerName , out LuceneIndexer indexer )
{
if ( ExamineManager . Instance . IndexProviderCollection . Any ( x = > x . Name = = indexerName ) )
{
indexer = ExamineManager . Instance . IndexProviderCollection [ indexerName ] as LuceneIndexer ;
if ( indexer = = null )
{
return new HttpResponseMessage ( HttpStatusCode . BadRequest )
{
Content = new StringContent ( string . Format ( "The indexer {0} is not of type {1}" , indexerName , typeof ( LuceneIndexer ) ) ) ,
ReasonPhrase = "Wrong Indexer Type"
} ;
}
//return Ok!
return Request . CreateResponse ( HttpStatusCode . OK ) ;
}
indexer = null ;
return new HttpResponseMessage ( HttpStatusCode . BadRequest )
{
Content = new StringContent ( string . Format ( "No indexer found with name = {0}" , indexerName ) ) ,
ReasonPhrase = "Indexer Not Found"
} ;
}
2013-02-27 05:24:45 +06:00
}
}