/* See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * Esri Inc. licenses this file to You 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 com.esri.gpt.catalog.lucene; import com.esri.gpt.catalog.discovery.DiscoveryClause; import com.esri.gpt.catalog.discovery.DiscoveryException; import com.esri.gpt.catalog.discovery.LogicalClause; import com.esri.gpt.catalog.discovery.PropertyClause; import com.esri.gpt.catalog.discovery.PropertyValueType; import com.esri.gpt.catalog.discovery.SpatialClause; import java.util.logging.Logger; import org.apache.lucene.queryParser.ParseException; import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanQuery; /** * Adapts a catalog discovery LogicalClause to the Lucene BooleanQuery model. */ public class LogicalClauseAdapter extends DiscoveryClauseAdapter { /** class variables ========================================================= */ /** The Logger. */ private static Logger LOGGER = Logger.getLogger(LogicalClauseAdapter.class.getName()); /** constructors ============================================================ */ /** * Constructs with an associated query adapter. * @param queryAdapter the query adapter */ protected LogicalClauseAdapter(LuceneQueryAdapter queryAdapter) { super(queryAdapter); } /** methods ================================================================= */ /** * Builds a Lucene BooleanQuery by recursively traversing a * catalog discovery LogicalClause. * @param activeBooleanQuery the active Lucene boolean query * @param logicalClause the logical clause to adapt * @throws DiscoveryException if an invalid clause is encountered * @throws ParseException if a Lucene query parsing exception occurs */ protected void adaptLogicalClause(BooleanQuery activeBooleanQuery, LogicalClause logicalClause) throws DiscoveryException, ParseException { // loop the the sub clauses, recurse any logical clauses for (DiscoveryClause clause: logicalClause.getClauses()) { if (clause == null) { throw new DiscoveryException("A null clause was encountered."); } else if (clause instanceof LogicalClause) { BooleanQuery subQuery = new BooleanQuery(); appendQuery(activeBooleanQuery,logicalClause,subQuery); adaptLogicalClause(subQuery,(LogicalClause)clause); } else if (clause instanceof PropertyClause) { PropertyClauseAdapter adapter = new PropertyClauseAdapter(getQueryAdapter()); PropertyClause subClause = (PropertyClause)clause; if ((subClause.getTarget() != null) && (subClause.getTarget().getMeaning() != null)) { PropertyValueType pvt = subClause.getTarget().getMeaning().getValueType(); if ((pvt != null) && pvt.equals(PropertyValueType.TIMEPERIOD)) { adapter = new TimeperiodClauseAdapter(getQueryAdapter()); } } adapter.adaptPropertyClause(activeBooleanQuery,logicalClause,subClause); } else if (clause instanceof SpatialClause) { SpatialClauseAdapter adapter = new SpatialClauseAdapter(getQueryAdapter()); SpatialClause subClause = (SpatialClause)clause; adapter.adaptSpatialClause(activeBooleanQuery,logicalClause,subClause); } else { String sErr = "Unrecognized clause type:"+clause.getClass().getName(); throw new DiscoveryException(sErr); } } // MUST_NOT causes a problem when there is only one MUST_NOT clause within // a BooleanQuery, to get round it we add all documents as a SHOULD BooleanClause[] clauses = activeBooleanQuery.getClauses(); if ((clauses == null) || (clauses.length == 0)) { // TODO this will result in no records being returned, // possible this should be fixed } else if (clauses.length == 1) { if (clauses[0].getOccur().equals(BooleanClause.Occur.MUST_NOT)) { LOGGER.finer("Fixing single MUST_NOT clause within a BooleanQuery..."); appendSelectAll(activeBooleanQuery); } } } }