/** @author Attilio Mattiocco */ class GetStructureTask extends SwingWorker<Void, Void> { private static Logger logger = Configuration.getSdmxLogger(); private ProgressViewer progress = null; private Component parent = null; public GetStructureTask(ProgressViewer progress, Component parent) { super(); this.progress = progress; this.parent = parent; } @Override protected Void doInBackground() throws Exception { try { DefaultListModel dimListModel = new DefaultListModel(); List<Dimension> dims = SdmxClientHandler.getDimensions(QueryPanel.selectedProvider, QueryPanel.selectedDataflow); int i = 0; for (Iterator<Dimension> iterator = dims.iterator(); iterator.hasNext(); ) { Dimension dim = iterator.next(); dimListModel.add(i++, dim.getId()); } JList dimList = new JList(dimListModel); dimList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); dimList.addListSelectionListener(new DimensionSelectionListener(parent)); QueryPanel.dimensionsPane.getViewport().add(dimList); String query = QueryPanel.getSDMXQuery(); QueryPanel.sdmxQuery.setText(query); // initSelections(QueryPanel.selectedDataflow,dims); } catch (Exception ex) { logger.severe( "Exception. Class: " + ex.getClass().getName() + " .Message: " + ex.getMessage()); logger.log(Level.FINER, "", ex); } finally { progress.setVisible(false); } return null; } // private void initSelections(String dataflow, List<Dimension> dims){ // QueryPanel.selectedDataflow = dataflow; // QueryPanel.codeSelections = new LinkedHashMap<String, Object[]>(); // for (Iterator<Dimension> iterator = dims.iterator(); iterator.hasNext();) { // Dimension d = (Dimension) iterator.next(); // QueryPanel.codeSelections.put(d.getId(), new Object[0]); // } // QueryPanel.sdmxQuery.setText(QueryPanel.getSDMXQuery()); // } }
/** @author Attilio Mattiocco */ public class GenericDataParser { protected static Logger logger = Configuration.getSdmxLogger(); private static final String SERIES = "Series"; private static final String SERIES_KEY = "SeriesKey"; private static final String VALUE = "value"; private static final String CONCEPT = "concept"; private static final String OBS = "Obs"; private static final String OBS_TIME = "Time"; private static final String OBS_VALUE = "ObsValue"; private static final String ATTRIBUTES = "Attributes"; private static final String ATTRIBUTEVALUE = "Value"; public static List<PortableTimeSeries> parse( InputStreamReader xmlBuffer, DataFlowStructure dsd, String dataflow, boolean data) throws XMLStreamException, UnsupportedEncodingException, SdmxException { XMLInputFactory inputFactory = XMLInputFactory.newInstance(); BufferedReader br = skipBOM(xmlBuffer); XMLEventReader eventReader = inputFactory.createXMLEventReader(br); List<PortableTimeSeries> tsList = new ArrayList<PortableTimeSeries>(); PortableTimeSeries ts = null; while (eventReader.hasNext()) { XMLEvent event = eventReader.nextEvent(); logger.finest(event.toString()); if (event.isStartElement()) { StartElement startElement = event.asStartElement(); if (startElement.getName().getLocalPart() == (SERIES)) { ts = new PortableTimeSeries(); ts.setDataflow(dataflow); } if (startElement.getName().getLocalPart() == (SERIES_KEY)) { setSeriesKey(ts, eventReader, dsd); } if (startElement.getName().getLocalPart() == (ATTRIBUTES)) { setSeriesAttributes(ts, eventReader); } if (startElement.getName().getLocalPart() == (OBS) && data) { setSeriesSingleObs(ts, eventReader); } } if (event.isEndElement()) { EndElement endElement = event.asEndElement(); if (endElement.getName().getLocalPart() == (SERIES)) { tsList.add(ts); } } } return tsList; } private static void setSeriesKey( PortableTimeSeries ts, XMLEventReader eventReader, DataFlowStructure dsd) throws XMLStreamException { String id = null; String val = null; String[] dimensions = new String[dsd.getDimensions().size()]; while (eventReader.hasNext()) { XMLEvent event = eventReader.nextEvent(); logger.finest(event.toString()); if (event.isStartElement()) { StartElement startElement = event.asStartElement(); if (startElement.getName().getLocalPart().equalsIgnoreCase(VALUE)) { @SuppressWarnings("unchecked") Iterator<Attribute> attributes = startElement.getAttributes(); while (attributes.hasNext()) { Attribute attribute = attributes.next(); if (attribute.getName().toString().equalsIgnoreCase(CONCEPT)) { id = attribute.getValue(); } else if (attribute.getName().toString().equalsIgnoreCase(VALUE)) { val = attribute.getValue(); } } } } if (event.isEndElement()) { EndElement endElement = event.asEndElement(); if (endElement.getName().getLocalPart().equalsIgnoreCase(VALUE)) { if (dsd.isDimension(id)) { dimensions[dsd.getDimensionPosition(id) - 1] = id + "=" + val; } if (id.equalsIgnoreCase("FREQ") || id.equalsIgnoreCase("FREQUENCY")) { ts.setFrequency(val); } } } if (event.isEndElement()) { EndElement endElement = event.asEndElement(); if (endElement.getName().getLocalPart() == (SERIES_KEY)) { ts.setDimensions(Arrays.asList(dimensions)); break; } } } } private static void setSeriesAttributes(PortableTimeSeries ts, XMLEventReader eventReader) throws XMLStreamException { String id = null; String val = null; while (eventReader.hasNext()) { XMLEvent event = eventReader.nextEvent(); logger.finest(event.toString()); if (event.isStartElement()) { StartElement startElement = event.asStartElement(); if (startElement.getName().getLocalPart().equalsIgnoreCase(VALUE)) { @SuppressWarnings("unchecked") Iterator<Attribute> attributes = startElement.getAttributes(); while (attributes.hasNext()) { Attribute attribute = attributes.next(); if (attribute.getName().toString().equalsIgnoreCase(CONCEPT)) { id = attribute.getValue(); } else if (attribute.getName().toString().equalsIgnoreCase(VALUE)) { val = attribute.getValue(); } } } } if (event.isEndElement()) { EndElement endElement = event.asEndElement(); if (endElement.getName().getLocalPart().equalsIgnoreCase(VALUE)) { ts.addAttribute(id + '=' + val); } } if (event.isEndElement()) { EndElement endElement = event.asEndElement(); if (endElement.getName().getLocalPart() == (ATTRIBUTES)) { break; } } } } private static void setSeriesSingleObs(PortableTimeSeries ts, XMLEventReader eventReader) throws XMLStreamException { String time = null; String val = null; Hashtable<String, String> obs_attr = new Hashtable<String, String>(); while (eventReader.hasNext()) { XMLEvent event = eventReader.nextEvent(); logger.finest(event.toString()); if (event.isStartElement()) { StartElement startElement = event.asStartElement(); if (startElement.getName().getLocalPart() == (OBS_TIME)) { time = eventReader.getElementText(); } if (startElement.getName().getLocalPart() == (OBS_VALUE)) { val = startElement.getAttributeByName(new QName(VALUE)).getValue(); } if (startElement.getName().getLocalPart() == (ATTRIBUTEVALUE)) { String name = startElement.getAttributeByName(new QName(CONCEPT)).getValue(); String value = startElement.getAttributeByName(new QName(VALUE)).getValue(); obs_attr.put(name, value); } } if (event.isEndElement()) { EndElement endElement = event.asEndElement(); if (endElement.getName().getLocalPart() == (OBS)) { try { ts.addObservation(new Double(val), time, obs_attr); } catch (NumberFormatException e) { logger.warning( "Invalid observation: '" + val + "' for ts " + ts.getName() + ". Setting NaN."); ts.addObservation(new Double("NaN"), time, obs_attr); } break; } } } } // some 2.0 providers are apparently adding a BOM private static BufferedReader skipBOM(InputStreamReader xmlBuffer) throws SdmxException { BufferedReader br = new BufferedReader(xmlBuffer); logger.fine(xmlBuffer.getEncoding()); try { // java uses Unicode big endian char[] cbuf = new char[1]; br.mark(1); br.read(cbuf, 0, 1); logger.fine(String.format("0x%2s", Integer.toHexString(cbuf[0]))); if ((byte) cbuf[0] == (byte) 0xfeff) { logger.fine("BOM found and skipped"); } else { br.reset(); } } catch (IOException e) { throw new SdmxException("Error handling BOM for UTF8 response stream."); } return br; } }