Java tutorial
/* * Copyright (C) 2005 - 2014 TIBCO Software Inc. All rights reserved. * http://www.jaspersoft.com. * * Unless you have purchased a commercial license agreement from Jaspersoft, * the following license terms apply: * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.jaspersoft.jasperserver.search.service.impl; import com.jaspersoft.jasperserver.api.JSException; import com.jaspersoft.jasperserver.api.common.domain.ExecutionContext; import com.jaspersoft.jasperserver.api.common.domain.impl.ExecutionContextImpl; import com.jaspersoft.jasperserver.api.logging.diagnostic.domain.DiagnosticAttribute; import com.jaspersoft.jasperserver.api.logging.diagnostic.helper.DiagnosticAttributeBuilder; import com.jaspersoft.jasperserver.api.logging.diagnostic.service.Diagnostic; import com.jaspersoft.jasperserver.api.logging.diagnostic.service.DiagnosticCallback; import com.jaspersoft.jasperserver.api.metadata.common.domain.Resource; import com.jaspersoft.jasperserver.api.metadata.common.domain.ResourceLookup; import com.jaspersoft.jasperserver.api.metadata.common.service.RepositoryService; import com.jaspersoft.jasperserver.api.search.SearchCriteriaFactory; import com.jaspersoft.jasperserver.api.search.SearchFilter; import com.jaspersoft.jasperserver.api.search.SearchSorter; import com.jaspersoft.jasperserver.api.search.TransformerFactory; import com.jaspersoft.jasperserver.search.common.CustomFilter; import com.jaspersoft.jasperserver.search.common.CustomSorter; import com.jaspersoft.jasperserver.search.common.RepositorySearchConfiguration; import com.jaspersoft.jasperserver.search.common.ResourceDetails; import com.jaspersoft.jasperserver.search.filter.AccessTypeFilter; import com.jaspersoft.jasperserver.search.filter.TextFilter; import com.jaspersoft.jasperserver.search.mode.AccessType; import com.jaspersoft.jasperserver.search.mode.SearchMode; import com.jaspersoft.jasperserver.search.mode.SearchModeSettingsResolver; import com.jaspersoft.jasperserver.search.service.*; import com.jaspersoft.jasperserver.search.sorter.ByLabelSorter; import net.sf.ehcache.CacheManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import java.util.*; /** * Implementation of {@link RepositorySearchService}. * * @author Yuriy Plakosh * @version $Id: RepositorySearchServiceImpl.java 47331 2014-07-18 09:13:06Z kklein $ */ @Transactional(propagation = Propagation.SUPPORTS, readOnly = true) public class RepositorySearchServiceImpl implements RepositorySearchService, Diagnostic { private static final Log log = LogFactory.getLog(RepositorySearchServiceImpl.class); protected RepositoryService repositoryService; private ResourceService resourceService; protected TransformerFactory transformerFactory; private Map<String, ChildrenLoaderService> childrenLoaders; protected SearchCriteriaFactory defaultSearchCriteriaFactory; private SearchModeSettingsResolver searchModeSettingsResolver; protected Map<String, List<String>> filterOptionToResourceTypes; protected ByLabelSorter sorter; @javax.annotation.Resource private TextFilter textFilter; @javax.annotation.Resource private AccessTypeFilter accessTypeFilter; public ByLabelSorter getSorter() { return sorter; } public void setSorter(ByLabelSorter sorter) { this.sorter = sorter; } public void setSearchModeSettingsResolver(SearchModeSettingsResolver searchModeSettingsResolver) { this.searchModeSettingsResolver = searchModeSettingsResolver; } public void setDefaultSearchCriteriaFactory(SearchCriteriaFactory defaultSearchCriteriaFactory) { this.defaultSearchCriteriaFactory = defaultSearchCriteriaFactory; } public void setRepositoryService(RepositoryService repositoryService) { this.repositoryService = repositoryService; } public void setResourceService(ResourceService resourceService) { this.resourceService = resourceService; } public void setTransformerFactory(TransformerFactory transformerFactory) { this.transformerFactory = transformerFactory; } public void setFilterOptionToResourceTypes(Map<String, List<String>> filterOptionToResourceTypes) { this.filterOptionToResourceTypes = filterOptionToResourceTypes; } @Transactional(propagation = Propagation.REQUIRED) public List<ResourceDetails> getResults(ExecutionContext context, SearchCriteriaFactory searchCriteriaFactory, List<SearchFilter> filters, SearchSorter sorter, int current, int max) { List<ResourceLookup> resources = getLookups(context, searchCriteriaFactory, filters, sorter, current, max); return getResourceDetailsList(resources); } @Override @Transactional(propagation = Propagation.REQUIRED) public List<ResourceDetails> getResults(ExecutionContext context, RepositorySearchCriteria criteria) { List<ResourceLookup> resources = getLookups(context, criteria); return getResourceDetailsList(resources); } @Override @Transactional(propagation = Propagation.REQUIRED) public List<ResourceLookup> getLookups(ExecutionContext context, SearchCriteriaFactory searchCriteriaFactory, List<SearchFilter> filters, SearchSorter sorter, int current, int max) { return repositoryService.getResources(context, searchCriteriaFactory, filters, sorter, transformerFactory, current, max); } @Override @Transactional(propagation = Propagation.REQUIRED) public List<ResourceLookup> getLookups(ExecutionContext context, RepositorySearchCriteria criteria) { context = putCriteriaToContext(context, criteria); // SearchMode.SEARCH is used by default final RepositorySearchConfiguration configuration = getConfiguration( criteria.getSearchMode() != null ? criteria.getSearchMode() : SearchMode.SEARCH); return getLookups(context, obtainFactory(criteria), createAllFiltersList(configuration, criteria), getSorter(configuration, criteria.getSortBy()), criteria.getStartIndex(), criteria.getMaxCount()); } @Override @Transactional(propagation = Propagation.REQUIRED) public RepositorySearchResult<ResourceLookup> getLookupsForFullPage(ExecutionContext context, RepositorySearchCriteria clientCriteria) { RepositorySearchAccumulator<ResourceLookup> result = null; RepositorySearchCriteria criteria; try { criteria = clientCriteria.clone(); } catch (CloneNotSupportedException e) { throw new JSException(e.getMessage()); } if (criteria != null) { context = putCriteriaToContext(context, criteria); final SearchCriteriaFactory criteriaFactory = obtainFactory(criteria); final RepositorySearchConfiguration conf = getConfiguration( criteria.getSearchMode() != null ? criteria.getSearchMode() : SearchMode.SEARCH); final List<SearchFilter> filters = createAllFiltersList(conf, criteria); final SearchSorter sorter = getSorter(conf, criteria.getSortBy()); int startIndex = criteria.getStartIndex(); int itemsPerPage = criteria.getMaxCount(); int currentLimit = itemsPerPage; int totalCount = getResultsCount(null, criteria); if (startIndex > totalCount) { return RepositorySearchAccumulator.EMPTY_RESULT; } result = new RepositorySearchAccumulator<ResourceLookup>(startIndex, itemsPerPage, totalCount); do { criteria.setStartIndex(startIndex); criteria.setMaxCount(currentLimit); List<ResourceLookup> currentLookups = repositoryService.getResources(context, criteriaFactory, filters, sorter, transformerFactory, criteria.getStartIndex(), criteria.getMaxCount()); debug(criteria, currentLookups, result); if (itemsPerPage == 0) { result.fill(criteria, currentLookups); break; } else if ((currentLookups.size() + result.size()) > itemsPerPage) { currentLimit = itemsPerPage - result.size(); } else { result.fill(criteria, currentLookups); startIndex = result.getNextOffset(); int nexLimit = currentLimit + (currentLimit - currentLookups.size()); currentLimit = (conf.getMaxItemsPerQuery() > 0 && conf.getMaxItemsPerQuery() < nexLimit) ? conf.getMaxItemsPerQuery() : nexLimit; } } while (criteria.isForceFullPage() && startIndex < result.getTotalCount() && !result.isFull()); } return result == null ? RepositorySearchAccumulator.EMPTY_RESULT : result; } private void debug(RepositorySearchCriteria criteria, List<ResourceLookup> lookups, RepositorySearchAccumulator<ResourceLookup> result) { if (log.isDebugEnabled()) { log.debug("Searching -> \n" + "startIndex: " + criteria.getStartIndex() + ", limit: " + criteria.getMaxCount() + " <> found: " + lookups.size() + ", total: " + result.getTotalCount()); } } public int getResultsCount(ExecutionContext context, RepositorySearchCriteria criteria) { context = putCriteriaToContext(context, criteria); // SearchMode.SEARCH is used by default final RepositorySearchConfiguration configuration = getConfiguration( criteria.getSearchMode() != null ? criteria.getSearchMode() : SearchMode.SEARCH); return getResultsCount(context, obtainFactory(criteria), createAllFiltersList(configuration, criteria), getSorter(configuration, criteria.getSortBy())); } @Override public Map<DiagnosticAttribute, DiagnosticCallback> getDiagnosticData() { final RepositorySearchCriteria repositorySearchCriteria = new RepositorySearchCriteriaImpl.Builder() .setFolderUri("/").setSearchText(null).setStartIndex(0).setMaxCount(0) .setSearchMode(SearchMode.SEARCH).setSortBy("name").getCriteria(); final RepositorySearchConfiguration configuration = getConfiguration( repositorySearchCriteria.getSearchMode()); final SearchCriteriaFactory factory = defaultSearchCriteriaFactory .newFactory(Resource.class.getCanonicalName()); final SearchSorter searchSorter = this.getSorter(); return new DiagnosticAttributeBuilder() .addDiagnosticAttribute(DiagnosticAttributeBuilder.TOTAL_REPORTS_COUNT, new DiagnosticCallback<Integer>() { @Override public Integer getDiagnosticAttributeValue() { final List<SearchFilter> allFiltersList = new ArrayList<SearchFilter>( createAllFiltersList(configuration, repositorySearchCriteria)); repositorySearchCriteria.setResourceTypes( filterOptionToResourceTypes.get("resourceTypeFilter-reports")); return repositoryService.getResourcesCount( putCriteriaToContext(null, repositorySearchCriteria), factory, allFiltersList, searchSorter, transformerFactory); } }) .addDiagnosticAttribute(DiagnosticAttributeBuilder.TOTAL_REPORT_OUTPUTS_COUNT, new DiagnosticCallback<Integer>() { @Override public Integer getDiagnosticAttributeValue() { final List<SearchFilter> allFiltersList = new ArrayList<SearchFilter>( createAllFiltersList(configuration, repositorySearchCriteria)); repositorySearchCriteria.setResourceTypes( filterOptionToResourceTypes.get("resourceTypeFilter-reportOutput")); return repositoryService.getResourcesCount( putCriteriaToContext(null, repositorySearchCriteria), factory, allFiltersList, searchSorter, transformerFactory); } }) .addDiagnosticAttribute(DiagnosticAttributeBuilder.TOTAL_FOLDERS_COUNT, new DiagnosticCallback<Integer>() { @Override public Integer getDiagnosticAttributeValue() { return repositoryService.getFoldersCount(null); } }) .addDiagnosticAttribute(DiagnosticAttributeBuilder.TOTAL_OLAP_VIEWS_COUNT, new DiagnosticCallback<Integer>() { @Override public Integer getDiagnosticAttributeValue() { final List<SearchFilter> allFiltersList = new ArrayList<SearchFilter>( createAllFiltersList(configuration, repositorySearchCriteria)); repositorySearchCriteria.setResourceTypes( filterOptionToResourceTypes.get("resourceTypeFilter-view")); return repositoryService.getResourcesCount( putCriteriaToContext(null, repositorySearchCriteria), factory, allFiltersList, searchSorter, transformerFactory); } }) .addDiagnosticAttribute(DiagnosticAttributeBuilder.TOTAL_DATA_SOURCES_COUNT, new DiagnosticCallback<Integer>() { @Override public Integer getDiagnosticAttributeValue() { final List<SearchFilter> allFiltersList = new ArrayList<SearchFilter>( createAllFiltersList(configuration, repositorySearchCriteria)); repositorySearchCriteria.setResourceTypes( filterOptionToResourceTypes.get("resourceTypeFilter-dataSources")); return repositoryService.getResourcesCount( putCriteriaToContext(null, repositorySearchCriteria), factory, allFiltersList, searchSorter, transformerFactory); } }) .build(); } /** * @param context - execution context * @param criteria - search criteria * @deprecated criteria shouldn't be in context, temporary solution */ protected ExecutionContext putCriteriaToContext(ExecutionContext context, RepositorySearchCriteria criteria) { ExecutionContext nullSafeContext = context != null ? context : ExecutionContextImpl.getRuntimeExecutionContext(); if (nullSafeContext.getAttributes() == null) nullSafeContext.setAttributes(new ArrayList()); nullSafeContext.getAttributes().add(criteria); return nullSafeContext; } public SearchSorter getSorter(RepositorySearchConfiguration configuration, String sortBy) { SearchSorter result = null; SearchSorter defaultSorter = null; for (CustomSorter sorter : configuration.getCustomSorters()) { if (sorter.getId().equals(sortBy)) { result = sorter.getSearchSorter(); break; } else if (sorter.isDefault()) { defaultSorter = sorter.getSearchSorter(); } } return result != null ? result : defaultSorter; } protected RepositorySearchConfiguration getConfiguration(SearchMode searchMode) { return searchModeSettingsResolver.getSettings(searchMode).getRepositorySearchConfiguration(); } protected List<SearchFilter> createAllFiltersList(RepositorySearchConfiguration configuration, RepositorySearchCriteria criteria) { List<SearchFilter> filterList = new ArrayList<SearchFilter>(); filterList.addAll(configuration.getSystemFilters()); filterList.addAll(getRestrictionsFilters(configuration)); // Hack - pro text filter adds restriction, which replace found repost options with their reports //In order to avoid it, in Web services we changing text filter to CE text filer explicitly for (int aTextFilterIndex = 0; aTextFilterIndex < filterList.size(); aTextFilterIndex++) { if (filterList.get(aTextFilterIndex) instanceof TextFilter) { filterList.remove(aTextFilterIndex); filterList.add(aTextFilterIndex, textFilter); } } if (!criteria.getAccessType().equals(AccessType.ALL)) { if (criteria.getCustomFilters() == null) { criteria.setCustomFilters(new LinkedList<SearchFilter>()); } criteria.getCustomFilters().add(accessTypeFilter); } if (criteria != null && criteria.getCustomFilters() != null && !criteria.getCustomFilters().isEmpty()) filterList.addAll(criteria.getCustomFilters()); return filterList; } protected List<SearchFilter> getRestrictionsFilters(RepositorySearchConfiguration configuration) { Set<String> customFilerIds = new HashSet<String>(configuration.getCustomFiltersMap().keySet()); List<SearchFilter> filters = new ArrayList<SearchFilter>(); if (customFilerIds != null && !customFilerIds.isEmpty()) for (CustomFilter filter : configuration.getCustomFilters()) { if (customFilerIds.contains(filter.getId())) { filters.add(filter.getFilter()); } } return filters; } @Transactional(propagation = Propagation.REQUIRED) public int getResultsCount(ExecutionContext context, SearchCriteriaFactory searchCriteriaFactory, List<SearchFilter> filters, SearchSorter sorter) { return repositoryService.getResourcesCount(context, searchCriteriaFactory, filters, sorter, transformerFactory); } @Transactional(propagation = Propagation.REQUIRED) public List<ResourceDetails> getResourceChildren(String type, String resourceUri) { ChildrenLoaderService childrenLoaderService = childrenLoaders.get(type); if (childrenLoaderService != null) { return getResourceDetailsList(childrenLoaderService.getChildren(resourceUri)); } return Collections.emptyList(); } private List<ResourceDetails> getResourceDetailsList(List<ResourceLookup> resources) { List<ResourceDetails> list = new ArrayList<ResourceDetails>(); for (Resource resource : resources) { ResourceDetails resourceDetails = resourceService.getResourceDetails(resource); list.add(resourceDetails); } return list; } public void setChildrenLoaders(Map<String, ChildrenLoaderService> childrenLoaders) { this.childrenLoaders = childrenLoaders; } private SearchCriteriaFactory obtainFactory(RepositorySearchCriteria criteria) { SearchCriteriaFactory res; if (criteria.isExcludeFolders() || !criteria.getAccessType().equals(AccessType.ALL)) { if (criteria.getResourceTypes() != null && criteria.getResourceTypes().size() == 1 && criteria.getCustomFilters() != null && !criteria.getCustomFilters().isEmpty()) { res = defaultSearchCriteriaFactory.newFactory(criteria.getResourceTypes().get(0)); criteria.getResourceTypes().clear(); } else { res = defaultSearchCriteriaFactory.newFactory(null); } } else { res = defaultSearchCriteriaFactory.newFactory(ResourceLookup.class.getName()); } return res; } }