/*
* $Id: AlarmSearchHelper.java,v 1.7 2011/04/13 15:45:42 acaproni Exp $
*
* $Date: 2011/04/13 15:45:42 $
* $Revision: 1.7 $
* $Author: acaproni $
*
* Copyright CERN, All Rights Reserved.
*/
package cern.laser.client.impl.services.selection;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import javax.jms.Message;
import javax.jms.ObjectMessage;
import org.apache.log4j.Logger;
import org.omg.CORBA.ORB;
import alma.acs.container.ContainerServicesBase;
import alma.acs.logging.AcsLogger;
import alma.alarmsystem.CERNAlarmService;
import cern.cmw.mom.pubsub.ExceptionListener;
import cern.cmw.mom.pubsub.MOMException;
import cern.cmw.mom.pubsub.PubSubFactory;
import cern.cmw.mom.pubsub.Subscriber;
import cern.cmw.mom.pubsub.SubscriptionListener;
import cern.laser.client.LaserConnectionException;
import cern.laser.client.LaserException;
import cern.laser.client.LaserTimeOutException;
import cern.laser.client.data.Category;
import cern.laser.client.impl.common.AlarmServiceSingleton;
import cern.laser.client.impl.data.AlarmImpl;
import cern.laser.client.services.selection.AlarmSearchListener;
import cern.laser.client.services.selection.LaserSearchException;
import cern.laser.client.services.selection.Selection;
import cern.laser.util.UUIDGenerator;
/**
*
*
* @version $Revision: 1.7 $ $Date: 2011/04/13 15:45:42 $
* @author Katarina Sigerud
*/
class AlarmSearchHelper implements ExceptionListener {
private static final Logger LOGGER = Logger.getLogger(AlarmSearchHelper.class.getName());
private static final String LASER_SEARCH_PROPERTY = "LASER_SEARCH";
private static final long SEARCH_DELAY = 1000;
private static final long SEARCH_TIMEOUT = 60000;
private boolean searchFinished = false;
private long searchWaitTime = 0;
private Subscriber cmwSubscriber;
private String searchRootTopic;
private boolean cmwConnected = true;
private AlarmSearchListener searchListener;
private SubscriptionListener initialSearchListener;
// The AlarmService component
private CERNAlarmService m_laser;
//
// -- CONSTRUCTORS ------------------------------------------------
//
AlarmSearchHelper(AlarmSearchListener selectionListener, ORB orb, AcsLogger logger) throws LaserException {
this.searchListener = selectionListener;
try {
this.m_laser = AlarmServiceSingleton.getInstance(orb,logger);
} catch (Exception e) {
throw new LaserException("unable to setup initial selection", e);
}
}
//
// -- PUBLIC METHODS ----------------------------------------------
//
public void search(Selection selection, int nbOfRows) throws LaserConnectionException, LaserException,
LaserTimeOutException {
searchFinished(false);
String console_id = "";
String host_name = "";
try {
console_id = UUIDGenerator.getInstance().getUUID().toString();
host_name = InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
throw new LaserException("unable to get a unique id for the console : " + e.getMessage());
}
String init_topic = getSearchRootTopic() + "." + console_id;
long init_subscription;
try {
init_subscription = getSubscriber().subscribe(init_topic, getSearchListener(), null);
} catch (Exception e) {
throw new LaserException("unable to subscribe to topic " + init_topic + " : " + e.getMessage());
}
// activate the selection on the BT
Integer[] category_ids = getCategoryIds(selection);
String sql = buildSQLFilter(selection, nbOfRows);
try {
if (m_laser!=null) {
int[] cis = new int[category_ids.length];
for (int i = 0; i < category_ids.length; i++)
cis[i] = category_ids[i].intValue();
m_laser.search(cis, sql, console_id);
} else {
throw new NullPointerException("AlarmSystem component is null");
}
} catch (Exception e) {
throw new LaserException("unable to perform initial selection at host " + host_name + " : " + e.getMessage());
}
resetInitWaitTime();
waitForInit();
try {
// stop init subscription
getSubscriber().unSubscribe(init_subscription);
} catch (Exception e) {
// Intentionally left blank
}
}
public void resetSelection() throws LaserException {
try {
getSubscriber().unSubscribeAll();
} catch (Exception e) {
throw new LaserException("unable to unsubscribe all");
}
if (cmwSubscriber != null) {
cmwSubscriber.close();
cmwSubscriber = null;
}
}
//
// -- implements ExceptionListener ---------------------------------
//
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
public void onException(MOMException e) {
if (e.testException(MOMException.CONNECTION_LOST_EXCEPTION)) {
cmwConnected = false;
if (searchListener != null) {
searchListener.onSearchException(new LaserSearchException(
cern.laser.client.services.selection.LaserSelectionException.CONNECTION_DROPPED));
}
} else {
if (e.testException(MOMException.CONNECTION_RECOVERED_EXCEPTION)) {
cmwConnected = true;
if (searchListener != null) {
searchListener.onSearchException(new LaserSearchException(
cern.laser.client.services.selection.LaserSelectionException.CONNECTION_REESTABILISHED));
}
}
}
}
//
// -- PROTECTED METHODS -------------------------------------------
//
//
// -- PRIVATE METHODS ---------------------------------------------
//
private void waitForInit() {
while (!isSearchTimedOut()) {
try {
Thread.sleep(SEARCH_DELAY);
} catch (InterruptedException ie) {
}
if (isSearchFinished()) {
break;
}
increaseSearchWaitTime();
}
}
private String buildSQLFilter(Selection selection, int nbOfRows) {
String sql = selection.getFilterSelection().toSQLString();
StringBuffer buffer = null;
if (sql == null) {
buffer = new StringBuffer("");
} else {
buffer = new StringBuffer(sql);
buffer.append(" AND ");
}
buffer.append("rownum<=");
buffer.append(nbOfRows);
if (LOGGER.isDebugEnabled()) LOGGER.debug("sql " + buffer.toString());
return buffer.toString();
}
private synchronized void searchFinished(boolean value) {
searchFinished = value;
if (searchListener != null) {
searchListener.searchFinished();
}
if (cmwSubscriber != null) {
cmwSubscriber.close();
}
}
private synchronized boolean isSearchFinished() {
return searchFinished;
}
private synchronized void increaseSearchWaitTime() {
searchWaitTime += SEARCH_DELAY;
}
private void resetInitWaitTime() {
searchWaitTime = 0;
}
private boolean isSearchTimedOut() {
return searchWaitTime > SEARCH_TIMEOUT;
}
private String getSearchRootTopic() throws LaserException, LaserConnectionException {
if (searchRootTopic == null) {
try {
if (m_laser!=null) {
searchRootTopic = m_laser.getSearchRootTopic();
} else {
throw new NullPointerException("AlarmSystem component is null");
}
} catch (Exception e1) {
throw new LaserException("unable to find client root topic : " + e1.getMessage());
}
}
return searchRootTopic;
}
private SubscriptionListener getSearchListener() {
if (initialSearchListener == null) {
initialSearchListener = new SubscriptionListener() {
public void onMessage(Message msg) {
try {
if (searchListener != null) {
if (searchListener.isSearchCancelled()) {
LOGGER.info("search cancelled");
searchFinished(true);
} else {
try {
cern.laser.business.data.Alarm business_alarm = (cern.laser.business.data.Alarm) ((ObjectMessage) msg)
.getObject();
searchListener.onSearchAlarm(new AlarmImpl(business_alarm));
} catch (Exception e) {
LOGGER.warn("error on message : " + e.getMessage());
}
if (msg.propertyExists(LASER_SEARCH_PROPERTY)) {
searchFinished(true);
}
}
}
} catch (Exception e) {
LOGGER.warn("error on message : " + e.getMessage());
}
}
};
}
return initialSearchListener;
}
private Subscriber getSubscriber() throws LaserException {
try {
if (cmwSubscriber == null) {
cmwSubscriber = PubSubFactory.subscriber();
cmwSubscriber.setExceptionListener(this);
}
} catch (Exception e) {
throw new LaserException("unable to create the CMW subscriber", e);
}
return cmwSubscriber;
}
private Integer[] getCategoryIds(Selection selection) throws LaserConnectionException, LaserException {
Category[] categories = selection.getCategorySelection().list();
Collection category_ids = new ArrayList(categories.length);
for (int i = 0; i < categories.length; i++) {
category_ids.add(categories[i].getCategoryId());
}
return (Integer[]) category_ids.toArray(new Integer[category_ids.size()]);
}
}