Powered By Blogger

Tuesday, December 7, 2010

Builoding advanced Search Query . Refer SearchContenxt class

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();

StringBuilder fullTextBuf = new StringBuilder(64);
StringBuilder nameAttrBuf = new StringBuilder(128);
StringBuilder additionalAttrsBuf = new StringBuilder(128);

if (text.length() != 0 && text.length() >= minimum)
{
if (text.indexOf(' ') == -1 && text.charAt(0) != '"')
{
// check for existance of a special operator
boolean operatorAND = (text.charAt(0) == OP_AND);
boolean operatorNOT = (text.charAt(0) == OP_NOT);
// strip operator from term if one was found
if (operatorAND || operatorNOT)
{
text = text.substring(1);
}

if (text.length() != 0)
{
// prepend NOT operator if supplied
if (operatorNOT)
{
fullTextBuf.append(OP_NOT);
nameAttrBuf.append(OP_NOT);
}

processSearchTextAttribute(nameAttr, text, nameAttrBuf, fullTextBuf);
for (QName qname : this.simpleSearchAdditionalAttrs)
{
processSearchAttribute(qname, text, additionalAttrsBuf, false, operatorNOT);
}
}
}
else
{
// multiple word search
if (text.charAt(0) == '"' && text.charAt(text.length() - 1) == '"')
{
// as a single quoted phrase
String quotedSafeText = '"' + text.substring(1, text.length() - 1) + '"';
fullTextBuf.append("TEXT:").append(quotedSafeText);
nameAttrBuf.append("@").append(nameAttr).append(":").append(quotedSafeText);
for (QName qname : this.simpleSearchAdditionalAttrs)
{
additionalAttrsBuf.append(" @").append(
Repository.escapeQName(qname)).append(":").append(quotedSafeText);
}
}
else
{
// as individual search terms
StringTokenizer t = new StringTokenizer(text, " ");

fullTextBuf.append('(');
nameAttrBuf.append('(');
additionalAttrsBuf.append('(');

int termCount = 0;
int tokenCount = t.countTokens();
for (int i=0; i {
String term = t.nextToken();

// check for existance of a special operator
boolean operatorAND = (term.charAt(0) == OP_AND);
boolean operatorNOT = (term.charAt(0) == OP_NOT);
// strip operator from term if one was found
if (operatorAND || operatorNOT)
{
term = term.substring(1);
}

// special case for AND all terms if set (apply after operator character removed)
// note that we can't force AND if NOT operator has been set
if (operatorNOT == false)
{
operatorAND = operatorAND | this.forceAndTerms;
}

if (term.length() != 0)
{
// prepend NOT operator if supplied
if (operatorNOT)
{
fullTextBuf.append(OP_NOT);
nameAttrBuf.append(OP_NOT);
}

// prepend AND operator if supplied
if (operatorAND)
{
fullTextBuf.append(OP_AND);
nameAttrBuf.append(OP_AND);
}

processSearchTextAttribute(nameAttr, term, nameAttrBuf, fullTextBuf);
for (QName qname : this.simpleSearchAdditionalAttrs)
{
processSearchAttribute(qname, term, additionalAttrsBuf, operatorAND, operatorNOT);
}

fullTextBuf.append(' ');
nameAttrBuf.append(' ');
additionalAttrsBuf.append(' ');

termCount++;
}
}
fullTextBuf.append(')');
nameAttrBuf.append(')');
additionalAttrsBuf.append(')');
}
}

validQuery = true;
}

// match a specific PATH for space location or categories
StringBuilder pathQuery = null;
if (location != null || (categories != null && categories.length !=0))
{
pathQuery = new StringBuilder(128);
if (location != null)
{
pathQuery.append(" PATH:\"").append(location).append("\" ");
if (categories != null && categories.length != 0)
{
pathQuery.append("AND (");
}
}
if (categories != null && categories.length != 0)
{
for (int i=0; i {
pathQuery.append(" PATH:\"").append(categories[i]).append("\" ");
}
if (location != null)
{
pathQuery.append(") ");
}
}
}

// match any extra query attribute values specified
StringBuilder attributeQuery = null;
if (queryAttributes.size() != 0)
{
attributeQuery = new StringBuilder(queryAttributes.size() << 6);
for (QName qname : queryAttributes.keySet())
{
String value = queryAttributes.get(qname).trim();
if (value.length() >= minimum)
{
processSearchAttribute(qname, value, attributeQuery);
}
}

// handle the case where we did not add any attributes due to minimum length restrictions
if (attributeQuery.length() == 0)
{
attributeQuery = null;
}
}

// match any extra fixed value attributes specified
if (queryFixedValues.size() != 0)
{
if (attributeQuery == null)
{
attributeQuery = new StringBuilder(queryFixedValues.size() << 6);
}
for (QName qname : queryFixedValues.keySet())
{
String escapedName = Repository.escapeQName(qname);
String value = queryFixedValues.get(qname);
attributeQuery.append(" +@").append(escapedName)
.append(":\"").append(value).append('"');
}
}

// range attributes are a special case also
if (rangeAttributes.size() != 0)
{
if (attributeQuery == null)
{
attributeQuery = new StringBuilder(rangeAttributes.size() << 6);
}
for (QName qname : rangeAttributes.keySet())
{
String escapedName = Repository.escapeQName(qname);
RangeProperties rp = rangeAttributes.get(qname);
String value1 = LuceneQueryParser.escape(rp.lower);
String value2 = LuceneQueryParser.escape(rp.upper);
attributeQuery.append(" +@").append(escapedName)
.append(":").append(rp.inclusive ? "[" : "{").append(value1)
.append(" TO ").append(value2).append(rp.inclusive ? "]" : "}");
}
}

// mimetype is a special case - it is indexed as a special attribute it comes from the combined
// ContentData attribute of cm:content - ContentData string cannot be searched directly
if (mimeType != null && mimeType.length() != 0)
{
if (attributeQuery == null)
{
attributeQuery = new StringBuilder(64);
}
String escapedName = Repository.escapeQName(QName.createQName(ContentModel.PROP_CONTENT + ".mimetype"));
attributeQuery.append(" +@").append(escapedName)
.append(":").append(mimeType);
}

// match against appropriate content type
String fileTypeQuery;
if (contentType != null)
{
fileTypeQuery = " TYPE:\"" + contentType + "\" ";
}
else
{
// default to cm:content
fileTypeQuery = " TYPE:\"{" + NamespaceService.CONTENT_MODEL_1_0_URI + "}content\" ";
}

// match against appropriate folder type
String folderTypeQuery;
if (folderType != null)
{
folderTypeQuery = " TYPE:\"" + folderType + "\" ";
}
else
{
folderTypeQuery = " TYPE:\"{" + NamespaceService.CONTENT_MODEL_1_0_URI + "}folder\" ";
}

String fullTextQuery = fullTextBuf.toString();
String nameAttrQuery = nameAttrBuf.toString();
String additionalAttrsQuery =
(this.simpleSearchAdditionalAttrs.size() != 0) ? additionalAttrsBuf.toString() : "";

if (text.length() != 0 && text.length() >= minimum)
{
// text query for name and/or full text specified
switch (mode)
{
case SearchContext.SEARCH_ALL:
query = '(' + fileTypeQuery + " AND " + '(' + nameAttrQuery + ' ' + additionalAttrsQuery + ' ' + fullTextQuery + ')' + ')' +
' ' +
'(' + folderTypeQuery + " AND " + '(' + nameAttrQuery + ' ' + additionalAttrsQuery + "))";
break;

case SearchContext.SEARCH_FILE_NAMES:
query = fileTypeQuery + " AND " + nameAttrQuery;
break;

case SearchContext.SEARCH_FILE_NAMES_CONTENTS:
query = fileTypeQuery + " AND " + '(' + nameAttrQuery + ' ' + fullTextQuery + ')';
break;

case SearchContext.SEARCH_SPACE_NAMES:
query = folderTypeQuery + " AND " + nameAttrQuery;
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 + ' ' + 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)
{
query = attributeQuery + " AND (" + query + ')';
}

// match entire query against any specified paths
if (pathQuery != null)
{
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:\r\n" + query);

return query;
}

No comments:

Post a Comment