mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
. Advanced Search improvements
. Fix to Lucene Indexer (from Andy) to correct the bug where if content was not indexed (e.g. JPEG) then it's mimetype/size values did not get added to the index. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2107 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -162,7 +162,7 @@ none=None
|
||||
no_selected_items=No selected items.
|
||||
search_select_item=Search for and select an item.
|
||||
search_select_items=Search for and select items.
|
||||
search_minimum=Please enter a minimum of {0} characters to perform a search.
|
||||
search_minimum=Not enough information was entered to perform a search, at least one value must be entered or a location selected to search within. Text fields require a minimum of {0} characters.
|
||||
filter=Filter
|
||||
choose_icon=Choose icon
|
||||
security=Security
|
||||
|
@@ -613,8 +613,6 @@ public class AdvancedSearchBean
|
||||
* Handler to perform a search based on the current criteria
|
||||
*/
|
||||
public String search()
|
||||
{
|
||||
if (this.text != null && this.text.length() != 0)
|
||||
{
|
||||
// construct the Search Context and set on the navigation bean
|
||||
// then simply navigating to the browse screen will cause it pickup the Search Context
|
||||
@@ -755,7 +753,6 @@ public class AdvancedSearchBean
|
||||
// set the Search Context onto the top-level navigator bean
|
||||
// this causes the browse screen to switch into search results view
|
||||
this.navigator.setSearchContext(search);
|
||||
}
|
||||
|
||||
return "browse";
|
||||
}
|
||||
|
@@ -578,9 +578,12 @@ public class BrowseBean implements IContextListener
|
||||
if (logger.isDebugEnabled())
|
||||
startTime = System.currentTimeMillis();
|
||||
|
||||
// special exit case for < 3 characters in length
|
||||
if (searchContext.getText().length() < getMinimumSearchLength())
|
||||
// get the searcher object to build the query
|
||||
String query = searchContext.buildQuery(getMinimumSearchLength());
|
||||
if (query == null)
|
||||
{
|
||||
// failed to build a valid query, the user probably did not enter the
|
||||
// minimum text required to construct a valid search
|
||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(FacesContext.getCurrentInstance(), MSG_SEARCH_MINIMUM),
|
||||
new Object[] {getMinimumSearchLength()}));
|
||||
this.containerNodes = Collections.<Node>emptyList();
|
||||
@@ -588,9 +591,7 @@ public class BrowseBean implements IContextListener
|
||||
return;
|
||||
}
|
||||
|
||||
// get the searcher object and perform the search of the root node
|
||||
String query = searchContext.buildQuery();
|
||||
|
||||
// perform the search against the repo
|
||||
UserTransaction tx = null;
|
||||
ResultSet results = null;
|
||||
try
|
||||
|
@@ -117,20 +117,26 @@ public final class SearchContext implements Serializable
|
||||
/**
|
||||
* Build the search query string based on the current search context members.
|
||||
*
|
||||
* @param minimum small possible textual string used for a match
|
||||
* this does not effect fixed values searches (e.g. boolean, int values) or date ranges
|
||||
*
|
||||
* @return prepared search query string
|
||||
*/
|
||||
public String buildQuery()
|
||||
public String buildQuery(int minimum)
|
||||
{
|
||||
String query;
|
||||
boolean validQuery = false;
|
||||
|
||||
// the QName for the well known "name" attribute
|
||||
String nameAttr = Repository.escapeQName(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, ELEMENT_NAME));
|
||||
|
||||
// match against content text
|
||||
String text = this.text.trim();
|
||||
String fullTextQuery;
|
||||
String nameAttrQuery;
|
||||
String fullTextQuery = null;
|
||||
String nameAttrQuery = null;
|
||||
|
||||
if (text.length() >= minimum)
|
||||
{
|
||||
if (text.indexOf(' ') == -1)
|
||||
{
|
||||
// simple single word text search
|
||||
@@ -195,6 +201,9 @@ public final class SearchContext implements Serializable
|
||||
}
|
||||
}
|
||||
|
||||
validQuery = true;
|
||||
}
|
||||
|
||||
// match a specific PATH for space location or categories
|
||||
StringBuilder pathQuery = null;
|
||||
if (location != null || (categories != null && categories.length !=0))
|
||||
@@ -223,11 +232,20 @@ public final class SearchContext implements Serializable
|
||||
{
|
||||
attributeQuery = new StringBuilder(queryAttributes.size() << 6);
|
||||
for (QName qname : queryAttributes.keySet())
|
||||
{
|
||||
String value = queryAttributes.get(qname).trim();
|
||||
if (value.length() >= minimum)
|
||||
{
|
||||
String escapedName = Repository.escapeQName(qname);
|
||||
String value = QueryParser.escape(queryAttributes.get(qname));
|
||||
attributeQuery.append(" +@").append(escapedName)
|
||||
.append(":").append(value).append('*');
|
||||
.append(":").append(QueryParser.escape(value)).append('*');
|
||||
}
|
||||
}
|
||||
|
||||
// handle the case where we did not add any attributes due to minimum length restrictions
|
||||
if (attributeQuery.length() == 0)
|
||||
{
|
||||
attributeQuery = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,17 +301,20 @@ public final class SearchContext implements Serializable
|
||||
String fileTypeQuery;
|
||||
if (contentType != null)
|
||||
{
|
||||
fileTypeQuery = " +TYPE:\"" + contentType + "\" ";
|
||||
fileTypeQuery = " TYPE:\"" + contentType + "\" ";
|
||||
}
|
||||
else
|
||||
{
|
||||
// default to cm:content
|
||||
fileTypeQuery = " +TYPE:\"{" + NamespaceService.CONTENT_MODEL_1_0_URI + "}content\" ";
|
||||
fileTypeQuery = " TYPE:\"{" + NamespaceService.CONTENT_MODEL_1_0_URI + "}content\" ";
|
||||
}
|
||||
|
||||
// match against FOLDER type
|
||||
String folderTypeQuery = " +TYPE:\"{" + NamespaceService.CONTENT_MODEL_1_0_URI + "}folder\" ";
|
||||
String folderTypeQuery = " TYPE:\"{" + NamespaceService.CONTENT_MODEL_1_0_URI + "}folder\" ";
|
||||
|
||||
if (text.length() >= minimum)
|
||||
{
|
||||
// text query for name and/or full text specified
|
||||
switch (mode)
|
||||
{
|
||||
case SearchContext.SEARCH_ALL:
|
||||
@@ -316,6 +337,29 @@ public final class SearchContext implements Serializable
|
||||
default:
|
||||
throw new IllegalStateException("Unknown search mode specified: " + mode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no text query specified - must be an attribute/value query only
|
||||
switch (mode)
|
||||
{
|
||||
case SearchContext.SEARCH_ALL:
|
||||
query = '(' + fileTypeQuery + " OR " + folderTypeQuery + ')';
|
||||
break;
|
||||
|
||||
case SearchContext.SEARCH_FILE_NAMES:
|
||||
case SearchContext.SEARCH_FILE_NAMES_CONTENTS:
|
||||
query = fileTypeQuery;
|
||||
break;
|
||||
|
||||
case SearchContext.SEARCH_SPACE_NAMES:
|
||||
query = folderTypeQuery;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalStateException("Unknown search mode specified: " + mode);
|
||||
}
|
||||
}
|
||||
|
||||
// match entire query against any additional attributes specified
|
||||
if (attributeQuery != null)
|
||||
@@ -329,6 +373,14 @@ public final class SearchContext implements Serializable
|
||||
query = "(" + pathQuery + ") AND (" + query + ')';
|
||||
}
|
||||
|
||||
// check that we have a query worth executing - if we have no attributes, paths or text/name search
|
||||
// then we'll only have a search against files/type TYPE which does nothing by itself!
|
||||
validQuery = validQuery | (attributeQuery != null) | (pathQuery != null);
|
||||
if (validQuery == false)
|
||||
{
|
||||
query = null;
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Query: " + query);
|
||||
|
||||
@@ -589,7 +641,7 @@ public final class SearchContext implements Serializable
|
||||
{
|
||||
root.addElement(ELEMENT_CONTENT_TYPE).addText(this.contentType);
|
||||
}
|
||||
if (this.mimeType != null)
|
||||
if (this.mimeType != null && this.mimeType.length() != 0)
|
||||
{
|
||||
root.addElement(ELEMENT_MIMETYPE).addText(this.mimeType);
|
||||
}
|
||||
|
@@ -33,19 +33,6 @@
|
||||
function pageLoaded()
|
||||
{
|
||||
document.getElementById("advsearch:search-text").focus();
|
||||
checkButtonState();
|
||||
}
|
||||
|
||||
function checkButtonState()
|
||||
{
|
||||
if (document.getElementById("advsearch:search-text").value.length == 0 )
|
||||
{
|
||||
document.getElementById("advsearch:search-button").disabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
document.getElementById("advsearch:search-button").disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
@@ -147,8 +134,7 @@
|
||||
<tr>
|
||||
<td colspan=2>
|
||||
<h:outputText value="#{msg.look_for}" style="font-weight:bold" />:
|
||||
<h:inputText id="search-text" value="#{AdvancedSearchBean.text}" size="48" maxlength="1024"
|
||||
onkeyup="javascript:checkButtonState();" onchange="javascript:checkButtonState();" /> *
|
||||
<h:inputText id="search-text" value="#{AdvancedSearchBean.text}" size="48" maxlength="1024" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
Reference in New Issue
Block a user