/* 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.server.assertion.handler; import com.esri.gpt.server.assertion.components.AsnAssertionRenderer; import com.esri.gpt.server.assertion.components.AsnAssertionSet; import com.esri.gpt.server.assertion.components.AsnAuthorizer; import com.esri.gpt.server.assertion.components.AsnConstants; import com.esri.gpt.server.assertion.components.AsnContext; import com.esri.gpt.server.assertion.components.AsnOperation; import com.esri.gpt.server.assertion.components.AsnProperty; import com.esri.gpt.server.assertion.components.AsnValueType; import com.esri.gpt.server.assertion.exception.AsnInvalidOperationException; import com.esri.gpt.server.assertion.index.Assertion; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.Sort; import org.apache.lucene.search.SortField; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TopDocs; /** * Handles assertions associated with comment queries. */ public class AsnCommentHandler extends AsnOperationHandler { /** constructors ============================================================ */ /** Default constructor */ public AsnCommentHandler() {} /** methods ================================================================= */ /** * Handles an assertion operation. * @param context the assertion operation context * @throws Exception if a processing exception occurs */ public void handle(AsnContext context) throws Exception { // initialize AsnOperation operation = context.getOperation(); AsnAuthorizer authorizer = context.getAuthorizer(); String subjectPfx = operation.getSubject().getURNPrefix(); String predicate = operation.getPredicate().getURN(); // query comments if (subjectPfx.endsWith(":assertionid") && predicate.equals("urn:esri:geoportal:comment:query")) { Assertion assertion = this.getIndexAdapter().loadAssertionById(context,true); authorizer.authorizeQuery(context); AsnAssertionRenderer renderer = new AsnAssertionRenderer(); AsnProperty prop = renderer.makeProperty(context,assertion); context.getOperationResponse().generateResponse(context,prop); } else if (subjectPfx.endsWith(":resourceid") && predicate.equals("urn:esri:geoportal:comment:query")) { authorizer.authorizeQuery(context); this.query(context); } else { throw new AsnInvalidOperationException(); } } /** * Queries comments. * @param context the assertion operation context * @throws Exception if an exception occurs */ private void query(AsnContext context) throws Exception { // initialize AsnOperation operation = context.getOperation(); AsnAssertionSet asnSet = operation.getAssertionSet(); AsnValueType vType = asnSet.getValueType(); String subject = operation.getSubject().getURN(); String predicate = vType.getRdfPredicate(); // build a query to match all occurrences of the subject/predicate pair BooleanQuery query = new BooleanQuery(); Query qSubject = new TermQuery(new Term(AsnConstants.FIELD_RDF_SUBJECT,subject)); Query qPredicate = new TermQuery(new Term(AsnConstants.FIELD_RDF_PREDICATE,predicate)); query.add(qSubject,BooleanClause.Occur.MUST); query.add(qPredicate,BooleanClause.Occur.MUST); // sort on descending timestamp String tsField = AsnConstants.FIELD_SYS_TIMESTAMP; Sort sortOption = new Sort(new SortField(tsField,SortField.STRING,true)); // determine the start and end positions int startRecord = context.getRequestOptions().getStartRecord() - 1; int maxRecords = context.getRequestOptions().getMaxRecords(); if (startRecord < 0) startRecord = 0; int recordsPerPage = maxRecords; if (recordsPerPage <= 0) recordsPerPage = 1; int hitsToReturn = startRecord + recordsPerPage; int nextRecord = 0; int numDocs = 0; IndexReader reader = null; IndexSearcher searcher = null; try { // make the reader and searcher, execute the search reader = this.getIndexAdapter().makeIndexReader(); searcher = new IndexSearcher(reader); TopDocs topDocs = searcher.search(query,null,hitsToReturn,sortOption); ScoreDoc[] scoreDocs = null; int totalHits = topDocs.totalHits; if (maxRecords > 0) { scoreDocs = topDocs.scoreDocs; if ((scoreDocs != null) && (scoreDocs.length) > 0) { numDocs = scoreDocs.length; if (totalHits > numDocs) { nextRecord = numDocs + 1; } } } // root property for the response String rootSubject = subject; String roorPredicate = operation.getPredicate().getURN()+"response"; AsnProperty rootProp = new AsnProperty(rootSubject,roorPredicate,null); // hit count and next record String queryPfx = asnSet.getURNPrefix()+":query"; rootProp.getChildren().add(new AsnProperty(null,queryPfx+":hits",""+totalHits)); if (nextRecord > 0) { rootProp.getChildren().add(new AsnProperty(null,queryPfx+":nextRecord",""+nextRecord)); } // canCreate capability for the active user String canCreatePred = asnSet.getURNPrefix()+":activeUser:canCreate"; String canCreateVal = ""+context.getAuthorizer().canCreate(context,asnSet.getAuthPolicy()); rootProp.getChildren().add(new AsnProperty(null,canCreatePred,canCreateVal)); // process the documents, generate the response AsnAssertionRenderer renderer = new AsnAssertionRenderer(); for (int i=startRecord; i<numDocs; i++) { Document document = reader.document(scoreDocs[i].doc); Assertion assertion = asnSet.newAssertion(context,false); assertion.load(document); rootProp.getChildren().add(renderer.makeProperty(context,assertion)); } context.getOperationResponse().generateResponse(context,rootProp.getChildren()); } finally { this.getIndexAdapter().closeReader(reader); this.getIndexAdapter().closeSearcher(searcher); } } }