Java tutorial
/* * **************************************************- * ingrid-interface-csw * ================================================== * Copyright (C) 2014 - 2016 wemove digital solutions GmbH * ================================================== * Licensed under the EUPL, Version 1.1 or as soon they will be * approved by the European Commission - subsequent versions of the * EUPL (the "Licence"); * * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * * http://ec.europa.eu/idabc/eupl5 * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * **************************************************# */ /** * Copyright (c) 2012 wemove digital solutions. All rights reserved. */ package de.ingrid.interfaces.csw.search.impl; import java.io.File; import java.util.Set; import java.util.logging.Level; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.lucene.analysis.Analyzer; import org.geotoolkit.lucene.filter.SpatialQuery; import org.geotoolkit.lucene.index.LuceneIndexSearcher; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import de.ingrid.interfaces.csw.config.ApplicationProperties; import de.ingrid.interfaces.csw.config.ConfigurationProvider; import de.ingrid.interfaces.csw.domain.CSWRecord; import de.ingrid.interfaces.csw.domain.constants.ConfigurationKeys; import de.ingrid.interfaces.csw.domain.constants.ElementSetName; import de.ingrid.interfaces.csw.domain.filter.FilterParser; import de.ingrid.interfaces.csw.domain.query.CSWQuery; import de.ingrid.interfaces.csw.search.CSWRecordRepository; import de.ingrid.interfaces.csw.search.CSWRecordResults; import de.ingrid.interfaces.csw.search.Searcher; import de.ingrid.interfaces.csw.tools.LuceneTools; import de.ingrid.interfaces.csw.tools.StringUtils; /** * A Searcher implementation that searches in a Lucene index. * * @author ingo herwig <ingo@wemove.com> */ @Service public class LuceneSearcher implements Searcher { final protected static Log log = LogFactory.getLog(LuceneSearcher.class); /** * The path to the Lucene index */ private File indexPath; /** * The update job configuration provider */ @Autowired private ConfigurationProvider configurationProvider; /** * The FilterParser instance that converts csw queries to InGrid queries */ @Autowired private FilterParser filterParser; /** * The Lucene index searcher */ protected LuceneIndexSearcher lis = null; /** * The started state */ protected boolean isStarted = false; /** * The repository where the CSW records are retrieved from */ @Autowired private CSWRecordRepository recordRepository; @Autowired private LuceneTools luceneTools; @Override public void start() throws Exception { if (this.isStarted) { this.stop(); } // overwrite indexer path with configuration if (configurationProvider != null) { this.indexPath = configurationProvider.getIndexPath(); } log.info("Start search index: " + this.indexPath); // CREATE new analyzer to guarantee that analyzer not closed ! Analyzer myAnalyzer = luceneTools.createAnalyzer(); lis = new LuceneIndexSearcher(this.indexPath, "", myAnalyzer); lis.setCacheEnabled(ApplicationProperties.getBoolean(ConfigurationKeys.CACHE_ENABLE, false)); lis.setLogLevel(log.isDebugEnabled() ? Level.FINEST : (log.isInfoEnabled() ? Level.INFO : (log.isWarnEnabled() ? Level.WARNING : Level.SEVERE))); this.isStarted = true; } @Override public void stop() throws Exception { if (lis != null) { log.info("Close search index: " + this.indexPath); lis.destroy(); this.isStarted = false; } } @Override public CSWRecordResults search(CSWQuery query) throws Exception { if (this.filterParser == null) { throw new RuntimeException("LuceneSearcher is not configured properly: filterParser is not set."); } if (this.recordRepository == null) { throw new RuntimeException("LuceneSearcher is not configured properly: recordRepository is not set."); } if (!this.isStarted) { start(); } if (this.lis == null) { throw new RuntimeException("LuceneSearcher is not started."); } CSWRecordResults results = new CSWRecordResults(); ElementSetName elementSetName = query.getElementSetName(); if (query.getIds() != null) { // there are records specified by id. So we can search in the record // repository // directly for (String id : query.getIds()) { if (this.recordRepository.containsRecord(id)) { CSWRecord record = this.recordRepository.getRecord(id, elementSetName); results.add(record); } } // add number of results as total hits results.setTotalHits((results.getResults() != null) ? results.getResults().size() : 0); } else { // use the query constraints to search for records in the Lucene // index if (log.isDebugEnabled()) { log.debug("Incoming constraint:" + (query.getConstraint() != null ? StringUtils.nodeToString(query.getConstraint().getDocumentElement()) : "no filter set")); log.debug("Incoming SortBy:" + (query.getSort() != null ? StringUtils.nodeToString(query.getSort().getDocumentElement()) : "no SortBy set")); } SpatialQuery spatialQuery = this.filterParser.parse(query); if (log.isDebugEnabled()) { log.debug("Incoming spatial query:" + spatialQuery); } if (spatialQuery == null) { throw new RuntimeException("Error parsing query constraint: Lucene query is null"); } Set<String> resultIds = lis.doSearch(spatialQuery); if (log.isDebugEnabled()) { log.debug("Found " + resultIds.size() + " hits, returning " + Math.min((query.getStartPosition() + query.getMaxRecords() - 1), resultIds.size()) + "."); } // get the CSWRecord for each document found in the index int cnt = 1; int endIdx = Math.min((query.getStartPosition() + query.getMaxRecords() - 1), resultIds.size()); for (String resultId : resultIds) { if (cnt >= query.getStartPosition() && cnt <= endIdx) { CSWRecord record = this.recordRepository.getRecord(resultId, elementSetName); results.add(record); } else if (cnt > endIdx) { break; } cnt++; } results.setTotalHits(resultIds.size()); } return results; } @Override public File getIndexPath() { if (this.indexPath == null && configurationProvider != null) { this.indexPath = configurationProvider.getIndexPath(); } return this.indexPath; } /** * Set the path to the Lucene index * * @param indexPath */ public void setIndexPath(File indexPath) { this.indexPath = indexPath; } /** * Set the FilterParser instance * * @param filterParser */ public void setFilterParser(FilterParser filterParser) { this.filterParser = filterParser; } @Override public void setRecordRepository(CSWRecordRepository recordRepository) { this.recordRepository = recordRepository; } public boolean isStarted() { return isStarted; } @Override public void refresh() throws Exception { if (lis != null) { this.lis.refresh(); } } public void setLuceneTools(LuceneTools myLuceneTools) { this.luceneTools = myLuceneTools; } }