Package com.esri.gpt.control.georss

Source Code of com.esri.gpt.control.georss.JsonSearchEngine

/*
* Copyright 2012 Esri.
*
* Licensed 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.control.georss;

import com.esri.gpt.catalog.context.CatalogIndexException;
import com.esri.gpt.catalog.discovery.DiscoveredRecord;
import com.esri.gpt.catalog.discovery.rest.RestQuery;
import com.esri.gpt.catalog.lucene.LuceneIndexAdapter;
import com.esri.gpt.catalog.lucene.LuceneQueryAdapter;
import com.esri.gpt.catalog.search.OpenSearchProperties;
import com.esri.gpt.catalog.search.ResourceIdentifier;
import com.esri.gpt.framework.context.ApplicationConfiguration;
import com.esri.gpt.framework.context.ApplicationContext;
import com.esri.gpt.framework.context.RequestContext;
import com.esri.gpt.framework.jsf.FacesContextBroker;
import com.esri.gpt.framework.jsf.MessageBroker;
import com.esri.gpt.framework.sql.ConnectionBroker;
import com.esri.gpt.framework.sql.ManagedConnection;
import com.esri.gpt.framework.util.Val;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.IndexSearcher;

/**
* JSON search engine.
   * <p/>
   * Uses <i>json.engine.className</i> parameter from <b>gpt.xml</b> to create instance.
   * Creates default instance if parameter is empty.
   * <p/>
   * Two parameters: <i>json.meta.lucene</i> and <i>json.meta.catalog</i> from gpt.xml
   * configuration file determines whether certain family of output parameters
   * is allowed to be print to the output or not. Default: <code>true</code>.
* @see ExtJsonFeedWriter
*/
public abstract class JsonSearchEngine {

  /**
   * Logger.
   */
  private static final Logger LOG = Logger.getLogger(JsonSearchEngine.class.getCanonicalName());
 
  /**
   * Default search engine.
   */
  private static final JsonSearchEngine defaultEngine = new JsonSearchEngine() {
    @Override
    public IFeedRecords search(HttpServletRequest request, HttpServletResponse response, RequestContext context, RestQuery query) throws Exception {
      return doSearch(request, response, context, query);
    }
  };

  /**
   * Creates instance of the search engine.
   * @return instance of {@link JsonSearchEngine}
   */
  public static JsonSearchEngine createInstance() {
    String className = getConfigParam("json.engine.className");
    if (className.isEmpty()) {
      return defaultEngine;
    } else {
      try {
        Class engineClass = Class.forName(className);
        return (JsonSearchEngine) engineClass.newInstance();
      } catch (Exception ex) {
        LOG.log(Level.INFO, "Error creating JSON search engine: " + className +". Using default JSON search engine instead.", ex);
        return defaultEngine;
      }
    }
  }

  /**
   * Performs search operation.
   *
   * @param request HTTP servlet request
   * @param response HTTP servlet response
   * @param context request context
   * @param query query
   * @return records
   * @throws Exception if searching fails
   */
  public abstract IFeedRecords search(HttpServletRequest request, HttpServletResponse response, RequestContext context, RestQuery query) throws Exception;

  /**
   * Loads standard field meta info.
   * @param fields list of fields
   */
  protected void loadStdFieldMeta(List<IFeedRecords.FieldMeta> fields) {
    fields.add(new IFeedRecords.FieldMeta("objectid", "esriFieldTypeOID", "OBJECTID"));
    fields.add(new IFeedRecords.FieldMeta("title", "esriFieldTypeString", "Title", 256));
    fields.add(new IFeedRecords.FieldMeta("id", "esriFieldTypeGUID", "UUID", 38));
    fields.add(new IFeedRecords.FieldMeta("updated", "esriFieldTypeDate", "Updated", 20));
    fields.add(new IFeedRecords.FieldMeta("contentType", "esriFieldTypeString", "Content Type", 64));
    fields.add(new IFeedRecords.FieldMeta("summary", "esriFieldTypeString", "Summary", 256));
    fields.add(new IFeedRecords.FieldMeta("shape", "esriFieldTypeGeometry", "Shape"));
  }

