← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 6914: Impl json view of report table data

 

------------------------------------------------------------
revno: 6914
committer: Lars Helge Overland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Fri 2012-05-11 21:04:25 +0200
message:
  Impl json view of report table data
removed:
  dhis-2/dhis-web/dhis-web-api/src/main/resources/templates/html/grid.xsl
added:
  dhis-2/dhis-support/dhis-support-system/src/main/resources/grid-html.vm
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/GridHeader.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/adapter/JacksonRowDataSerializer.java
  dhis-2/dhis-support/dhis-support-system/pom.xml
  dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/grid/GridUtils.java
  dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/grid/ListGrid.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/ReportTableController.java
  dhis-2/dhis-web/dhis-web-api/src/main/resources/templates/html/model2html.xsl
  dhis-2/dhis-web/dhis-web-api/src/main/resources/templates/html/reportTable.xsl


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/GridHeader.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/GridHeader.java	2012-04-26 07:56:54 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/GridHeader.java	2012-05-11 19:04:25 +0000
@@ -27,19 +27,17 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import java.util.Arrays;
+import java.util.List;
+
+import org.hisp.dhis.common.view.DetailedView;
+
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonView;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
-import org.hisp.dhis.common.view.DetailedView;
-
-import java.util.Arrays;
-import java.util.List;
 
 /**
  * @author Lars Helge Overland
  */
