/* * Copyright (c) 2006-2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * 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.wso2.carbon.registry.search.services; import org.apache.axis2.context.MessageContext; import org.apache.commons.lang.StringUtils; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.registry.admin.api.search.ISearchService; import org.wso2.carbon.registry.common.AttributeSearchService; import org.wso2.carbon.registry.common.ResourceData; import org.wso2.carbon.registry.common.services.RegistryAbstractAdmin; import org.wso2.carbon.registry.core.RegistryConstants; import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.registry.core.pagination.PaginationContext; import org.wso2.carbon.registry.core.pagination.PaginationUtils; import org.wso2.carbon.registry.core.session.UserRegistry; import org.wso2.carbon.registry.core.utils.RegistryUtils; import org.wso2.carbon.registry.indexing.IndexingConstants; import org.wso2.carbon.registry.search.beans.AdvancedSearchResultsBean; import org.wso2.carbon.registry.search.beans.CustomSearchParameterBean; import org.wso2.carbon.registry.search.beans.MediaTypeValueList; import org.wso2.carbon.registry.search.beans.SearchResultsBean; import org.wso2.carbon.registry.search.internal.SearchDataHolder; import org.wso2.carbon.registry.search.services.utils.AdvancedSearchFilterActions; import org.wso2.carbon.registry.search.services.utils.CustomSearchParameterPopulator; import org.wso2.carbon.registry.search.services.utils.SearchResultsBeanPopulator; import org.wso2.carbon.registry.search.services.utils.SearchUtils; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.Map; /** * This class is dedicated for resource search */ public class SearchService extends RegistryAbstractAdmin implements ISearchService<SearchResultsBean, AdvancedSearchResultsBean, CustomSearchParameterBean, MediaTypeValueList> { private boolean allEmpty = true; private static final String SEARCH_ATTRIBUTES_ALL_EMPTY_MESSAGE = "At least one field must be filled"; private static final String SEARCH_ATTRIBUTES_CONTAINS_ILLEGAL_CHARACTER_MESSAGE = " contains illegal characters"; /* (non-Javadoc) * @see org.wso2.carbon.registry.search.services.ISearchService#getSearchResults(java.lang.String, java.lang.String) */ public SearchResultsBean getSearchResults(String searchType, String criteria) throws RegistryException { RegistryUtils.recordStatistics(searchType, criteria); UserRegistry registry = (UserRegistry) getRootRegistry(); return SearchResultsBeanPopulator.populate(registry, searchType, criteria); } /* public AdvancedSearchResultsBean getAdvancedSearchResults(String resourceName, String authorName, String updaterName, String createdAfter, String createdBefore, String updatedAfter, String updatedBefore, String tags, String commentWords, String propertyName, String propertyValue, String content) throws RegistryException { UserRegistry registry = (UserRegistry) getRootRegistry(); Registry configSystemRegistry = getConfigSystemRegistry(); return AdvancedSearchResultsBeanPopulator.populate(configSystemRegistry, registry, resourceName, authorName, updaterName, createdAfter, createdBefore, updatedAfter, updatedBefore, tags, commentWords, propertyName, propertyValue, content); }*/ /** * Method to get Advance search result bean * * @param parameters CustomSearchParameterBean * @return AdvancedSearchResultsBean * @throws RegistryException */ public AdvancedSearchResultsBean getAdvancedSearchResults(CustomSearchParameterBean parameters) throws RegistryException { RegistryUtils.recordStatistics(parameters); AdvancedSearchResultsBean advancedSearchResultsBean; UserRegistry registry = (UserRegistry) getRootRegistry(); AttributeSearchService attributeSearchService = SearchDataHolder.getInstance().getAttributeIndexingService(); // Get advance search parameter values String[][] searchParameterValues = parameters.getParameterValues(); ResourceData[] advanceSearchResourceData = new ResourceData[0]; // Map to store advance search attributes values Map<String, String> advanceSearchAttributes; // Validating the values sent String validationErrorMessage = getValidationErrorMessage(searchParameterValues); if (validationErrorMessage != null && StringUtils.isNotEmpty(validationErrorMessage)) { return SearchUtils.getEmptyResultBeanWithErrorMsg(validationErrorMessage); } // No attribute has provide for search if (allEmpty) { return SearchUtils.getEmptyResultBeanWithErrorMsg(SEARCH_ATTRIBUTES_ALL_EMPTY_MESSAGE); } // Add search parameter values to advanceSearchAttributes Map advanceSearchAttributes = getAdvanceSearchValueMap(searchParameterValues); // Get Advance Search resource data if (attributeSearchService != null && advanceSearchAttributes.size() > 0) { if (!(advanceSearchAttributes.size() == 2 && advanceSearchAttributes.containsKey("leftOp") && advanceSearchAttributes.get("leftOp").equals("na") && advanceSearchAttributes .containsKey("rightOp") && advanceSearchAttributes.get("rightOp").equals("na"))) { advanceSearchAttributes.put(IndexingConstants.ADVANCE_SEARCH, "true"); advanceSearchResourceData = attributeSearchService.search(registry, advanceSearchAttributes); } } advancedSearchResultsBean = new AdvancedSearchResultsBean(); if (advanceSearchResourceData != null && advanceSearchResourceData.length > 0) { advanceSearchResourceData = getSortedSearchResults(advanceSearchResourceData); advancedSearchResultsBean.setResourceDataList(advanceSearchResourceData); if (!isEmptyResourceDataList(advancedSearchResultsBean)) { return getPaginatedResult(advancedSearchResultsBean); } } advancedSearchResultsBean.setResourceDataList(new ResourceData[0]); return advancedSearchResultsBean; } /** * Method to sort search results based on created date, author and rating. * * @param results search results * @return sorted search results based on sort criteria */ private ResourceData[] getSortedSearchResults(ResourceData[] results) { MessageContext messageContext = MessageContext.getCurrentMessageContext(); if (messageContext != null && PaginationUtils.isPaginationHeadersExist(messageContext)) { String createdDate = "created"; String author = "author"; String rating = "rating"; try { PaginationContext paginationContext = PaginationUtils.initPaginationContext(messageContext); String sortOrder = paginationContext.getSortOrder(); String sortBy = paginationContext.getSortBy(); if (sortBy != null && sortOrder != null) { // Sort by created date if (createdDate.equals(sortBy)) { sortReultsOnCreatedDate(results, sortOrder); } // Sort by author else if (author.equals(sortBy)) { sortResultsOnAuthor(results, sortOrder); } // Sort by average rating else if (rating.equals(sortBy)) { sortResultsOnrating(results, sortOrder); } } } finally { PaginationContext.destroy(); } return results; } else { return results; } } /** * Method to sort search results based on created date. * * @param results search results * @param sortOrder ascending or descending * @return sorted search results based on created date */ private ResourceData[] sortReultsOnCreatedDate(ResourceData[] results, final String sortOrder) { final String sortCriteria = "ASC"; Arrays.sort(results, new Comparator<ResourceData>() { @Override public int compare(ResourceData o1, ResourceData o2) { if (sortCriteria.equals(sortOrder)) { return o1.getCreatedOn().compareTo(o2.getCreatedOn()); } else { return o2.getCreatedOn().compareTo(o1.getCreatedOn()); } } }); return results; } /** * Method to sort search results based on author. * * @param results search results * @param sortOrder ascending or descending * @return sorted search results based on author */ private ResourceData[] sortResultsOnAuthor(ResourceData[] results, final String sortOrder) { final String sortCriteria = "ASC"; Arrays.sort(results, new Comparator<ResourceData>() { @Override public int compare(ResourceData o1, ResourceData o2) { if (sortCriteria.equals(sortOrder)) { return o1.getAuthorUserName().compareTo(o2.getAuthorUserName()); } else { return o2.getAuthorUserName().compareTo(o1.getAuthorUserName()); } } }); return results; } /** * Method to sort search results based on average rating. * * @param results search results * @param sortOrder ascending or descending * @return sorted search results based on average rating */ private ResourceData[] sortResultsOnrating(ResourceData[] results, final String sortOrder) { final String sortCriteria = "ASC"; Arrays.sort(results, new Comparator<ResourceData>() { @Override public int compare(ResourceData o1, ResourceData o2) { Float rating1 = Float.valueOf(o1.getAverageRating()); Float rating2 = Float.valueOf(o2.getAverageRating()); if (sortCriteria.equals(sortOrder)) { return rating1.compareTo(rating2); } else { return rating2.compareTo(rating1); } } }); return results; } /** * Method to check whether the result set is empty * * @param resultsBean AdvancedSearchResultsBean * @return boolean value of result empty or not */ private boolean isEmptyResourceDataList(AdvancedSearchResultsBean resultsBean) { boolean resultEmpty = true; if ((resultsBean.getResourceDataList() != null && resultsBean.getResourceDataList().length > 0)) { for (ResourceData data : resultsBean.getResourceDataList()) { if (data != null) { resultEmpty = false; break; } } } return resultEmpty; } /** * Method to get the advance search attribute validation error message * * @param searchParameterValues search parameter values * @return validation error message */ private String getValidationErrorMessage(String[][] searchParameterValues) { String message = null; for (String[] tempParameterValue : searchParameterValues) { if (tempParameterValue[1] != null & tempParameterValue[1].trim().length() > 0) { allEmpty = false; // Validating all the dates if (tempParameterValue[0].equals("createdAfter") || tempParameterValue[0].equals("createdBefore") || tempParameterValue[0].equals("updatedAfter") || tempParameterValue[0].equals("updatedBefore")) { if (!SearchUtils.validateDateInput(tempParameterValue[1])) { message = tempParameterValue[0] + SEARCH_ATTRIBUTES_CONTAINS_ILLEGAL_CHARACTER_MESSAGE; } } else if (tempParameterValue[0].equals("author")) { // Validating media type if (SearchUtils.validatePathInput(tempParameterValue[1])) { message = tempParameterValue[0] + SEARCH_ATTRIBUTES_CONTAINS_ILLEGAL_CHARACTER_MESSAGE; } } else if (tempParameterValue[0].equals("mediaType")) { // Validating media type if (SearchUtils.validateMediaTypeInput(tempParameterValue[1])) { message = tempParameterValue[0] + SEARCH_ATTRIBUTES_CONTAINS_ILLEGAL_CHARACTER_MESSAGE; } } else if (tempParameterValue[0].equals("content")) { // Validating content if (SearchUtils.validateContentInput(tempParameterValue[1])) { message = tempParameterValue[0] + SEARCH_ATTRIBUTES_CONTAINS_ILLEGAL_CHARACTER_MESSAGE; } } else if (tempParameterValue[0].equals("tags")) { // Validating tags boolean containsTag = false; for (String str : tempParameterValue[1].split(",")) { if (str.trim().length() > 0) { containsTag = true; break; } } if (!containsTag) { message = tempParameterValue[0] + SEARCH_ATTRIBUTES_CONTAINS_ILLEGAL_CHARACTER_MESSAGE; } if (SearchUtils.validateTagsInput(tempParameterValue[1])) { message = tempParameterValue[0] + SEARCH_ATTRIBUTES_CONTAINS_ILLEGAL_CHARACTER_MESSAGE; } } else { if (SearchUtils.validatePathInput(tempParameterValue[1])) { message = tempParameterValue[0] + SEARCH_ATTRIBUTES_CONTAINS_ILLEGAL_CHARACTER_MESSAGE; } } } } return message; } /** * Method to get the advance search attribute Map * * @param searchParameterValues search parameter array * @return attribute map */ private Map<String, String> getAdvanceSearchValueMap(String[][] searchParameterValues) { // Map to store advance search attributes values Map<String, String> advanceSearchAttributes = new HashMap<String, String>(); for (String[] tempParameterValue : searchParameterValues) { if (tempParameterValue[0].equals("content") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { advanceSearchAttributes.put(IndexingConstants.FIELD_CONTENT, tempParameterValue[1]); } else if (tempParameterValue[0].equals("mediaType") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { advanceSearchAttributes.put(IndexingConstants.FIELD_MEDIA_TYPE, tempParameterValue[1]); } else if (tempParameterValue[0].equals("resourcePath") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { if (!(tempParameterValue[1].length() == 1 && tempParameterValue[1].charAt(0) == '%')) { advanceSearchAttributes.put(IndexingConstants.FIELD_RESOURCE_NAME, tempParameterValue[1]); } } else if (tempParameterValue[0].equals("author") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { if (!(tempParameterValue[1].length() == 1 && tempParameterValue[1].charAt(0) == '%')) { advanceSearchAttributes.put(IndexingConstants.FIELD_CREATED_BY, tempParameterValue[1]); } } else if (tempParameterValue[0].equals("updater") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { if (!(tempParameterValue[1].length() == 1 && tempParameterValue[1].charAt(0) == '%')) { advanceSearchAttributes.put(IndexingConstants.FIELD_LAST_UPDATED_BY, tempParameterValue[1]); } } else if (tempParameterValue[0].equals("createdAfter") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { advanceSearchAttributes.put(IndexingConstants.FIELD_CREATED_AFTER, tempParameterValue[1]); } else if (tempParameterValue[0].equals("createdBefore") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { advanceSearchAttributes.put(IndexingConstants.FIELD_CREATED_BEFORE, tempParameterValue[1]); } else if (tempParameterValue[0].equals("updatedAfter") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { advanceSearchAttributes.put(IndexingConstants.FIELD_UPDATED_AFTER, tempParameterValue[1]); } else if (tempParameterValue[0].equals("updatedBefore") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { advanceSearchAttributes.put(IndexingConstants.FIELD_UPDATED_BEFORE, tempParameterValue[1]); } else if (tempParameterValue[0].equals("tags") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { advanceSearchAttributes.put(IndexingConstants.FIELD_TAGS, tempParameterValue[1]); } else if (tempParameterValue[0].equals("commentWords") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { advanceSearchAttributes.put(IndexingConstants.FIELD_COMMENTS, tempParameterValue[1]); } else if (tempParameterValue[0].equals("associationType") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { advanceSearchAttributes.put(IndexingConstants.FIELD_ASSOCIATION_TYPES, tempParameterValue[1]); } else if (tempParameterValue[0].equals("associationDest") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { advanceSearchAttributes.put(IndexingConstants.FIELD_ASSOCIATION_DESTINATIONS, tempParameterValue[1]); } else if (tempParameterValue[0].equals("authorNameNegate") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { advanceSearchAttributes.put(IndexingConstants.FIELD_CREATED_BY_NEGATE, tempParameterValue[1]); } else if (tempParameterValue[0].equals("updaterNameNegate") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { advanceSearchAttributes.put(IndexingConstants.FIELD_UPDATE_BY_NEGATE, tempParameterValue[1]); } else if (tempParameterValue[0].equals("createdRangeNegate") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { advanceSearchAttributes.put(IndexingConstants.FIELD_CREATED_RANGE_NEGATE, tempParameterValue[1]); } else if (tempParameterValue[0].equals("updatedRangeNegate") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { advanceSearchAttributes.put(IndexingConstants.FIELD_UPDATED_RANGE_NEGATE, tempParameterValue[1]); } else if (tempParameterValue[0].equals("mediaTypeNegate") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { advanceSearchAttributes.put(IndexingConstants.FIELD_MEDIA_TYPE_NEGATE, tempParameterValue[1]); } else if (tempParameterValue[0].equals("propertyName") && tempParameterValue[1] != null && !StringUtils .isEmpty(tempParameterValue[1])) { advanceSearchAttributes.put(IndexingConstants.FIELD_PROPERTY_NAME, tempParameterValue[1]); } else if (tempParameterValue[0].equals("leftPropertyValue") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { if (!(tempParameterValue[1].length() == 1 && tempParameterValue[1].charAt(0) == '%')) { advanceSearchAttributes.put(IndexingConstants.FIELD_LEFT_PROPERTY_VAL, tempParameterValue[1]); } } else if (tempParameterValue[0].equals("rightPropertyValue") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { if (!(tempParameterValue[1].length() == 1 && tempParameterValue[1].charAt(0) == '%')) { advanceSearchAttributes.put(IndexingConstants.FIELD_RIGHT_PROPERTY_VAL, tempParameterValue[1]); } } else if (tempParameterValue[0].equals("leftOp") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { advanceSearchAttributes.put(IndexingConstants.FIELD_LEFT_OP, tempParameterValue[1]); } else if (tempParameterValue[0].equals("rightOp") && tempParameterValue[1] != null && !StringUtils.isEmpty(tempParameterValue[1])) { advanceSearchAttributes.put(IndexingConstants.FIELD_RIGHT_OP, tempParameterValue[1]); } } return advanceSearchAttributes; } /** * Method to get the paginated result for advance search * * @param advancedSearchResultsBean AdvancedSearchResultsBean * @return paginated result */ private AdvancedSearchResultsBean getPaginatedResult(AdvancedSearchResultsBean advancedSearchResultsBean) { ResourceData[] paginatedResult; MessageContext messageContext = MessageContext.getCurrentMessageContext(); if (messageContext != null && PaginationUtils.isPaginationHeadersExist(messageContext) && advancedSearchResultsBean.getResourceDataList() != null) { int rowCount = advancedSearchResultsBean.getResourceDataList().length; try { PaginationUtils.setRowCount(messageContext, Integer.toString(rowCount)); PaginationContext paginationContext = PaginationUtils.initPaginationContext(messageContext); int start = paginationContext.getStart(); int count = paginationContext.getCount(); int startIndex; if (start == 1) { startIndex = 0; } else { startIndex = start; } if (rowCount < start + count) { paginatedResult = new ResourceData[rowCount - startIndex]; System.arraycopy(advancedSearchResultsBean.getResourceDataList(), startIndex, paginatedResult, 0, (rowCount - startIndex)); } else { paginatedResult = new ResourceData[count]; System.arraycopy(advancedSearchResultsBean.getResourceDataList(), startIndex, paginatedResult, 0, count); } advancedSearchResultsBean.setResourceDataList(paginatedResult); return advancedSearchResultsBean; } finally { PaginationContext.destroy(); } } else { return advancedSearchResultsBean; } } /* (non-Javadoc) * @see org.wso2.carbon.registry.search.services.ISearchService#getMediaTypeSearch(java.lang.String) */ public MediaTypeValueList getMediaTypeSearch(String mediaType) throws RegistryException { UserRegistry registry = (UserRegistry) getRootRegistry(); return CustomSearchParameterPopulator.getMediaTypeParameterValues(registry, mediaType); } /* (non-Javadoc) * @see org.wso2.carbon.registry.search.services.ISearchService#saveAdvancedSearchFilter(org.wso2.carbon.registry.search.beans.CustomSearchParameterBean, java.lang.String) */ public void saveAdvancedSearchFilter(CustomSearchParameterBean queryBean, String filterName) throws RegistryException { UserRegistry configUserRegistry = (UserRegistry) getConfigUserRegistry(); AdvancedSearchFilterActions.saveAdvancedSearchQueryBean(configUserRegistry, queryBean, filterName); } /* (non-Javadoc) * @see org.wso2.carbon.registry.search.services.ISearchService#getAdvancedSearchFilter(java.lang.String) */ public CustomSearchParameterBean getAdvancedSearchFilter(String filterName) throws RegistryException { UserRegistry configUserRegistry = (UserRegistry) getConfigUserRegistry(); return AdvancedSearchFilterActions.getAdvancedSearchQueryBean(configUserRegistry, filterName); } /* (non-Javadoc) * @see org.wso2.carbon.registry.search.services.ISearchService#getSavedFilters() */ public String[] getSavedFilters() throws RegistryException { UserRegistry configUserRegistry = (UserRegistry) getConfigUserRegistry(); return AdvancedSearchFilterActions.getSavedFilterNames(configUserRegistry); } public void deleteFilter(String filterName) throws RegistryException { UserRegistry configUserRegistry = (UserRegistry) getConfigUserRegistry(); configUserRegistry .delete(RegistryConstants.PATH_SEPARATOR + "users" + RegistryConstants.PATH_SEPARATOR + CarbonContext .getThreadLocalCarbonContext().getUsername() + RegistryConstants.PATH_SEPARATOR + "searchFilters" + RegistryConstants.PATH_SEPARATOR + filterName); } }