/* * Copyright (c) 2009-2010 Lockheed Martin Corporation * * Licensed 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. */ package org.eurekastreams.server.service.actions.strategies.directory; import org.eurekastreams.commons.search.LuceneFieldBooster; /** * Strategy to build a Lucene query string for searching the directory. */ public class DirectorySearchLuceneQueryBuilder { /** * Search format mask. */ private String searchFormatMask; /** * Field booster. */ private LuceneFieldBooster fieldBooster; /** * Field boost factor. */ private int fieldBoostFactor; /** * Org id getter - don't use the interface - the query terms added only make sense for ID, not shortName. */ private OrganizationIdGetter orgIdGetter; /** * Constructor. * * @param inSearchFormatMask * the search format mask. * @param inFieldBooster * the field booster. * @param inFieldBoostFactor * the boost factor (recommend 50). * @param inOrgIdGetter * the strategy to use to get the organization identifier - either the id or the shortName */ public DirectorySearchLuceneQueryBuilder(final String inSearchFormatMask, final LuceneFieldBooster inFieldBooster, final int inFieldBoostFactor, final OrganizationIdGetter inOrgIdGetter) { searchFormatMask = inSearchFormatMask; fieldBooster = inFieldBooster; fieldBoostFactor = inFieldBoostFactor; orgIdGetter = inOrgIdGetter; } /** * Modify the input search string mask, boosting a field if requested, scoping the search to a parent organization * id if requested, and passing in a userId clause that will add the ability to fetch private groups that the * current user is a follower or coordinator for. * * @param searchText * the search term the user entered, already escaped to prevent query-injection * @param weightedField * the field to boost * @param orgShortName * the organization short name to scope the query to (optional, can be empty) * @param userId * the current user's Person Id - extends ExtendedUserDetails if logged in * @return a native lucene query */ public String buildNativeQuery(final String searchText, final String weightedField, final String orgShortName, final long userId) { String queryMask = searchFormatMask; // weight a field if asked by the client if (weightedField.length() > 0) { queryMask = fieldBooster.boostField(queryMask, weightedField, fieldBoostFactor); } // only search under a certain org if requested - get the identifier the query is expecting if (orgShortName.length() > 0) { String orgIdentifier = orgIdGetter.getIdentifier(orgShortName); if (queryMask.length() == 0) { queryMask = String.format("+parentOrganizationIdHierarchy:(%s)", orgIdentifier); } else { queryMask = String.format("+(%s) +parentOrganizationIdHierarchy:(%s)", queryMask, orgIdentifier); } } // the query mask expects two terms - the search term, then an additional permission clause - optional, only // passed in if user is logged in return String.format(queryMask, searchText); } }