-@JacksonXmlRootElement( localName = "header", namespace = Dxf2Namespace.NAMESPACE )
 public class GridHeader
 {
     private static final List<String> NUMERIC_TYPES = Arrays.asList( Float.class.getName(), Double.class.getName(), Long.class.getName(), Integer.class.getName() );
@@ -97,7 +95,6 @@
 
     @JsonProperty
     @JsonView( {DetailedView.class} )
-    @JacksonXmlProperty( isAttribute = true )
     public String getName()
     {
         return name;
@@ -110,7 +107,6 @@
 
     @JsonProperty
     @JsonView( {DetailedView.class} )
-    @JacksonXmlProperty( namespace = Dxf2Namespace.NAMESPACE )
     public String getColumn()
     {
         return column;
@@ -123,7 +119,6 @@
 
     @JsonProperty
     @JsonView( {DetailedView.class} )
-    @JacksonXmlProperty( namespace = Dxf2Namespace.NAMESPACE )
     public String getType()
     {
         return type;
@@ -136,7 +131,6 @@
 
     @JsonProperty
     @JsonView( {DetailedView.class} )
-    @JacksonXmlProperty( namespace = Dxf2Namespace.NAMESPACE )
     public boolean isHidden()
     {
         return hidden;
@@ -149,7 +143,6 @@
 
     @JsonProperty
     @JsonView( {DetailedView.class} )
-    @JacksonXmlProperty( namespace = Dxf2Namespace.NAMESPACE )
     public boolean isMeta()
     {
         return meta;

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/adapter/JacksonRowDataSerializer.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/adapter/JacksonRowDataSerializer.java	2012-04-26 10:56:58 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/adapter/JacksonRowDataSerializer.java	2012-05-11 19:04:25 +0000
@@ -27,47 +27,38 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import java.io.IOException;
+import java.util.List;
+
 import com.fasterxml.jackson.core.JsonGenerator;
 import com.fasterxml.jackson.databind.JsonSerializer;
 import com.fasterxml.jackson.databind.SerializerProvider;
 
-import java.io.IOException;
-import java.util.List;
-
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
  */
 public class JacksonRowDataSerializer
     extends JsonSerializer<List<List<Object>>>
 {
-    private static final String ROW_NAME = "row";
-    private static final String FIELD_NAME = "field";
     private static final String EMPTY = "";
     
     @Override
     public void serialize( List<List<Object>> values, JsonGenerator jgen, SerializerProvider provider ) throws IOException
     {
-        boolean b = true;
-
-        for ( List<Object> value : values )
+        jgen.writeStartArray();
+        
+        for ( List<Object> row : values )
         {
-            if ( !b )
-            {
-                jgen.writeFieldName( ROW_NAME );
-            }
-
-            b = false;
-
-            jgen.writeStartObject();
-
-            for ( Object object : value )
-            {
-                object = object == null ? EMPTY : object;
-                    
-                jgen.writeStringField( FIELD_NAME, String.valueOf( object ) );
-            }
-
-            jgen.writeEndObject();
+            jgen.writeStartArray();
+            
+            for ( Object field : row )
+            {
+                jgen.writeString( field != null ? String.valueOf( field ) : EMPTY );
+            }
+            
+            jgen.writeEndArray();
         }
+        
+        jgen.writeEndArray();
     }
 }

=== modified file 'dhis-2/dhis-support/dhis-support-system/pom.xml'
--- dhis-2/dhis-support/dhis-support-system/pom.xml	2012-05-10 09:57:03 +0000
+++ dhis-2/dhis-support/dhis-support-system/pom.xml	2012-05-11 19:04:25 +0000
@@ -29,6 +29,10 @@
       <groupId>org.hisp.dhis</groupId>
       <artifactId>dhis-support-test</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.hisp.dhis</groupId>
+      <artifactId>dhis-support-xml</artifactId>
+    </dependency>
     
     <!-- JasperReports -->
 

=== modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/grid/GridUtils.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/grid/GridUtils.java	2012-03-09 11:46:58 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/grid/GridUtils.java	2012-05-11 19:04:25 +0000
@@ -59,6 +59,8 @@
 import net.sf.jasperreports.engine.JasperPrint;
 import net.sf.jasperreports.engine.JasperReport;
 
+import org.amplecode.staxwax.factory.XMLFactory;
+import org.amplecode.staxwax.writer.XMLWriter;
 import org.apache.commons.lang.StringUtils;
 import org.apache.velocity.VelocityContext;
 import org.hisp.dhis.common.Grid;
@@ -99,8 +101,25 @@
     private static final String KEY_GRID = "grid";
     private static final String KEY_ENCODER = "encoder";
     private static final String KEY_PARAMS = "params";
-    private static final String TEMPLATE = "grid.vm";
+    private static final String JASPER_TEMPLATE = "grid.vm";
+    private static final String HTML_TEMPLATE = "grid-html.vm";
 
+    private static final String ATTR_GRID = "grid";
+    private static final String ATTR_TITLE = "title";
+    private static final String ATTR_SUBTITLE = "subtitle";
+    private static final String ATTR_WIDTH = "width";
+    private static final String ATTR_HEIGHT = "height";
+    private static final String ATTR_HEADERS = "headers";
+    private static final String ATTR_HEADER = "header";
+    private static final String ATTR_NAME = "name";
+    private static final String ATTR_COLUMN = "column";
+    private static final String ATTR_TYPE = "type";
+    private static final String ATTR_HIDDEN = "hidden";
+    private static final String ATTR_META = "meta";
+    private static final String ATTR_ROWS = "rows";
+    private static final String ATTR_ROW = "row";
+    private static final String ATTR_FIELD = "field";
+    
     /**
      * Writes a PDF representation of the given Grid to the given OutputStream.
      */
@@ -321,7 +340,7 @@
         
         final StringWriter writer = new StringWriter();
         
-        render( grid, params, writer );
+        render( grid, params, writer, JASPER_TEMPLATE );
         
         String report = writer.toString();
 
@@ -338,9 +357,58 @@
     public static void toJrxml( Grid grid, Map<?, ?> params, Writer writer )
         throws Exception
     {
-        render( grid, params, writer );
+        render( grid, params, writer, JASPER_TEMPLATE );
     }
 
+    /**
+     * Writes a JRXML (Jasper Reports XML) representation of the given Grid to the given Writer.
+     */
+    public static void toHtml( Grid grid, Writer writer )
+        throws Exception
+    {
+        render( grid, null, writer, HTML_TEMPLATE );
+    }
+    
+    /**
+     * Writes an XML representation of the given Grid to the given OutputStream.
+     */
+    public static void toXml( Grid grid, OutputStream out )
+    {
+        XMLWriter writer = XMLFactory.getXMLWriter( out );
+        
+        writer.openDocument();
+        writer.openElement( ATTR_GRID, ATTR_TITLE, grid.getTitle(), ATTR_SUBTITLE, grid.getSubtitle(), 
+            ATTR_WIDTH, String.valueOf( grid.getWidth() ), ATTR_HEIGHT, String.valueOf( grid.getHeight() ) );
+        
+        writer.openElement( ATTR_HEADERS );
+        
+        for ( GridHeader header : grid.getHeaders() )
+        {
+            writer.writeElement( ATTR_HEADER, null, ATTR_NAME, header.getName(), ATTR_COLUMN, header.getColumn(), 
+                ATTR_TYPE, header.getType(), ATTR_HIDDEN, String.valueOf( header.isHidden() ), ATTR_META, String.valueOf( header.isMeta() ) ); 
+        }
+        
+        writer.closeElement();        
+        writer.openElement( ATTR_ROWS );
+        
+        for ( List<Object> row : grid.getRows() )
+        {
+            writer.openElement( ATTR_ROW );
+            
+            for ( Object field : row )
+            {
+                writer.writeElement( ATTR_FIELD, field != null ? String.valueOf( field ) : EMPTY );
+            }
+            
+            writer.closeElement();
+        }
+        
+        writer.closeElement();
+        writer.closeElement();
+        
+        writer.closeDocument();
+    }
+    
     // -------------------------------------------------------------------------
     // Supportive methods
     // -------------------------------------------------------------------------
@@ -348,7 +416,7 @@
     /**
      * Render using Velocity.
      */
-    private static void render( Grid grid, Map<?, ?> params, Writer writer )
+    private static void render( Grid grid, Map<?, ?> params, Writer writer, String template )
         throws Exception
     {
         final VelocityContext context = new VelocityContext();
@@ -357,7 +425,7 @@
         context.put( KEY_ENCODER, ENCODER );
         context.put( KEY_PARAMS, params );
         
-        new VelocityManager().getEngine().getTemplate( TEMPLATE ).merge( context, writer );
+        new VelocityManager().getEngine().getTemplate( template ).merge( context, writer );
     }
     
     /**

=== modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/grid/ListGrid.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/grid/ListGrid.java	2012-05-01 14:21:21 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/grid/ListGrid.java	2012-05-11 19:04:25 +0000
@@ -27,34 +27,36 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonView;
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import static org.hisp.dhis.system.util.MathUtils.getRounded;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 import net.sf.jasperreports.engine.JRException;
 import net.sf.jasperreports.engine.JRField;
+
 import org.apache.commons.math.stat.regression.SimpleRegression;
-import org.hisp.dhis.common.Dxf2Namespace;
 import org.hisp.dhis.common.Grid;
 import org.hisp.dhis.common.GridHeader;
 import org.hisp.dhis.common.adapter.JacksonRowDataSerializer;
 import org.hisp.dhis.common.view.DetailedView;
 import org.hisp.dhis.system.util.MathUtils;
 
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.util.*;
-
-import static org.hisp.dhis.system.util.MathUtils.getRounded;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonView;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 
 /**
  * @author Lars Helge Overland
  * @version $Id$
  */
-@JacksonXmlRootElement( localName = "grid", namespace = Dxf2Namespace.NAMESPACE )
 public class ListGrid
     implements Grid
 {
@@ -117,7 +119,6 @@
 
     @JsonProperty
     @JsonView( {DetailedView.class} )
-    @JacksonXmlProperty( namespace = Dxf2Namespace.NAMESPACE )
     public String getTitle()
     {
         return title;
@@ -132,7 +133,6 @@
 
     @JsonProperty
     @JsonView( {DetailedView.class} )
-    @JacksonXmlProperty( namespace = Dxf2Namespace.NAMESPACE )
     public String getSubtitle()
     {
         return subtitle;
@@ -147,7 +147,6 @@
 
     @JsonProperty
     @JsonView( {DetailedView.class} )
-    @JacksonXmlProperty( namespace = Dxf2Namespace.NAMESPACE )
     public String getTable()
     {
         return table;
@@ -171,8 +170,6 @@
 
     @JsonProperty
     @JsonView( {DetailedView.class} )
-    @JacksonXmlElementWrapper( localName = "headers", namespace = Dxf2Namespace.NAMESPACE )
-    @JacksonXmlProperty( localName = "header", namespace = Dxf2Namespace.NAMESPACE )
     public List<GridHeader> getHeaders()
     {
         return headers;
@@ -195,7 +192,6 @@
 
     @JsonProperty
     @JsonView( {DetailedView.class} )
-    @JacksonXmlProperty( namespace = Dxf2Namespace.NAMESPACE )
     public int getHeight()
     {
         return (grid != null && grid.size() > 0) ? grid.size() : 0;
@@ -203,7 +199,6 @@
 
     @JsonProperty
     @JsonView( {DetailedView.class} )
-    @JacksonXmlProperty( namespace = Dxf2Namespace.NAMESPACE )
     public int getWidth()
     {
         verifyGridState();
@@ -242,8 +237,6 @@
     @JsonProperty
     @JsonSerialize( using = JacksonRowDataSerializer.class )
     @JsonView( {DetailedView.class} )
-    @JacksonXmlElementWrapper( localName = "rows", namespace = Dxf2Namespace.NAMESPACE )
-    @JacksonXmlProperty( localName = "row", namespace = Dxf2Namespace.NAMESPACE )
     public List<List<Object>> getRows()
     {
         return grid;

=== added file 'dhis-2/dhis-support/dhis-support-system/src/main/resources/grid-html.vm'
--- dhis-2/dhis-support/dhis-support-system/src/main/resources/grid-html.vm	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/resources/grid-html.vm	2012-05-11 19:04:25 +0000
@@ -0,0 +1,39 @@
+<style type="text/css">
+.gridTable th, .gridTable td
+{
+  text-align: center;
+  width: 150px;
+  line-height: 170%;
+}
+</style>
+
+<h3>$!encoder.htmlEncode( $grid.title )</h3>
+
+<h4>$!encoder.htmlEncode( $grid.subtitle )</h4>
+
+<table class="listTable gridTable">
+
+<thead>
+<tr>
+#foreach( $header in $grid.getVisibleHeaders() )
+<th #if( $header.meta )style="text-align:left"#end>$!encoder.htmlEncode( $header.name )</th>
+#end
+</tr>
+</thead>
+
+<tbody>
+#foreach( $row in $grid.getVisibleRows() )
+<tr>
+#foreach( $col in $row )
+#set( $index = ( $velocityCount - 1 ) )
+#if( $grid.getVisibleHeaders().get( $index ).meta )
+<td style="text-align:left">$!encoder.htmlEncode( $col )</td>
+#else
+<td>$!encoder.htmlEncode( $col )</td>
+#end
+#end
+</tr>
+#end
+</tbody>
+
+</table>
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/ReportTableController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/ReportTableController.java	2012-04-25 20:43:17 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/ReportTableController.java	2012-05-11 19:04:25 +0000
@@ -163,6 +163,52 @@
         return "grid";
     }
 
+    @RequestMapping( value = "/{uid}/data.html", method = RequestMethod.GET )
+    public void getReportTableHtml( @PathVariable( "uid" ) String uid,
+                                   @RequestParam( value = "ou", required = false ) String organisationUnitUid,
+                                   @RequestParam( value = "pe", required = false ) String period,
+                                   HttpServletResponse response ) throws Exception
+    {
+        ReportTable reportTable = reportTableService.getReportTable( uid );
+
+        if ( organisationUnitUid == null && reportTable.hasReportParams() && reportTable.getReportParams().isOrganisationUnitSet() )
+        {
+            organisationUnitUid = organisationUnitService.getRootOrganisationUnits().iterator().next().getUid();
+        }
+
+        Date date = period != null ? DateUtils.getMediumDate( period ) : new Cal().now().subtract( Calendar.MONTH, 1 ).time();
+
+        Grid grid = reportTableService.getReportTableGrid( uid, i18nManager.getI18nFormat(), date, organisationUnitUid );
+
+        String filename = filenameEncode( grid.getTitle() ) + ".html";
+        contextUtils.configureResponse( response, ContextUtils.CONTENT_TYPE_HTML, CacheStrategy.RESPECT_SYSTEM_SETTING, filename, false );
+
+        GridUtils.toHtml( grid, response.getWriter() );
+    }
+
+    @RequestMapping( value = "/{uid}/data.xml", method = RequestMethod.GET )
+    public void getReportTableXml( @PathVariable( "uid" ) String uid,
+                                   @RequestParam( value = "ou", required = false ) String organisationUnitUid,
+                                   @RequestParam( value = "pe", required = false ) String period,
+                                   HttpServletResponse response ) throws Exception
+    {
+        ReportTable reportTable = reportTableService.getReportTable( uid );
+
+        if ( organisationUnitUid == null && reportTable.hasReportParams() && reportTable.getReportParams().isOrganisationUnitSet() )
+        {
+            organisationUnitUid = organisationUnitService.getRootOrganisationUnits().iterator().next().getUid();
+        }
+
+        Date date = period != null ? DateUtils.getMediumDate( period ) : new Cal().now().subtract( Calendar.MONTH, 1 ).time();
+
+        Grid grid = reportTableService.getReportTableGrid( uid, i18nManager.getI18nFormat(), date, organisationUnitUid );
+
+        String filename = filenameEncode( grid.getTitle() ) + ".xml";
+        contextUtils.configureResponse( response, ContextUtils.CONTENT_TYPE_XML, CacheStrategy.RESPECT_SYSTEM_SETTING, filename, false );
+
+        GridUtils.toXml( grid, response.getOutputStream() );
+    }
+
     @RequestMapping( value = "/{uid}/data.pdf", method = RequestMethod.GET )
     public void getReportTablePdf( @PathVariable( "uid" ) String uid,
                                    @RequestParam( value = "ou", required = false ) String organisationUnitUid,

=== removed file 'dhis-2/dhis-web/dhis-web-api/src/main/resources/templates/html/grid.xsl'
--- dhis-2/dhis-web/dhis-web-api/src/main/resources/templates/html/grid.xsl	2012-04-26 07:56:54 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/resources/templates/html/grid.xsl	1970-01-01 00:00:00 +0000
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.0"
-                xmlns="http://www.w3.org/1999/xhtml";
-                xmlns:d="http://dhis2.org/schema/dxf/2.0";
-    >
-
-  <xsl:template match="d:header">
-	<th> <xsl:value-of select="@name"/> </th>
-  </xsl:template>
-  
-  <xsl:template match="d:rows">
-	<xsl:apply-templates select="d:row"/>
-  </xsl:template>
-  
-  <xsl:template match="d:row">
-	<tr>
-	  <xsl:for-each select="d:field">
-		<td> <xsl:value-of select="."/> </td>
-	  </xsl:for-each>
-	</tr>
-  </xsl:template>
-	
-  <xsl:template match="d:grid">
-    <div class="grid">
-	  <h2>
-        <xsl:value-of select="d:title"/>
-      </h2>
-	  <h4>
-		<xsl:value-of select="d:subtitle"/>
-	  </h4>
-	  <table>
-		<thead>
-		  <tr>
-			<xsl:apply-templates select="d:headers"/>
-		  </tr>
-		</thead>
-		<tbody>
-		  <xsl:apply-templates select="d:rows"/>
-		</tbody>
-	  </table>	  
-	</div>
-  </xsl:template>
-
-</xsl:stylesheet>

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/resources/templates/html/model2html.xsl'
--- dhis-2/dhis-web/dhis-web-api/src/main/resources/templates/html/model2html.xsl	2012-05-01 09:53:59 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/resources/templates/html/model2html.xsl	2012-05-11 19:04:25 +0000
@@ -48,7 +48,6 @@
   <xsl:include href="userGroup.xsl" />
   <xsl:include href="userAuthorityGroup.xsl" />
   <xsl:include href="userCredentials.xsl" />
-  <xsl:include href="grid.xsl" />
   <xsl:include href="messageConversations.xsl" />
   <xsl:include href="messageConversation.xsl" />
   <xsl:include href="dataValueSets.xsl" />

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/resources/templates/html/reportTable.xsl'
--- dhis-2/dhis-web/dhis-web-api/src/main/resources/templates/html/reportTable.xsl	2012-04-26 08:33:26 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/resources/templates/html/reportTable.xsl	2012-05-11 19:04:25 +0000
@@ -11,8 +11,9 @@
 	  <table>
 		<tr>
 			<td>Resource Data</td>
-			<td><a href="{@link}/data">html</a></td>
+			<td><a href="{@link}/data.html">html</a></td>
 			<td><a href="{@link}/data.xml">xml</a></td>
+			<td><a href="{@link}/data.json">json</a></td>
 			<td><a href="{@link}/data.pdf">pdf</a></td>
 			<td><a href="{@link}/data.xls">xls</a></td>
 			<td><a href="{@link}/data.csv">csv</a></td>