/******************************************************************************* * ALMA - Atacama Large Millimeter Array * Copyright (c) ESO - European Southern Observatory, 2011 * (in the framework of the ALMA collaboration). * All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *******************************************************************************/ /** * @author Julio Araya (jaray[at]alumnos.inf.utfsm.cl) & * Nicolas Troncoso (ntroncos[at]alumnos.inf.utfsm.cl) **/ package cl.utfsm.samplingSystemUI.core; import java.util.concurrent.LinkedBlockingQueue; import java.util.logging.Level; import org.omg.CORBA.portable.IDLEntity; import org.omg.CosNaming.NamingContext; import org.omg.CosNotification.StructuredEvent; import alma.ACSErrTypeCommon.wrappers.AcsJGenericErrorEx; import alma.acs.container.ContainerServices; import alma.acs.nc.NCSubscriber; import alma.acsnc.EventDescription; import alma.acssamp.SampObjPackage.SampDataBlock; import alma.acssamp.SampObjPackage.SampDataBlockSeqHelper; final class NotificationChannelSuscription extends NCSubscriber<IDLEntity> { /** * Used for further processing the data received by this NC subscriber. */ private LinkedBlockingQueue<DataItem> cChannel = null; /** * Notifies the subscription to the channel service. * * @param channelName * The name of the channel. * @param cServices * Services of the container. * @param namingService * @throws alma.acs.exceptions.AcsJException */ public NotificationChannelSuscription(String channelName, ContainerServices services, NamingContext namingService) throws alma.acs.exceptions.AcsJException{ super(channelName, null, services, namingService, NotificationChannelSuscription.class.getSimpleName(), IDLEntity.class); try { // We subscribe to *all* events on this channel by using a generic subscription, // to make sure that server-side filtering does not remove any events. // Due to the non-standard processing in MyNCSubscriber, the generic callback should never be invoked. addGenericSubscription(new GenericCallback() { @Override public void receiveGeneric(Object event, EventDescription eventDescrip) { logger.warning("Unexpected event delivery to 'receiveGeneric' method."); } }); } catch (Exception e) { String msg = "Failed to subscribe to sampling events: "; AcsJGenericErrorEx ex2 = new AcsJGenericErrorEx(e); ex2.setErrorDesc(msg); throw ex2; } // Create a channel, or get if it already exists try { cChannel = ThreadCommunicator.getInstance().createChannel(channelName); } catch(IllegalArgumentException e) { cChannel = ThreadCommunicator.getInstance().getChannel(channelName); } logger.info("Starting notification channel " + channelName); } /** * Saves a log with information about time and value of the sampled data. * * @param stEvent A structured event. **/ public boolean push_structured_event_called(StructuredEvent stEvent) { try{ SampDataBlock[] sampledData = SampDataBlockSeqHelper.extract(stEvent.filterable_data[0].value); for (int i =0; i< sampledData.length; i++){ // extract the time stamp long timeOmg= sampledData[i].sampTime; // extract the value // Check if this is an int, double or float. Anyways, we return it as double org.omg.CORBA.Any sampVal = sampledData[i].sampVal; org.omg.CORBA.TCKind kind = sampledData[i].sampVal.type().kind(); double value = 0; switch(kind.value()) { case org.omg.CORBA.TCKind._tk_double: value=sampVal.extract_double(); break; case org.omg.CORBA.TCKind._tk_float: value=(double)sampVal.extract_float(); break; case org.omg.CORBA.TCKind._tk_long: value=(double)sampVal.extract_long(); break; default: throw new IllegalArgumentException("No matching type for incoming data: " + kind.value()); } saveSampledData(timeOmg, value); } } catch(Exception ex){ logger.log(Level.WARNING, "Failed to process SampDataBlockSeq event.", ex); } // Veto against further processing of this event, since we've done it already here in this non-standard way. return false; } /** * Returns the name of the channel. **/ public String getChannelName(){ return channelName; } private void saveSampledData(long time, double value){ if(cChannel==null){ logger.info("The channel name is not set"); return; } if(!cChannel.offer(new DataItem(time,value))) logger.info("Dropped data due to full queue"); } }