/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.das2.qstream.filter; import java.nio.ByteBuffer; import java.text.ParseException; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.das2.qds.DDataSet; import org.das2.qds.DataSetUtil; import org.das2.qds.MutablePropertyDataSet; import org.das2.qds.QDataSet; import org.das2.qstream.PacketDescriptor; import org.das2.qstream.PlaneDescriptor; import org.das2.qstream.SerializeDelegate; import org.das2.qstream.SerializeRegistry; import org.das2.qstream.StreamComment; import org.das2.qstream.StreamDescriptor; import org.das2.qstream.StreamException; import org.das2.qstream.StreamHandler; import org.das2.qstream.TransferType; import org.das2.qstream.Util; import org.das2.qstream.XMLSerializeDelegate; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * Use this to promote the abstraction of the stream to QDataSets. This was * introduced when it became clear that to introduce an FFT filter would be * quite difficult with the StreamHandler interface. For example, take a simple * rank 2 spectrogram. The DEPEND_1 tags can be encoded inline, or as a single * packet. It would be burdensome to have to handle both cases. * * @author jbf */ public class QDataSetsFilter implements StreamHandler { protected static final Logger logger= Logger.getLogger("qstream"); /** * implement this to receive QDataSets packet-by-packet. */ public static class QDataSetSink implements StreamHandler { @Override public void streamDescriptor(StreamDescriptor sd) throws StreamException { } @Override public void packetDescriptor(PacketDescriptor pd) throws StreamException { } @Override public void packet(PacketDescriptor pd, ByteBuffer data) throws StreamException { } @Override public void streamClosed(StreamDescriptor sd) throws StreamException { } @Override public void streamException(StreamException se) throws StreamException { } @Override public void streamComment(StreamComment se) throws StreamException { } /** * QDataSets or parts of datasets as they come in. * @param sd * @param ds */ public void packetData( PacketDescriptor pd, PlaneDescriptor pld, QDataSet ds ) { } } /** * send packets on to here */ QDataSetSink sink; Map> propsn= new HashMap(); /** * * @param n node containing properties * @param props map to insert properties, or null. */ private static Map doProps( Node n, Map props ) { if ( props==null ) { props= new LinkedHashMap(); } if ( n==null ) return props; XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); try { NodeList odims = (NodeList) xpath.evaluate("property", n, XPathConstants.NODESET ); for (int j = 0; j < odims.getLength(); j++) { Element n2 = (Element) odims.item(j); String pname = n2.getAttribute("name"); if ( pname.equals(QDataSet.USER_PROPERTIES) ) { //System.err.println("ehre"); } String svalue; if ( n2.hasAttribute("value") ){ svalue= n2.getAttribute("value"); } else { svalue= n2.getTextContent(); } Element evalue=null; String stype; if ( n2.hasAttribute("type") ) { stype = n2.getAttribute("type"); } else { evalue= Util.singletonChildElement(n2); stype= evalue.getTagName(); } if (stype.equals("qdataset")) { //The QStream has these as Strings, which need to be converted to //if (pname.equals(QDataSet.DELTA_MINUS) || pname.equals(QDataSet.DELTA_PLUS) ) { // System.err.println("skipping DELTA_MINUS and DELTA_PLUS because bug"); // continue; //} //props.put(pname, svalue); if ( pname.equals(QDataSet.DEPEND_0) ) { props.put( QDataSet.DEPENDNAME_0, svalue ); } } else { SerializeDelegate delegate = SerializeRegistry.getByName(stype); if (delegate == null) { logger.log(Level.SEVERE, "!!! No delegate found for \"{0}\"", stype); // chris and I didn't see this invisible message continue; } Object oval; try { if ( evalue!=null && delegate instanceof XMLSerializeDelegate ) { oval= ((XMLSerializeDelegate)delegate).xmlParse(evalue); } else { oval= delegate.parse(stype, svalue); } props.put(pname, oval); } catch (ParseException ex) { logger.log(Level.SEVERE, ex.getMessage(), ex); } } } } catch ( XPathExpressionException ex ) { logger.log( Level.SEVERE, ex.getMessage(), ex ); } return props; } @Override public void streamDescriptor(StreamDescriptor sd) throws StreamException { sink.streamDescriptor(sd); } @Override public void packetDescriptor(PacketDescriptor pd) throws StreamException { sink.packetDescriptor(pd); Element ele= pd.getDomElement(); XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); XPathExpression exprv; XPathExpression exprp; try { NodeList odims = (NodeList) xpath.evaluate("/packet/qdataset", ele, XPathConstants.NODESET ); List pds= pd.getPlanes(); for (int j = 0; j < odims.getLength(); j++) { Element ds= (Element)odims.item(j); exprp= xpath.compile( "properties" ); //exprp= xpath.compile( "properties" ); Node nprops= (Node) exprp.evaluate( ds, XPathConstants.NODE ); Map props= doProps( nprops, null ); String id= ds.getAttribute("id"); propsn.put( id, props ); exprv= xpath.compile("values/@values"); Node values= (Node) exprv.evaluate( ds, XPathConstants.NODE ); if ( values!=null ) { PlaneDescriptor planed= pds.get(j); //exprv= xpath.compile("values/@length"); String svalues= values.getTextContent(); String[] ss= svalues.split(","); double[] dd= new double[ss.length]; for ( int i=0; i props= propsn.get( planed.getName() ); if ( props!=null ) DataSetUtil.putProperties( props, ds ); //j++; //} catch ( XPathExpressionException ex ) { // logger.log( Level.SEVERE, "packet", ex ); //} sink.packetData( pd, planed, ds ); } } @Override public void streamClosed(StreamDescriptor sd) throws StreamException { sink.streamClosed(sd); } @Override public void streamException(StreamException se) throws StreamException { sink.streamException(se); } @Override public void streamComment(StreamComment se) throws StreamException { sink.streamComment(se); } public void setSink( QDataSetSink sink ) { this.sink= sink; } // public static void main( String[] args ) throws IOException, StreamException, Exception { // //File f = new File( "/home/jbf/data.nobackup/qds/waveformTable.qds" ); // File f = new File( "/home/jbf/data.nobackup/qds/waveformTable2.qds" ); // // InputStream in = new FileInputStream(f); // // QDataSetsFilter filter= new QDataSetsFilter(); // // filter.sink= new QDataSetsFilter.QDataSetSink() { // // @Override // public void packetData(PacketDescriptor pd, PlaneDescriptor pld, QDataSet ds) { // System.err.println( "From "+pld.getName() + ": " + ds ); // } // // }; // // StreamTool.readStream( Channels.newChannel(in), filter ); // //StreamTool.readStream( Channels.newChannel(in), handler ); // test without filter. // // } }