  /**
   * Performs search operation.
   * @param request HTTP servlet request
   * @param response HTTP servlet response
   * @param context request context
   * @param query query
   * @return records
   * @throws Exception if searching fails
   */
  protected IFeedRecords doSearch(HttpServletRequest request, HttpServletResponse response, RequestContext context, RestQuery query) throws Exception {
    MessageBroker msgBroker = new FacesContextBroker(request, response).extractMessageBroker();
    final Map<DiscoveredRecord, Map<String, List<String>>> mapping = new HashMap<DiscoveredRecord, Map<String, List<String>>>();

    List<IFeedRecords.FieldMeta> fields = new ArrayList<IFeedRecords.FieldMeta>();
    loadStdFieldMeta(fields);

    int startRecord = query.getFilter().getStartRecord();
    boolean returnIdsOnly = Val.chkBool(Val.chkStr(request.getParameter("returnIdsOnly")), false);
    if (returnIdsOnly) {
      startRecord = 1;
      query.getFilter().setMaxRecords(1);
      LuceneQueryAdapter tmp = new LuceneQueryAdapter();
      tmp.execute(context, query);
      query.getFilter().setMaxRecords(query.getResult().getNumberOfHits());
    }

    query.getFilter().setStartRecord(startRecord);
    LuceneQueryAdapter lqa = new LuceneQueryAdapter() {
      @Override
      protected void onRecord(DiscoveredRecord record, Document document) {
        Map<String, List<String>> fieldMap = new HashMap<String, List<String>>();
        for (Fieldable field : document.getFields()) {
          String name = field.name();
          List<String> fieldValues = fieldMap.get(name);
          if (fieldValues == null) {
            fieldValues = new ArrayList<String>();
            fieldMap.put(name, fieldValues);
          }
          fieldValues.add(field.stringValue());
        }
        mapping.put(record, fieldMap);
      }
    };
    lqa.execute(context, query);
    startRecord += query.getFilter().getMaxRecords();

    loadLuceneMeta(context, fields);

    OpenSearchProperties osProps = new OpenSearchProperties();
    osProps.setShortName(msgBroker.retrieveMessage("catalog.openSearch.shortName"));
    osProps.setNumberOfHits(query.getResult().getNumberOfHits());
    osProps.setStartRecord(query.getFilter().getStartRecord());
    osProps.setRecordsPerPage(query.getFilter().getMaxRecords());

    ResourceIdentifier resourceIdentifier = ResourceIdentifier.newIdentifier(context);
    DiscoveredRecordsAdapter discoveredRecordsAdapter =
            new DiscoveredRecordsAdapter(resourceIdentifier, osProps, fields, query.getResult().getRecords(), mapping);

    loadCatalog(context, discoveredRecordsAdapter);

    FeedLinkBuilder linkBuilder = new FeedLinkBuilder(context, RequestContext.resolveBaseContextPath(request), msgBroker);
    for (IFeedRecord record : discoveredRecordsAdapter) {
      linkBuilder.build(record);
    }

    return discoveredRecordsAdapter;
  }

  /**
   * Loads Lucene index metadata.
   * @param context request context
   * @param fields list of fields
   * @throws CatalogIndexException if accessing index fails
   */
  protected void loadLuceneMeta(RequestContext context, List<IFeedRecords.FieldMeta> fields) throws CatalogIndexException {
    if (!isLuceneMetaAllowed()) {
      return;
    }

    LuceneIndexAdapter indexAdapter = new LuceneIndexAdapter(context);
    IndexSearcher searcher = null;
    try {
      searcher = indexAdapter.newSearcher();
      IndexReader indexReader = searcher.getIndexReader();
      for (String fieldName : indexReader.getFieldNames(IndexReader.FieldOption.ALL)) {
        fields.add(new IFeedRecords.FieldMeta(IFeedRecord.STD_COLLECTION_INDEX + "." + fieldName, "esriFieldTypeString", fieldName));
      }
    } catch (Exception e) {
      String sMsg = "Error accessing index:\n " + Val.chkStr(e.getMessage());
      throw new CatalogIndexException(sMsg, e);
    } finally {
      indexAdapter.closeSearcher(searcher);
    }
  }

  /**
   * Loads catalog meta.
   * @param context request context
   * @param records records
   * @throws SQLException if accessing catalog database fails
   */
  protected void loadCatalog(RequestContext context, IFeedRecords records) throws SQLException {
    if (!isCatalogMetaAllowed()) {
      return;
    }

    ConnectionBroker connectionBroker = context.getConnectionBroker();
    ManagedConnection managedConnection = connectionBroker.returnConnection("");
    Connection conn = managedConnection.getJdbcConnection();

    boolean firstRecord = true;

    for (IFeedRecord record : records) {
      PreparedStatement st = null;
      ResultSet rs = null;
      try {
        st = conn.prepareStatement("SELECT * FROM GPT_RESOURCE WHERE DOCUUID=?");
        st.setString(1, record.getUuid());

        rs = st.executeQuery();
        if (rs.next()) {
          ResultSetMetaData metaData = rs.getMetaData();
          for (int i = 1; i <= metaData.getColumnCount(); i++) {
            String name = metaData.getColumnName(i);
            Object value = rs.getObject(i);
            IFeedAttribute attribute = IFeedAttribute.Factory.create(value, metaData.getColumnDisplaySize(i));
            if (firstRecord) {
              records.getMetaData().add(new IFeedRecords.FieldMeta(IFeedRecord.STD_COLLECTION_CATALOG + "." + name, attribute.getEsriType(), name, attribute.getLength()));
            }
            record.getData(IFeedRecord.STD_COLLECTION_CATALOG).put(name, attribute);
          }
        }
        firstRecord = false;
      } finally {
        if (rs != null) {
          try {
            rs.close();
          } catch (SQLException e) {
          }
        }
        if (st != null) {
          try {
            st.close();
          } catch (SQLException e) {
          }
        }
      }
    }
  }

  /**
   * Gets gpt.xml configuration parameter.
   * @param paramName parameter name
   * @return parameter value
   */
  protected static String getConfigParam(String paramName) {
    ApplicationContext appCtx = ApplicationContext.getInstance();
    ApplicationConfiguration appCfg = appCtx.getConfiguration();
    return Val.chkStr(appCfg.getCatalogConfiguration().getParameters().getValue(paramName));
  }

  /**
   * Checks if Lucene data is allowed.
   * Reads "json.meta.lucene" configuration parameter.
   * @return <code>true</code> if data is allowed
   */
  protected boolean isLuceneMetaAllowed() {
    String sMeta = getConfigParam("json.meta.lucene");
    return Val.chkBool(sMeta, true);
  }

  /**
   * Checks if catalog data is allowed.
   * Reads "json.meta.catalog" configuration parameter.
   * @return <code>true</code> if data is allowed
   */
  protected boolean isCatalogMetaAllowed() {
    String sMeta = getConfigParam("json.meta.catalog");
    return Val.chkBool(sMeta, true);
  }
}
TOP

Related Classes of com.esri.gpt.control.georss.JsonSearchEngine

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.