mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +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.
|
no_selected_items=No selected items.
|
||||||
search_select_item=Search for and select an item.
|
search_select_item=Search for and select an item.
|
||||||
search_select_items=Search for and select items.
|
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
|
filter=Filter
|
||||||
choose_icon=Choose icon
|
choose_icon=Choose icon
|
||||||
security=Security
|
security=Security
|
||||||
|
@@ -614,148 +614,145 @@ public class AdvancedSearchBean
|
|||||||
*/
|
*/
|
||||||
public String search()
|
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
|
||||||
|
SearchContext search = new SearchContext();
|
||||||
|
|
||||||
|
search.setText(this.text);
|
||||||
|
|
||||||
|
if (this.mode.equals(MODE_ALL))
|
||||||
{
|
{
|
||||||
// construct the Search Context and set on the navigation bean
|
search.setMode(SearchContext.SEARCH_ALL);
|
||||||
// then simply navigating to the browse screen will cause it pickup the Search Context
|
|
||||||
SearchContext search = new SearchContext();
|
|
||||||
|
|
||||||
search.setText(this.text);
|
|
||||||
|
|
||||||
if (this.mode.equals(MODE_ALL))
|
|
||||||
{
|
|
||||||
search.setMode(SearchContext.SEARCH_ALL);
|
|
||||||
}
|
|
||||||
else if (this.mode.equals(MODE_FILES_TEXT))
|
|
||||||
{
|
|
||||||
search.setMode(SearchContext.SEARCH_FILE_NAMES_CONTENTS);
|
|
||||||
}
|
|
||||||
else if (this.mode.equals(MODE_FILES))
|
|
||||||
{
|
|
||||||
search.setMode(SearchContext.SEARCH_FILE_NAMES);
|
|
||||||
}
|
|
||||||
else if (this.mode.equals(MODE_FOLDERS))
|
|
||||||
{
|
|
||||||
search.setMode(SearchContext.SEARCH_SPACE_NAMES);
|
|
||||||
}
|
|
||||||
|
|
||||||
// additional attributes search
|
|
||||||
if (this.description != null && this.description.length() != 0)
|
|
||||||
{
|
|
||||||
search.addAttributeQuery(ContentModel.PROP_DESCRIPTION, this.description);
|
|
||||||
}
|
|
||||||
if (this.title != null && this.title.length() != 0)
|
|
||||||
{
|
|
||||||
search.addAttributeQuery(ContentModel.PROP_TITLE, this.title);
|
|
||||||
}
|
|
||||||
if (this.author != null && this.author.length() != 0)
|
|
||||||
{
|
|
||||||
search.addAttributeQuery(ContentModel.PROP_AUTHOR, this.author);
|
|
||||||
}
|
|
||||||
if (this.contentFormat != null && this.contentFormat.length() != 0)
|
|
||||||
{
|
|
||||||
search.setMimeType(this.contentFormat);
|
|
||||||
}
|
|
||||||
if (this.createdDateChecked == true)
|
|
||||||
{
|
|
||||||
SimpleDateFormat df = CachingDateFormat.getDateFormat();
|
|
||||||
String strCreatedDate = df.format(this.createdDateFrom);
|
|
||||||
String strCreatedDateTo = df.format(this.createdDateTo);
|
|
||||||
search.addRangeQuery(ContentModel.PROP_CREATED, strCreatedDate, strCreatedDateTo, true);
|
|
||||||
}
|
|
||||||
if (this.modifiedDateChecked == true)
|
|
||||||
{
|
|
||||||
SimpleDateFormat df = CachingDateFormat.getDateFormat();
|
|
||||||
String strModifiedDate = df.format(this.modifiedDateFrom);
|
|
||||||
String strModifiedDateTo = df.format(this.modifiedDateTo);
|
|
||||||
search.addRangeQuery(ContentModel.PROP_MODIFIED, strModifiedDate, strModifiedDateTo, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// walk each of the custom properties add add them as additional attributes
|
|
||||||
for (String qname : this.customProperties.keySet())
|
|
||||||
{
|
|
||||||
Object value = this.customProperties.get(qname);
|
|
||||||
DataTypeDefinition typeDef = getCustomPropertyLookup().get(qname);
|
|
||||||
if (typeDef != null)
|
|
||||||
{
|
|
||||||
QName typeName = typeDef.getName();
|
|
||||||
if (DataTypeDefinition.DATE.equals(typeName) || DataTypeDefinition.DATETIME.equals(typeName))
|
|
||||||
{
|
|
||||||
// only apply date to search if the user has checked the enable checkbox
|
|
||||||
if (value != null && Boolean.valueOf(value.toString()) == true)
|
|
||||||
{
|
|
||||||
SimpleDateFormat df = CachingDateFormat.getDateFormat();
|
|
||||||
String strDateFrom = df.format(this.customProperties.get(
|
|
||||||
UISearchCustomProperties.PREFIX_DATE_FROM + qname));
|
|
||||||
String strDateTo = df.format(this.customProperties.get(
|
|
||||||
UISearchCustomProperties.PREFIX_DATE_TO + qname));
|
|
||||||
search.addRangeQuery(QName.createQName(qname), strDateFrom, strDateTo, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (DataTypeDefinition.BOOLEAN.equals(typeName))
|
|
||||||
{
|
|
||||||
if (((Boolean)value) == true)
|
|
||||||
{
|
|
||||||
search.addFixedValueQuery(QName.createQName(qname), value.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (DataTypeDefinition.NODE_REF.equals(typeName) || DataTypeDefinition.CATEGORY.equals(typeName))
|
|
||||||
{
|
|
||||||
if (value != null)
|
|
||||||
{
|
|
||||||
search.addFixedValueQuery(QName.createQName(qname), value.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (DataTypeDefinition.INT.equals(typeName) || DataTypeDefinition.LONG.equals(typeName) ||
|
|
||||||
DataTypeDefinition.FLOAT.equals(typeName) || DataTypeDefinition.DOUBLE.equals(typeName))
|
|
||||||
{
|
|
||||||
String strVal = value.toString();
|
|
||||||
if (strVal != null && strVal.length() != 0)
|
|
||||||
{
|
|
||||||
search.addFixedValueQuery(QName.createQName(qname), strVal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// by default use toString() value - this is for text fields and unknown types
|
|
||||||
String strVal = value.toString();
|
|
||||||
if (strVal != null && strVal.length() != 0)
|
|
||||||
{
|
|
||||||
search.addAttributeQuery(QName.createQName(qname), strVal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// location path search
|
|
||||||
if (this.lookin.equals(LOOKIN_OTHER) && this.location != null)
|
|
||||||
{
|
|
||||||
search.setLocation(SearchContext.getPathFromSpaceRef(this.location, this.locationChildren));
|
|
||||||
}
|
|
||||||
|
|
||||||
// category path search
|
|
||||||
if (this.categories.size() != 0)
|
|
||||||
{
|
|
||||||
String[] paths = new String[this.categories.size()];
|
|
||||||
for (int i=0; i<paths.length; i++)
|
|
||||||
{
|
|
||||||
Node category = this.categories.get(i);
|
|
||||||
boolean includeChildren = (Boolean)category.getProperties().get(INCLUDE_CHILDREN);
|
|
||||||
paths[i] = SearchContext.getPathFromSpaceRef(category.getNodeRef(), includeChildren);
|
|
||||||
}
|
|
||||||
search.setCategories(paths);
|
|
||||||
}
|
|
||||||
|
|
||||||
// content type restriction
|
|
||||||
if (this.contentType != null)
|
|
||||||
{
|
|
||||||
search.setContentType(this.contentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
else if (this.mode.equals(MODE_FILES_TEXT))
|
||||||
|
{
|
||||||
|
search.setMode(SearchContext.SEARCH_FILE_NAMES_CONTENTS);
|
||||||
|
}
|
||||||
|
else if (this.mode.equals(MODE_FILES))
|
||||||
|
{
|
||||||
|
search.setMode(SearchContext.SEARCH_FILE_NAMES);
|
||||||
|
}
|
||||||
|
else if (this.mode.equals(MODE_FOLDERS))
|
||||||
|
{
|
||||||
|
search.setMode(SearchContext.SEARCH_SPACE_NAMES);
|
||||||
|
}
|
||||||
|
|
||||||
|
// additional attributes search
|
||||||
|
if (this.description != null && this.description.length() != 0)
|
||||||
|
{
|
||||||
|
search.addAttributeQuery(ContentModel.PROP_DESCRIPTION, this.description);
|
||||||
|
}
|
||||||
|
if (this.title != null && this.title.length() != 0)
|
||||||
|
{
|
||||||
|
search.addAttributeQuery(ContentModel.PROP_TITLE, this.title);
|
||||||
|
}
|
||||||
|
if (this.author != null && this.author.length() != 0)
|
||||||
|
{
|
||||||
|
search.addAttributeQuery(ContentModel.PROP_AUTHOR, this.author);
|
||||||
|
}
|
||||||
|
if (this.contentFormat != null && this.contentFormat.length() != 0)
|
||||||
|
{
|
||||||
|
search.setMimeType(this.contentFormat);
|
||||||
|
}
|
||||||
|
if (this.createdDateChecked == true)
|
||||||
|
{
|
||||||
|
SimpleDateFormat df = CachingDateFormat.getDateFormat();
|
||||||
|
String strCreatedDate = df.format(this.createdDateFrom);
|
||||||
|
String strCreatedDateTo = df.format(this.createdDateTo);
|
||||||
|
search.addRangeQuery(ContentModel.PROP_CREATED, strCreatedDate, strCreatedDateTo, true);
|
||||||
|
}
|
||||||
|
if (this.modifiedDateChecked == true)
|
||||||
|
{
|
||||||
|
SimpleDateFormat df = CachingDateFormat.getDateFormat();
|
||||||
|
String strModifiedDate = df.format(this.modifiedDateFrom);
|
||||||
|
String strModifiedDateTo = df.format(this.modifiedDateTo);
|
||||||
|
search.addRangeQuery(ContentModel.PROP_MODIFIED, strModifiedDate, strModifiedDateTo, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// walk each of the custom properties add add them as additional attributes
|
||||||
|
for (String qname : this.customProperties.keySet())
|
||||||
|
{
|
||||||
|
Object value = this.customProperties.get(qname);
|
||||||
|
DataTypeDefinition typeDef = getCustomPropertyLookup().get(qname);
|
||||||
|
if (typeDef != null)
|
||||||
|
{
|
||||||
|
QName typeName = typeDef.getName();
|
||||||
|
if (DataTypeDefinition.DATE.equals(typeName) || DataTypeDefinition.DATETIME.equals(typeName))
|
||||||
|
{
|
||||||
|
// only apply date to search if the user has checked the enable checkbox
|
||||||
|
if (value != null && Boolean.valueOf(value.toString()) == true)
|
||||||
|
{
|
||||||
|
SimpleDateFormat df = CachingDateFormat.getDateFormat();
|
||||||
|
String strDateFrom = df.format(this.customProperties.get(
|
||||||
|
UISearchCustomProperties.PREFIX_DATE_FROM + qname));
|
||||||
|
String strDateTo = df.format(this.customProperties.get(
|
||||||
|
UISearchCustomProperties.PREFIX_DATE_TO + qname));
|
||||||
|
search.addRangeQuery(QName.createQName(qname), strDateFrom, strDateTo, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (DataTypeDefinition.BOOLEAN.equals(typeName))
|
||||||
|
{
|
||||||
|
if (((Boolean)value) == true)
|
||||||
|
{
|
||||||
|
search.addFixedValueQuery(QName.createQName(qname), value.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (DataTypeDefinition.NODE_REF.equals(typeName) || DataTypeDefinition.CATEGORY.equals(typeName))
|
||||||
|
{
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
search.addFixedValueQuery(QName.createQName(qname), value.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (DataTypeDefinition.INT.equals(typeName) || DataTypeDefinition.LONG.equals(typeName) ||
|
||||||
|
DataTypeDefinition.FLOAT.equals(typeName) || DataTypeDefinition.DOUBLE.equals(typeName))
|
||||||
|
{
|
||||||
|
String strVal = value.toString();
|
||||||
|
if (strVal != null && strVal.length() != 0)
|
||||||
|
{
|
||||||
|
search.addFixedValueQuery(QName.createQName(qname), strVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// by default use toString() value - this is for text fields and unknown types
|
||||||
|
String strVal = value.toString();
|
||||||
|
if (strVal != null && strVal.length() != 0)
|
||||||
|
{
|
||||||
|
search.addAttributeQuery(QName.createQName(qname), strVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// location path search
|
||||||
|
if (this.lookin.equals(LOOKIN_OTHER) && this.location != null)
|
||||||
|
{
|
||||||
|
search.setLocation(SearchContext.getPathFromSpaceRef(this.location, this.locationChildren));
|
||||||
|
}
|
||||||
|
|
||||||
|
// category path search
|
||||||
|
if (this.categories.size() != 0)
|
||||||
|
{
|
||||||
|
String[] paths = new String[this.categories.size()];
|
||||||
|
for (int i=0; i<paths.length; i++)
|
||||||
|
{
|
||||||
|
Node category = this.categories.get(i);
|
||||||
|
boolean includeChildren = (Boolean)category.getProperties().get(INCLUDE_CHILDREN);
|
||||||
|
paths[i] = SearchContext.getPathFromSpaceRef(category.getNodeRef(), includeChildren);
|
||||||
|
}
|
||||||
|
search.setCategories(paths);
|
||||||
|
}
|
||||||
|
|
||||||
|
// content type restriction
|
||||||
|
if (this.contentType != null)
|
||||||
|
{
|
||||||
|
search.setContentType(this.contentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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";
|
return "browse";
|
||||||
}
|
}
|
||||||
|
@@ -578,9 +578,12 @@ public class BrowseBean implements IContextListener
|
|||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
startTime = System.currentTimeMillis();
|
startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
// special exit case for < 3 characters in length
|
// get the searcher object to build the query
|
||||||
if (searchContext.getText().length() < getMinimumSearchLength())
|
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),
|
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(FacesContext.getCurrentInstance(), MSG_SEARCH_MINIMUM),
|
||||||
new Object[] {getMinimumSearchLength()}));
|
new Object[] {getMinimumSearchLength()}));
|
||||||
this.containerNodes = Collections.<Node>emptyList();
|
this.containerNodes = Collections.<Node>emptyList();
|
||||||
@@ -588,9 +591,7 @@ public class BrowseBean implements IContextListener
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the searcher object and perform the search of the root node
|
// perform the search against the repo
|
||||||
String query = searchContext.buildQuery();
|
|
||||||
|
|
||||||
UserTransaction tx = null;
|
UserTransaction tx = null;
|
||||||
ResultSet results = null;
|
ResultSet results = null;
|
||||||
try
|
try
|
||||||
|
@@ -117,82 +117,91 @@ public final class SearchContext implements Serializable
|
|||||||
/**
|
/**
|
||||||
* Build the search query string based on the current search context members.
|
* 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
|
* @return prepared search query string
|
||||||
*/
|
*/
|
||||||
public String buildQuery()
|
public String buildQuery(int minimum)
|
||||||
{
|
{
|
||||||
String query;
|
String query;
|
||||||
|
boolean validQuery = false;
|
||||||
|
|
||||||
// the QName for the well known "name" attribute
|
// the QName for the well known "name" attribute
|
||||||
String nameAttr = Repository.escapeQName(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, ELEMENT_NAME));
|
String nameAttr = Repository.escapeQName(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, ELEMENT_NAME));
|
||||||
|
|
||||||
// match against content text
|
// match against content text
|
||||||
String text = this.text.trim();
|
String text = this.text.trim();
|
||||||
String fullTextQuery;
|
String fullTextQuery = null;
|
||||||
String nameAttrQuery;
|
String nameAttrQuery = null;
|
||||||
|
|
||||||
if (text.indexOf(' ') == -1)
|
if (text.length() >= minimum)
|
||||||
{
|
{
|
||||||
// simple single word text search
|
if (text.indexOf(' ') == -1)
|
||||||
if (text.charAt(0) != '*')
|
|
||||||
{
|
{
|
||||||
// escape characters and append the wildcard character
|
// simple single word text search
|
||||||
String safeText = QueryParser.escape(text);
|
if (text.charAt(0) != '*')
|
||||||
fullTextQuery = " TEXT:" + safeText + '*';
|
|
||||||
nameAttrQuery = " @" + nameAttr + ":" + safeText + '*';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// found a leading wildcard - prepend it again after escaping the other characters
|
|
||||||
String safeText = QueryParser.escape(text.substring(1));
|
|
||||||
fullTextQuery = " TEXT:*" + safeText + '*';
|
|
||||||
nameAttrQuery = " @" + nameAttr + ":*" + safeText + '*';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// multiple word search
|
|
||||||
if (text.charAt(0) == '"' && text.charAt(text.length() - 1) == '"')
|
|
||||||
{
|
|
||||||
// as quoted phrase
|
|
||||||
String quotedSafeText = '"' + QueryParser.escape(text.substring(1, text.length() - 1)) + '"';
|
|
||||||
fullTextQuery = " TEXT:" + quotedSafeText;
|
|
||||||
nameAttrQuery = " @" + nameAttr + ":" + quotedSafeText;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// as individual search terms
|
|
||||||
StringTokenizer t = new StringTokenizer(text, " ");
|
|
||||||
StringBuilder fullTextBuf = new StringBuilder(64);
|
|
||||||
StringBuilder nameAttrBuf = new StringBuilder(64);
|
|
||||||
fullTextBuf.append('(');
|
|
||||||
nameAttrBuf.append('(');
|
|
||||||
while (t.hasMoreTokens())
|
|
||||||
{
|
{
|
||||||
String term = t.nextToken();
|
// escape characters and append the wildcard character
|
||||||
if (term.charAt(0) != '*')
|
String safeText = QueryParser.escape(text);
|
||||||
{
|
fullTextQuery = " TEXT:" + safeText + '*';
|
||||||
String safeTerm = QueryParser.escape(term);
|
nameAttrQuery = " @" + nameAttr + ":" + safeText + '*';
|
||||||
fullTextBuf.append("TEXT:").append(safeTerm).append('*');
|
}
|
||||||
nameAttrBuf.append("@").append(nameAttr).append(":").append(safeTerm).append('*');
|
else
|
||||||
}
|
{
|
||||||
else
|
// found a leading wildcard - prepend it again after escaping the other characters
|
||||||
{
|
String safeText = QueryParser.escape(text.substring(1));
|
||||||
String safeTerm = QueryParser.escape(term.substring(1));
|
fullTextQuery = " TEXT:*" + safeText + '*';
|
||||||
fullTextBuf.append("TEXT:*").append(safeTerm).append('*');
|
nameAttrQuery = " @" + nameAttr + ":*" + safeText + '*';
|
||||||
nameAttrBuf.append("@").append(nameAttr).append(":*").append(safeTerm).append('*');
|
|
||||||
}
|
|
||||||
if (t.hasMoreTokens())
|
|
||||||
{
|
|
||||||
fullTextBuf.append(" OR ");
|
|
||||||
nameAttrBuf.append(" OR ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fullTextBuf.append(')');
|
|
||||||
nameAttrBuf.append(')');
|
|
||||||
fullTextQuery = fullTextBuf.toString();
|
|
||||||
nameAttrQuery = nameAttrBuf.toString();
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// multiple word search
|
||||||
|
if (text.charAt(0) == '"' && text.charAt(text.length() - 1) == '"')
|
||||||
|
{
|
||||||
|
// as quoted phrase
|
||||||
|
String quotedSafeText = '"' + QueryParser.escape(text.substring(1, text.length() - 1)) + '"';
|
||||||
|
fullTextQuery = " TEXT:" + quotedSafeText;
|
||||||
|
nameAttrQuery = " @" + nameAttr + ":" + quotedSafeText;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// as individual search terms
|
||||||
|
StringTokenizer t = new StringTokenizer(text, " ");
|
||||||
|
StringBuilder fullTextBuf = new StringBuilder(64);
|
||||||
|
StringBuilder nameAttrBuf = new StringBuilder(64);
|
||||||
|
fullTextBuf.append('(');
|
||||||
|
nameAttrBuf.append('(');
|
||||||
|
while (t.hasMoreTokens())
|
||||||
|
{
|
||||||
|
String term = t.nextToken();
|
||||||
|
if (term.charAt(0) != '*')
|
||||||
|
{
|
||||||
|
String safeTerm = QueryParser.escape(term);
|
||||||
|
fullTextBuf.append("TEXT:").append(safeTerm).append('*');
|
||||||
|
nameAttrBuf.append("@").append(nameAttr).append(":").append(safeTerm).append('*');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String safeTerm = QueryParser.escape(term.substring(1));
|
||||||
|
fullTextBuf.append("TEXT:*").append(safeTerm).append('*');
|
||||||
|
nameAttrBuf.append("@").append(nameAttr).append(":*").append(safeTerm).append('*');
|
||||||
|
}
|
||||||
|
if (t.hasMoreTokens())
|
||||||
|
{
|
||||||
|
fullTextBuf.append(" OR ");
|
||||||
|
nameAttrBuf.append(" OR ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fullTextBuf.append(')');
|
||||||
|
nameAttrBuf.append(')');
|
||||||
|
fullTextQuery = fullTextBuf.toString();
|
||||||
|
nameAttrQuery = nameAttrBuf.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
validQuery = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// match a specific PATH for space location or categories
|
// match a specific PATH for space location or categories
|
||||||
@@ -224,10 +233,19 @@ public final class SearchContext implements Serializable
|
|||||||
attributeQuery = new StringBuilder(queryAttributes.size() << 6);
|
attributeQuery = new StringBuilder(queryAttributes.size() << 6);
|
||||||
for (QName qname : queryAttributes.keySet())
|
for (QName qname : queryAttributes.keySet())
|
||||||
{
|
{
|
||||||
String escapedName = Repository.escapeQName(qname);
|
String value = queryAttributes.get(qname).trim();
|
||||||
String value = QueryParser.escape(queryAttributes.get(qname));
|
if (value.length() >= minimum)
|
||||||
attributeQuery.append(" +@").append(escapedName)
|
{
|
||||||
.append(":").append(value).append('*');
|
String escapedName = Repository.escapeQName(qname);
|
||||||
|
attributeQuery.append(" +@").append(escapedName)
|
||||||
|
.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,38 +301,64 @@ public final class SearchContext implements Serializable
|
|||||||
String fileTypeQuery;
|
String fileTypeQuery;
|
||||||
if (contentType != null)
|
if (contentType != null)
|
||||||
{
|
{
|
||||||
fileTypeQuery = " +TYPE:\"" + contentType + "\" ";
|
fileTypeQuery = " TYPE:\"" + contentType + "\" ";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// default to cm:content
|
// 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
|
// match against FOLDER type
|
||||||
String folderTypeQuery = " +TYPE:\"{" + NamespaceService.CONTENT_MODEL_1_0_URI + "}folder\" ";
|
String folderTypeQuery = " TYPE:\"{" + NamespaceService.CONTENT_MODEL_1_0_URI + "}folder\" ";
|
||||||
|
|
||||||
switch (mode)
|
if (text.length() >= minimum)
|
||||||
{
|
{
|
||||||
case SearchContext.SEARCH_ALL:
|
// text query for name and/or full text specified
|
||||||
query = '(' + fileTypeQuery + " AND " + '(' + nameAttrQuery + fullTextQuery + ')' + ')' + " OR " +
|
switch (mode)
|
||||||
'(' + folderTypeQuery + " AND " + nameAttrQuery + ')';
|
{
|
||||||
break;
|
case SearchContext.SEARCH_ALL:
|
||||||
|
query = '(' + fileTypeQuery + " AND " + '(' + nameAttrQuery + fullTextQuery + ')' + ')' + " OR " +
|
||||||
case SearchContext.SEARCH_FILE_NAMES:
|
'(' + folderTypeQuery + " AND " + nameAttrQuery + ')';
|
||||||
query = fileTypeQuery + " AND " + nameAttrQuery;
|
break;
|
||||||
break;
|
|
||||||
|
case SearchContext.SEARCH_FILE_NAMES:
|
||||||
case SearchContext.SEARCH_FILE_NAMES_CONTENTS:
|
query = fileTypeQuery + " AND " + nameAttrQuery;
|
||||||
query = fileTypeQuery + " AND " + '(' + nameAttrQuery + fullTextQuery + ')';
|
break;
|
||||||
break;
|
|
||||||
|
case SearchContext.SEARCH_FILE_NAMES_CONTENTS:
|
||||||
case SearchContext.SEARCH_SPACE_NAMES:
|
query = fileTypeQuery + " AND " + '(' + nameAttrQuery + fullTextQuery + ')';
|
||||||
query = folderTypeQuery + " AND " + nameAttrQuery;
|
break;
|
||||||
break;
|
|
||||||
|
case SearchContext.SEARCH_SPACE_NAMES:
|
||||||
default:
|
query = folderTypeQuery + " AND " + nameAttrQuery;
|
||||||
throw new IllegalStateException("Unknown search mode specified: " + mode);
|
break;
|
||||||
|
|
||||||
|
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
|
// match entire query against any additional attributes specified
|
||||||
@@ -329,6 +373,14 @@ public final class SearchContext implements Serializable
|
|||||||
query = "(" + pathQuery + ") AND (" + query + ')';
|
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())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Query: " + query);
|
logger.debug("Query: " + query);
|
||||||
|
|
||||||
@@ -589,7 +641,7 @@ public final class SearchContext implements Serializable
|
|||||||
{
|
{
|
||||||
root.addElement(ELEMENT_CONTENT_TYPE).addText(this.contentType);
|
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);
|
root.addElement(ELEMENT_MIMETYPE).addText(this.mimeType);
|
||||||
}
|
}
|
||||||
|
@@ -33,19 +33,6 @@
|
|||||||
function pageLoaded()
|
function pageLoaded()
|
||||||
{
|
{
|
||||||
document.getElementById("advsearch:search-text").focus();
|
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>
|
</script>
|
||||||
@@ -147,8 +134,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td colspan=2>
|
<td colspan=2>
|
||||||
<h:outputText value="#{msg.look_for}" style="font-weight:bold" />:
|
<h:outputText value="#{msg.look_for}" style="font-weight:bold" />:
|
||||||
<h:inputText id="search-text" value="#{AdvancedSearchBean.text}" size="48" maxlength="1024"
|
<h:inputText id="search-text" value="#{AdvancedSearchBean.text}" size="48" maxlength="1024" />
|
||||||
onkeyup="javascript:checkButtonState();" onchange="javascript:checkButtonState();" /> *
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user