package org.intermine.webservice.server.output;

/*
 * Copyright (C) 2002-2011 FlyMine
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  See the LICENSE file for more
 * information or http://www.gnu.org/copyleft/lesser.html.
 *
 */

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.intermine.api.InterMineAPI;
import org.intermine.api.results.ExportResultsIterator;
import org.intermine.api.results.ResultElement;
import org.intermine.model.InterMineObject;
import org.intermine.pathquery.Path;
import org.intermine.web.logic.PortalHelper;
import org.json.JSONArray;
import org.json.JSONObject;

/**
 * @author Alexis Kalderimis
 *
 */
public class JSONRowIterator implements Iterator<JSONArray>
{

    private final ExportResultsIterator subIter;
    private final List<Path> viewPaths = new ArrayList<Path>();
    private final InterMineAPI im;

    private static final String CELL_KEY_URL = "url";
    private static final String CELL_KEY_VALUE = "value";
    private static final String CELL_KEY_CLASS = "class";
    private static final String CELL_KEY_ID = "id";

    /**
     * Constructor
     * @param it An ExportResultsIterator that will be used internally to process the data.
     * @param im A reference to the the API settings bundle.
     */
    public JSONRowIterator(ExportResultsIterator it, InterMineAPI im) {
        this.subIter = it;
        this.im = im;
        init();
    }

    private void init() {
        viewPaths.addAll(subIter.getViewPaths());
    }

    @Override
    public boolean hasNext() {
        return subIter.hasNext();
    }

    /**
     * Get the JSONObject that represents each cell in the results row
     * @param cell The result element with the data
     * @return A JSONObject
     */
    protected JSONObject makeCell(ResultElement cell) {
        Map<String, Object> mapping = new HashMap<String, Object>();
        if (cell == null || cell.getId() == null) {
            mapping.put(CELL_KEY_URL, null);
            mapping.put(CELL_KEY_VALUE, null);
        } else {
            String link = null;
            if (im.getLinkRedirector() != null) {
                link = im.getLinkRedirector().generateLink(im, (InterMineObject) cell.getObject());
            }
            if (link == null) {
                link = PortalHelper.generateReportPath(cell);
            }
            mapping.put(CELL_KEY_URL, link);
            mapping.put(CELL_KEY_CLASS, cell.getType());
            mapping.put(CELL_KEY_ID, cell.getId());
            mapping.put(CELL_KEY_VALUE, cell.getField());
        }
        JSONObject ret = new JSONObject(mapping);
        return ret;
    }

    @Override
    public JSONArray next() {
        List<ResultElement> row = subIter.next();
        List<Object> jsonRow = new ArrayList<Object>();
        for (int i = 0; i < row.size(); i++) {
            ResultElement re = row.get(i);
            jsonRow.add(makeCell(re));
        }
        JSONArray next = new JSONArray(jsonRow);
        return next;
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException("Remove is not supported for this implementation");
    }

}

@@ -372,34 +372,8 @@
 st;%0A
-import java.util.HashMap;%0A
 impo
@@ -421,30 +421,8 @@
 ist;
-%0Aimport java.util.Map;
 %0A%0Aim
@@ -587,166 +587,49 @@
 ine.
-model.InterMineObject;%0Aimport org.intermine.pathquery.Path;%0Aimport org.intermine.web.logic.PortalHelper;%0Aimport org.json.JSONArray;%0Aimport org.json.JSONObject
+pathquery.Path;%0Aimport org.json.JSONArray
 ;%0A%0A/
@@ -878,17 +878,16 @@
 API im;%0A
-%0A
     priv
@@ -894,216 +894,51 @@
 ate 
-static final String CELL_KEY_URL = %22url%22;%0A    private static final String CELL_KEY_VALUE = %22value%22;%0A    private static final String CELL_KEY_CLASS = %22class%22;%0A    private static final String CELL_KEY_ID = %22id%22
+final TableCellFormatter tableCellFormatter
 ;%0A%0A 
@@ -1241,24 +1241,86 @@
 is.im = im;%0A
+        this.tableCellFormatter = new TableCellFormatter(im);%0A
         init
@@ -1503,1064 +1503,8 @@
  %7D%0A%0A
-    /**%0A     * Get the JSONObject that represents each cell in the results row%0A     * @param cell The result element with the data%0A     * @return A JSONObject%0A     */%0A    protected JSONObject makeCell(ResultElement cell) %7B%0A        Map%3CString, Object%3E mapping = new HashMap%3CString, Object%3E();%0A        if (cell == null %7C%7C cell.getId() == null) %7B%0A            mapping.put(CELL_KEY_URL, null);%0A            mapping.put(CELL_KEY_VALUE, null);%0A        %7D else %7B%0A            String link = null;%0A            if (im.getLinkRedirector() != null) %7B%0A                link = im.getLinkRedirector().generateLink(im, (InterMineObject) cell.getObject());%0A            %7D%0A            if (link == null) %7B%0A                link = PortalHelper.generateReportPath(cell);%0A            %7D%0A            mapping.put(CELL_KEY_URL, link);%0A            mapping.put(CELL_KEY_CLASS, cell.getType());%0A            mapping.put(CELL_KEY_ID, cell.getId());%0A            mapping.put(CELL_KEY_VALUE, cell.getField());%0A        %7D%0A        JSONObject ret = new JSONObject(mapping);%0A        return ret;%0A    %7D%0A%0A
     
@@ -1767,16 +1767,33 @@
 add(
-mak
+tabl
 eCell
+Formatter.toJSON
 (re)

Refactor json cell formatting into own class