/* 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.stats; import com.esri.gpt.catalog.context.CatalogConfiguration; import com.esri.gpt.catalog.discovery.PropertyMeanings; import com.esri.gpt.catalog.lucene.AclFilter; import com.esri.gpt.catalog.lucene.IsPartOfFilter; import com.esri.gpt.catalog.lucene.Storeable; import com.esri.gpt.catalog.lucene.Storeables; import com.esri.gpt.framework.context.RequestContext; import com.esri.gpt.framework.security.identity.AuthenticationStatus; import com.esri.gpt.framework.security.metadata.MetadataAcl; import com.esri.gpt.framework.util.Val; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.apache.lucene.index.IndexReader; import org.apache.lucene.search.Filter; import org.apache.lucene.util.OpenBitSet; /** * Request to obtain Lucene index statistics. */ public class StatsRequest { /** instance variables ====================================================== */ private String baseQueryUrl = "/geoportal/rest/find/document"; private String baseStatsUrl = "/geoportal/rest/index/stats"; private OpenBitSet documentFilterBitSet; private RequestContext requestContext; private String responseFormat = "html"; private PrintWriter responseWriter = new PrintWriter(System.err,true); private String sortBy; private Storeables storeables; /** constructors ============================================================ */ /** * Constructs with an associated request context. * @param requestContext the active request context */ public StatsRequest(RequestContext requestContext) { CatalogConfiguration catCfg = requestContext.getCatalogConfiguration(); PropertyMeanings meanings = catCfg.getConfiguredSchemas().getPropertyMeanings(); this.requestContext = requestContext; this.storeables = new Storeables(meanings); if ((requestContext != null) && (requestContext.getServletRequest() != null) && (requestContext.getServletRequest() instanceof HttpServletRequest)) { HttpServletRequest http = (HttpServletRequest)requestContext.getServletRequest(); if (http.getContextPath() != null) { this.baseQueryUrl = http.getContextPath()+"/rest/find/document"; this.baseStatsUrl = http.getContextPath()+"/rest/index/stats"; } } } /** properties ============================================================= */ /** * Gets the base URL used to construct a REST query. * <br/>e.g. /geoportal/rest/find/document * @return the base query url */ public String getBaseQueryUrl() { return this.baseQueryUrl; } /** * Gets the base URL used to construct a stats request. * <br/>e.g. /geoportal/rest/index/stats * @return the base stats url */ public String getBaseStatsUrl() { return this.baseStatsUrl; } /** * Gets the filter bitset representing the set of documents for which statistics * will be collected. * @return the document filter bitset (can be null) */ public OpenBitSet getDocumentFilterBitSet() { return this.documentFilterBitSet; } /** * Gets the underlying request context. * @return the request context */ public RequestContext getRequestContext() { return this.requestContext; } /** * Gets the response format (html|json) * @return the response format */ public String getResponseFormat() { return this.responseFormat; } /** * Sets the response format (html|json) * @param format the response format */ public void setResponseFormat(String format) { this.responseFormat = format; } /** * Gets the writer to be used wjen generating the response. * @return the response writer */ public PrintWriter getResponseWriter() { return this.responseWriter; } /** * Sets the writer to be used wjen generating the response. * @param writer the response writer */ public void setResponseWriter(PrintWriter writer) { this.responseWriter = writer; } /** * Gets the sort by parameter. * @return the sort by parameter */ public String getSortBy() { return this.sortBy; } /** * Sets the sort by parameter. * @param sortBy the sort by parameter */ public void setSortBy(String sortBy) { this.sortBy = sortBy; } /** * Gets the field names for which statistics can be collected. * @param reader the Lucene index reader * @return the array of field names */ public String[] getCollectableFieldNames(IndexReader reader) { List<String> collectable = new ArrayList<String>(); Collection<String> indexed = reader.getFieldNames(IndexReader.FieldOption.INDEXED); for (String name: indexed) { if (this.isFieldCollectable(name)) { collectable.add(name); } } return collectable.toArray(new String[0]); } /** * Gets the storable associated with a field name. * @param fieldName the subject field name * @return the associated storable (can be null) */ public Storeable getStoreable(String fieldName) { if (Val.chkStr(fieldName).equalsIgnoreCase("body")) { return null; } else { return (Storeable)this.storeables.get(fieldName); } } /** * Determines if statistics can be collected for a field. * @param fieldName the field name * @return true if statistics can be collected for the field */ public boolean isFieldCollectable(String fieldName) { return (this.getStoreable(fieldName) != null); } /** * Prepares the request prior to statistics collection. * <br/>A document filter bitset will be created associated with only those * documents that are visible to the active user. * @param reader the Lucene index reader * @throws IOException if an index i/o exception occurs */ public void prepare(IndexReader reader) throws IOException { MetadataAcl acl = new MetadataAcl(this.requestContext); AuthenticationStatus auth = this.requestContext.getUser().getAuthenticationStatus(); boolean bAdmin = auth.getAuthenticatedRoles().hasRole("gptAdministrator"); Filter filter = null; if (!bAdmin && !acl.isPolicyUnrestricted()) { String[] aclValues = acl.makeUserAcl(); filter = new AclFilter(Storeables.FIELD_ACL,aclValues); } filter = IsPartOfFilter.make(this.getRequestContext(),filter); if (filter != null) { this.documentFilterBitSet = (OpenBitSet)filter.getDocIdSet(reader); } } }