Package com.esri.gpt.control.rest.search

Source Code of com.esri.gpt.control.rest.search.SearchThread

/* 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.control.rest.search;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.esri.gpt.catalog.discovery.rest.RestQuery;
import com.esri.gpt.catalog.search.ASearchEngine;
import com.esri.gpt.catalog.search.GetRecordsGenerator;
import com.esri.gpt.catalog.search.SearchCriteria;
import com.esri.gpt.catalog.search.SearchEngineCSW;
import com.esri.gpt.catalog.search.SearchEngineFactory;
import com.esri.gpt.catalog.search.SearchRequestDefinition;
import com.esri.gpt.catalog.search.SearchResult;
import com.esri.gpt.framework.context.RequestContext;
import com.esri.gpt.framework.jsf.MessageBroker;

/**
* The Class SearchThread.
*
* @author UM,TM
*/
public class SearchThread extends Thread {

// clas variables ==============================================================
/** class logger *. */
private Logger LOG = Logger.getLogger(SearchThread.class.getCanonicalName());

// instance variables ==========================================================
/** The is working. */
private boolean isWorking = false;

private boolean stop;

/** The rid. */
private String rid;

/** The search context. */
private SearchContext searchContext;

/** The search status. */
private SearchStatus searchStatus = new SearchStatus();

/** The listeners. */
private ArrayList<ISearchListener> listeners;

private ASearchEngine searchEngine;

private CountDownLatch countDownLatch;

private volatile boolean timeUp;

private volatile ReentrantReadWriteLock globalLock = new ReentrantReadWriteLock();

private volatile Lock lockListenerEvent = globalLock.readLock();

private volatile Lock lockNotifyTimeUp = globalLock.writeLock();




// constructors ================================================================
/**
* Instantiates a new search thread.
*
* @param context
*          the context
* @param rid
*          the rid
*/
public SearchThread(SearchContext context, String rid, ASearchEngine engine,
  CountDownLatch countDownLatch) {
  this.setSearchContext(context);
  this.setRID(rid);
  this.setSearchEngine(engine);
  this.countDownLatch = countDownLatch;
  this.getSearchStatus().setRid(rid);
}

// properties ==================================================================

/**
* Gets the flag indicating if the search is in a working state.
*
* @return if the search is working
*/
public boolean getIsWorking() {
  return this.isWorking;
}

/**
* Sets the flag indicating if the search is in a working state.
*
* @param isWorking
*          <code>true</code> if the search is working
*/
public void setIsWorking(boolean isWorking) {
  this.isWorking = isWorking;
  if(isWorking == true) {
    this.writeStatus(SearchStatus.STATUSTYPE_WORKING);
  }
}

/**
* Gets the max search time.
*
* @return the max search time
*/
private int getMaxSearchTime() {
  return this.getSearchContext().getMaxSearchTime();
}

/**
* Gets the search engine.
*
* @return the search engine
*/
public ASearchEngine getSearchEngine() {
  return searchEngine;
}

/**
* Sets the search engine.
*
* @param searchEngine
*          the new search engine
*/
public void setSearchEngine(ASearchEngine searchEngine) {
  this.searchEngine = searchEngine;
}

/**
* Gets the RID.
*
* @return the RID
*/
public String getRID() {
  return this.rid;
}

/**
* Sets the RID.
*
* @param rid
*          the RID
*/
public void setRID(String rid) {
  this.rid = rid;
}

/**
* Gets the search context.
*
* @return the search context
*/
public SearchContext getSearchContext() {
  return this.searchContext;
}

/**
* Sets the search context.
*
* @param searchContext
*          the search context
*/
public void setSearchContext(SearchContext searchContext) {
  this.searchContext = searchContext;
}


public boolean isTimeUp() {
 
  return timeUp;
}

/**
* Sets the time up.  Called to notify the thread that its time is up.
*
* @param timeUp the new time up
*/
public void setTimeUp(boolean timeUp) {
  lockNotifyTimeUp.lock();
  try {
   
    LOG.finer("Setting time up when status is " +
        this.getSearchStatus().getStatusType());
   
    if(timeUp == true &&
        !(this.getSearchStatus().getStatusType()
          .equals(SearchStatus.STATUSTYPE_COMPLETED) ||
        this.getSearchStatus().getStatusType()
          .equals(SearchStatus.STATUSTYPE_FAILED))
        ) {
      this.getSearchStatus().setStatusType(SearchStatus.STATUSTYPE_SEARCH_TIMEOUT);
      this.fireSearchEventWorker();
      this.timeUp = timeUp;
    }
  } finally {
    lockNotifyTimeUp.unlock();
  }
}

/**
* Gets the search status.
*
* @return the search status
*/
public SearchStatus getSearchStatus() {
  return this.searchStatus;
}

/**
* Sets the search status.
*
* @param searchStatus
*          the search status
*/
public void setSearchStatus(SearchStatus searchStatus) {
  this.searchStatus = searchStatus;
}

// methods =====================================================================/**
/**
* Write status.
*
* @param status the status
*/
private void writeStatus(String status) {
  this.getSearchStatus().setStatusType(status);
  this.fireSearchEvent();
}

/**
* Adds the action listener.
*
* @param listener
*          the listener
*/
public void addActionListener(ISearchListener listener) {
  if (this.listeners == null) {
    listeners = new ArrayList<ISearchListener>();
  }
  listeners.add(listener);
}

/**
* Removes the action listener.
*
* @param listener
*          the listener
*/
public void removeActionListener(ISearchListener listener) {
  if (listeners == null || listeners.size() < 1) {
    return;
  }
  listeners.remove(listener);

}

/**
* Fire search event.
*/
private void fireSearchEvent() {

  lockListenerEvent.lock();
  try {
    this.fireSearchEventWorker();
  } finally {
    lockListenerEvent.unlock();
  }
}

/**
* Fire search event worker.  Use fire search event.  This method does not
* have lockign and is called by fireSearchEvent;
*/
private void fireSearchEventWorker() {
  LOG.fine("Writing " + this.getSearchStatus().getStatusType()
      + " to listners time up = " + this.isTimeUp());
 
  if (this.isTimeUp() || listeners == null || listeners.size() < 1) {
    return;
  }
  DistributedSearchEvent event = new DistributedSearchEvent(this, this
      .getSearchStatus());
  for (ISearchListener listener : listeners) {
    try {
      listener.searchEvent(event);
    } catch (Exception e) {
      LOG.log(Level.WARNING, "Error in listener", e);
    }

  }
}

/**
* Runs the process.
*/
public void run() {
  try {
    setIsWorking(true);
    runWorker();
  } finally {
    if(countDownLatch != null) {
      countDownLatch.countDown();
    }
  }
}

/**
* Runs the thread process
*
*/
public void runWorker() {

 
  RequestContext rc = null;
  try {
      // rc = RequestContext.extract(this.getSearchContext().getHttpRequest());
    rc = this.getSearchContext().getRequestContext();
    RestQuery query = this.getSearchContext().getRestQuery();

    SearchStatus status = this.getSearchStatus();
    status.setStartTimestamp(new Timestamp(System.currentTimeMillis()));
  
    if (this.isTimeUp()) {
      throw new Exception("This thread has been stopped");
    }
    SearchResult result = new SearchResult();
    SearchCriteria criteria = this.getSearchContext().getSearchCriteria();
    ASearchEngine engine = this.getSearchEngine();
    engine.setRequestDefinition(new SearchRequestDefinition(criteria, result));
    engine.setHitsOnly(true);
    engine.setConnectionTimeoutMs(this.getMaxSearchTime());
    engine.setResponseTimeout(this.getMaxSearchTime());

    if (LOG.isLoggable(Level.FINER)) {
      LOG.finer("Starting SEARCH IN thread id= " + this.getId() + ", rid="
          + this.getRID());
    }
    if (this.rid.equalsIgnoreCase("local")) {
      GetRecordsGenerator grg = new GetRecordsGenerator(rc);
      if (engine.getHitsOnly()) {
        grg.setResultType("HITS");
      }
      String cswRequest = grg.generateCswRequest(query);
      SearchEngineCSW csw = (SearchEngineCSW) engine;
      if (this.isTimeUp()) {
        throw new Exception("This threads time is up");
      }
      csw.doSearch(cswRequest);
    } else {
      if (this.isTimeUp()) {
        throw new Exception("This threads time is up");
      }
      engine.doSearch();
    }
    if (LOG.isLoggable(Level.FINER)) {
      LOG.finer("ENDING SEARCH IN thread id= " + this.getId() + ", rid="
          + this.getRID());
    }
    status.setHitCount(result.getMaxQueryHits());
    this.getSearchStatus().setEndTimestamp(
        new Timestamp(System.currentTimeMillis()));
    this.writeStatus(SearchStatus.STATUSTYPE_COMPLETED);
   
  } catch (Exception e) {
    this.getSearchStatus().setMessage(e.getMessage());
    this.writeStatus(SearchStatus.STATUSTYPE_FAILED);
    LOG.log(Level.WARNING, "Error during distributed search", e);
  } finally {

    this.getSearchStatus().setEndTimestamp(
        new Timestamp(System.currentTimeMillis()));
    this.setIsWorking(false);

  }
}

}
TOP

Related Classes of com.esri.gpt.control.rest.search.SearchThread

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.