=== added file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/adx/ADXConstants.java' --- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/adx/ADXConstants.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/adx/ADXConstants.java 2015-06-18 12:42:19 +0000 @@ -0,0 +1,67 @@ +package org.hisp.dhis.dxf2.adx; + +/* + * Copyright (c) 2004-2015, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * + * @author bobj + */ +public class ADXConstants +{ + //-------------------------------------------------------------------------- + // These are defined in the ADX standard + //-------------------------------------------------------------------------- + + public static final String NAMESPACE = "urn:ihe:qrph:adx:2015"; + + public static final String ROOT = "adx"; + + public static final String GROUP = "group"; + + public static final String PERIOD = "period"; + + public static final String ORGUNIT = "orgUnit"; + + public static final String DATAELEMENT = "dataelement"; + + public static final String DATAVALUE = "dataValue"; + + public static final String VALUE = "value"; + + public static final String ANNOTATION = "annotation"; + + //-------------------------------------------------------------------------- + // DHIS2 specific + //-------------------------------------------------------------------------- + + public static final String CATOPTCOMBO = "categoryOptionCombo"; + + public static final String ATTOPTCOMBO = "attributeOptionCombo"; + +} === added file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/adx/ADXDataService.java' --- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/adx/ADXDataService.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/adx/ADXDataService.java 2015-06-18 12:42:19 +0000 @@ -0,0 +1,59 @@ +package org.hisp.dhis.dxf2.adx; + +/* + * Copyright (c) 2004-2015, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import org.hisp.dhis.dxf2.common.ImportOptions; +import org.hisp.dhis.dxf2.datavalueset.DataExportParams; +import org.hisp.dhis.dxf2.importsummary.ImportSummaries; + +/** + * + * @author bobj + */ +public interface ADXDataService +{ + + /** + * postData + * + * Takes ADX Data from input stream and saves a series of DXF2 DataValueSets + * + * @param in The InputStream - typically from servlet http response + * @param importOptions The importOptions - typically from the servlet request + * @return an ImportSummaries collection of ImportSummary for each DataValueSet + * @throws IOException + */ + ImportSummaries postData( InputStream in, ImportOptions importOptions ) + throws IOException; + + void getData( DataExportParams params, OutputStream out ); +} === added file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/adx/DefaultADXDataService.java' --- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/adx/DefaultADXDataService.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/adx/DefaultADXDataService.java 2015-06-18 12:42:19 +0000 @@ -0,0 +1,184 @@ +package org.hisp.dhis.dxf2.adx; + +/* + * Copyright (c) 2004-2015, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.StringWriter; +import java.util.HashMap; +import java.util.Map; +import org.apache.commons.io.IOUtils; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import org.w3c.dom.Document; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import javax.xml.stream.XMLStreamException; +import org.amplecode.staxwax.factory.XMLFactory; +import org.hisp.dhis.dxf2.common.ImportOptions; +import org.hisp.dhis.dxf2.datavalueset.DataExportParams; +import org.hisp.dhis.dxf2.datavalueset.DataValueSetService; +import org.hisp.dhis.dxf2.importsummary.ImportSummaries; +import org.amplecode.staxwax.reader.XMLReader; +import javax.xml.stream.XMLStreamReader; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import org.hisp.dhis.dxf2.importsummary.ImportStatus; +import org.hisp.dhis.dxf2.importsummary.ImportSummary; +import org.hisp.dhis.period.Period; +import org.w3c.dom.Element; + +/** + * + * @author bobj + */ +public class DefaultADXDataService + implements ADXDataService +{ + + protected DataValueSetService dataValueSetService; + + @Override + public void getData( DataExportParams params, OutputStream out ) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + @Override + public ImportSummaries postData( InputStream in, ImportOptions importOptions ) + throws IOException + { + + XMLReader reader = XMLFactory.getXMLReader( in ); + + ImportSummaries importSummaries = new ImportSummaries(); + + reader.moveToStartElement( ADXConstants.ROOT, ADXConstants.NAMESPACE ); + + while ( reader.moveToStartElement( ADXConstants.GROUP, ADXConstants.NAMESPACE ) ) + { + DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder; + try + { + docBuilder = docFactory.newDocumentBuilder(); + Document dxf = docBuilder.newDocument(); + + // buld a dxf2 datavalueset document from each adx group + parseADXGroupToDxf( reader, dxf ); + + // write the document to String + DOMSource source = new DOMSource( dxf ); + StringWriter writer = new StringWriter(); + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + + StreamResult result = new StreamResult(writer); + transformer.transform( source, result ); + // create an inputstream for the String + InputStream dxfIn = IOUtils.toInputStream(result.toString(), "UTF-8" ); + + // pass off to the dxf2 datavalueset service + importSummaries.addImportSummary( dataValueSetService.saveDataValueSet( dxfIn, importOptions ) ); + } catch ( Exception ex ) + { + ImportSummary importSummary = new ImportSummary(); + importSummary.setStatus( ImportStatus.ERROR ); + importSummary.setDescription( "Exception: " + ex.getMessage() ); + importSummaries.addImportSummary( importSummary ); + Logger.getLogger( DefaultADXDataService.class.getName() ).log( Level.SEVERE, null, ex ); + } + } + + return importSummaries; + } + + protected void parseADXGroupToDxf( XMLReader reader, Document dxf ) throws XMLStreamException + { + Element root = dxf.createElementNS( "http://dhis2.org/schema/dxf/2.0", "dataValueSet" ); + + Map groupAttributes = readAttributes( reader ); + + String periodStr = groupAttributes.get( ADXConstants.PERIOD ); + groupAttributes.remove( ADXConstants.PERIOD ); + + Period period = ADXPeriod.parse( periodStr ); + root.setAttribute( "period", period.getIsoDate() ); + // pass through the remaining attributes to dxf + for ( String attribute : groupAttributes.keySet() ) + { + root.setAttribute( attribute, groupAttributes.get( attribute ) ); + } + + dxf.appendChild( root ); + + while ( reader.moveToStartElement( ADXConstants.DATAVALUE, ADXConstants.GROUP ) ) + { + parseADXDataValueToDxf( reader, dxf ); + } + } + + protected void parseADXDataValueToDxf( XMLReader reader, Document dxf ) throws XMLStreamException + { + Element dv = dxf.createElementNS( "http://dhis2.org/schema/dxf/2.0","dataValue"); + + Map groupAttributes = readAttributes( reader ); + + // pass through the remaining attributes to dxf + for ( String attribute : groupAttributes.keySet() ) + { + dv.setAttribute( attribute, groupAttributes.get( attribute ) ); + } + dxf.getFirstChild().appendChild( dv ); + } + + // TODO this should really be part of staxwax library + protected Map readAttributes( XMLReader staxWaxReader ) throws XMLStreamException + { + Map attributes = new HashMap<>(); + + XMLStreamReader reader = staxWaxReader.getXmlStreamReader(); + + if ( reader.getEventType() != START_ELEMENT ) + { + throw new IllegalArgumentException( "Trying to retrieve attributes from non START_ELEMENT node" ); + } + + // Read attributes + for ( int i = 0; i < reader.getAttributeCount(); i++ ) + { + attributes.put( reader.getAttributeLocalName( i ), reader.getAttributeValue( i ) ); + } + return attributes; + } +} === added file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/adx/DefaultADXDataServiceTest.java' --- dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/adx/DefaultADXDataServiceTest.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/adx/DefaultADXDataServiceTest.java 2015-06-18 12:42:19 +0000 @@ -0,0 +1,122 @@ +package org.hisp.dhis.dxf2.adx; + +/* + * Copyright (c) 2004-2015, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.io.IOException; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import org.amplecode.staxwax.factory.XMLFactory; +import org.amplecode.staxwax.reader.XMLReader; +import org.junit.After; +import org.junit.AfterClass; +import static org.junit.Assert.fail; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.core.io.ClassPathResource; +import org.w3c.dom.Document; + +/** + * + * @author bobj + */ +public class DefaultADXDataServiceTest +{ + + protected static final String SIMPLE_ADX_SAMPLE = "adx/adx_data_sample1.xml"; + + public DefaultADXDataServiceTest() + { + } + + @BeforeClass + public static void setUpClass() + { + } + + @AfterClass + public static void tearDownClass() + { + } + + @Before + public void setUp() throws IOException + { + } + + @After + public void tearDown() + { + } + + /** + * Test of parseADXGroup method, of class DefaultADXDataService. + */ + @Test + public void testParseADXGroup() throws Exception + { + try + { + System.out.println( "parseADXGroup" ); + XMLReader reader = XMLFactory.getXMLReader( new ClassPathResource( SIMPLE_ADX_SAMPLE ).getInputStream() ); + reader.moveToStartElement( ADXConstants.ROOT, ADXConstants.NAMESPACE ); + System.out.println( "Parsing adx, exported: " + reader.getAttributeValue( "exported" ) ); + + DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder; + docBuilder = docFactory.newDocumentBuilder(); + + DefaultADXDataService instance = new DefaultADXDataService(); + + while ( reader.moveToStartElement( ADXConstants.GROUP, ADXConstants.NAMESPACE ) ) + { + System.out.println( "Parsing new group" ); + Document dxf = docBuilder.newDocument(); + instance.parseADXGroupToDxf( reader, dxf ); + + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + DOMSource source = new DOMSource( dxf ); + StreamResult result = new StreamResult( System.out ); + + transformer.transform( source, result ); + System.out.println(); + } + } + catch ( Exception ex ) + { + fail( ex.toString() ); + } + } + +} === added directory 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/adx' === added file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/adx/adx_data_sample1.xml' --- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/adx/adx_data_sample1.xml 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/adx/adx_data_sample1.xml 2015-06-18 12:42:19 +0000 @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + Some qualifying text here on the datavalue + + + + + + + + === added file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/adx/adx_data_sample2.xml' --- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/adx/adx_data_sample2.xml 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/adx/adx_data_sample2.xml 2015-06-18 12:42:19 +0000 @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + Some qualifying text here on the datavalue + + + + + + +