public ClusteredCacheQueryImpl(
     Query luceneQuery,
     SearchFactoryIntegrator searchFactory,
     ExecutorService asyncExecutor,
     AdvancedCache<?, ?> cache,
     KeyTransformationHandler keyTransformationHandler,
     Class<?>... classes) {
   super(luceneQuery, searchFactory, cache, keyTransformationHandler, classes);
   this.asyncExecutor = asyncExecutor;
   this.hSearchQuery =
       searchFactory
           .createHSQuery()
           .luceneQuery(luceneQuery)
           .targetedEntities(Arrays.asList(classes));
   this.marshaller =
       ComponentRegistryUtils.getComponent(
           cache, StreamingMarshaller.class, KnownComponentNames.CACHE_MARSHALLER);
 }
 private void wipeExistingIndexes() {
   QueryInterceptor queryInterceptor = ComponentRegistryUtils.getQueryInterceptor(cache);
   queryInterceptor.purgeAllIndexes();
 }
  private LuceneQueryParsingResult parseQuery(
      AdvancedCache<byte[], byte[]> cache,
      final SerializationContext serCtx,
      String queryString,
      SearchIntegrator searchFactory) {
    LuceneProcessingChain processingChain;
    if (cache.getCacheConfiguration().compatibility().enabled()) {
      final QueryInterceptor queryInterceptor = ComponentRegistryUtils.getQueryInterceptor(cache);
      EntityNamesResolver entityNamesResolver =
          new EntityNamesResolver() {
            @Override
            public Class<?> getClassFromName(String entityName) {
              MessageMarshaller messageMarshaller =
                  (MessageMarshaller) serCtx.getMarshaller(entityName);
              Class clazz = messageMarshaller.getJavaClass();
              return queryInterceptor.isIndexed(clazz) ? clazz : null;
            }
          };

      processingChain =
          new LuceneProcessingChain.Builder(searchFactory, entityNamesResolver)
              .buildProcessingChainForClassBasedEntities();
    } else {
      EntityNamesResolver entityNamesResolver =
          new EntityNamesResolver() {
            @Override
            public Class<?> getClassFromName(String entityName) {
              return serCtx.canMarshall(entityName) ? ProtobufValueWrapper.class : null;
            }
          };

      FieldBridgeProvider fieldBridgeProvider =
          new FieldBridgeProvider() {
            @Override
            public FieldBridge getFieldBridge(String type, String propertyPath) {
              Descriptor md = serCtx.getMessageDescriptor(type);
              FieldDescriptor fd = getFieldDescriptor(md, propertyPath);
              switch (fd.getType()) {
                case DOUBLE:
                  return NumericFieldBridge.DOUBLE_FIELD_BRIDGE;
                case FLOAT:
                  return NumericFieldBridge.FLOAT_FIELD_BRIDGE;
                case INT64:
                case UINT64:
                case FIXED64:
                case SFIXED64:
                case SINT64:
                  return NumericFieldBridge.LONG_FIELD_BRIDGE;
                case INT32:
                case FIXED32:
                case UINT32:
                case SFIXED32:
                case SINT32:
                case BOOL:
                case ENUM:
                  return NumericFieldBridge.INT_FIELD_BRIDGE;
                case STRING:
                case BYTES:
                case GROUP:
                case MESSAGE:
                  return new NullEncodingTwoWayFieldBridge(
                      new TwoWayString2FieldBridgeAdaptor(StringBridge.INSTANCE), NULL_TOKEN);
              }
              return null;
            }
          };

      processingChain =
          new LuceneProcessingChain.Builder(searchFactory, entityNamesResolver)
              .buildProcessingChainForDynamicEntities(fieldBridgeProvider);
    }

    return new QueryParser().parseQuery(queryString, processingChain);
  }
  /** Execute Lucene index query. */
  private QueryResponse executeQuery(
      AdvancedCache<byte[], byte[]> cache, SerializationContext serCtx, QueryRequest request) {
    final SearchManager searchManager = Search.getSearchManager(cache);
    final SearchIntegrator searchFactory = searchManager.getSearchFactory();
    final QueryCache queryCache = ComponentRegistryUtils.getQueryCache(cache); // optional component

    LuceneQueryParsingResult parsingResult;
    Query luceneQuery;

    if (queryCache != null) {
      KeyValuePair<String, Class> queryCacheKey =
          new KeyValuePair<String, Class>(request.getJpqlString(), LuceneQueryParsingResult.class);
      parsingResult = queryCache.get(queryCacheKey);
      if (parsingResult == null) {
        parsingResult = parseQuery(cache, serCtx, request.getJpqlString(), searchFactory);
        queryCache.put(queryCacheKey, parsingResult);
      }
    } else {
      parsingResult = parseQuery(cache, serCtx, request.getJpqlString(), searchFactory);
    }

    luceneQuery = parsingResult.getQuery();

    if (!cache.getCacheConfiguration().compatibility().enabled()) {
      // restrict on entity type
      QueryBuilder qb =
          searchFactory.buildQueryBuilder().forEntity(parsingResult.getTargetEntity()).get();
      luceneQuery =
          qb.bool()
              .must(
                  qb.keyword()
                      .onField(TYPE_FIELD_NAME)
                      .ignoreFieldBridge()
                      .ignoreAnalyzer()
                      .matching(parsingResult.getTargetEntityName())
                      .createQuery())
              .must(luceneQuery)
              .createQuery();
    }

    CacheQuery cacheQuery = searchManager.getQuery(luceneQuery, parsingResult.getTargetEntity());

    if (parsingResult.getSort() != null) {
      cacheQuery = cacheQuery.sort(parsingResult.getSort());
    }

    int projSize = 0;
    if (parsingResult.getProjections() != null && !parsingResult.getProjections().isEmpty()) {
      projSize = parsingResult.getProjections().size();
      cacheQuery =
          cacheQuery.projection(parsingResult.getProjections().toArray(new String[projSize]));
    }
    if (request.getStartOffset() > 0) {
      cacheQuery = cacheQuery.firstResult((int) request.getStartOffset());
    }
    if (request.getMaxResults() > 0) {
      cacheQuery = cacheQuery.maxResults(request.getMaxResults());
    }

    List<?> list = cacheQuery.list();
    List<WrappedMessage> results =
        new ArrayList<WrappedMessage>(projSize == 0 ? list.size() : list.size() * projSize);
    for (Object o : list) {
      if (projSize == 0) {
        results.add(new WrappedMessage(o));
      } else {
        Object[] row = (Object[]) o;
        for (int j = 0; j < projSize; j++) {
          results.add(new WrappedMessage(row[j]));
        }
      }
    }

    QueryResponse response = new QueryResponse();
    response.setTotalResults(cacheQuery.getResultSize());
    response.setNumResults(list.size());
    response.setProjectionSize(projSize);
    response.setResults(results);

    return response;
  }