com.novartis.opensource.yada.format.JSONResponse Maven / Gradle / Ivy
/**
* Copyright 2016 Novartis Institutes for BioMedical Research Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.novartis.opensource.yada.format;
import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.novartis.opensource.yada.YADAQueryConfigurationException;
import com.novartis.opensource.yada.YADAQueryResult;
import com.novartis.opensource.yada.YADARequest;
import com.novartis.opensource.yada.YADARequestException;
import com.novartis.opensource.yada.util.YADAUtils;
/**
*
* The default response for the framework, embedding results in a standard YADA JSON object and returning the object as a {@link String}
*
*
* Multi-query responses take the following form:
*
* {
* RESULTSETS: [
* RESULTSET: {
* ROWS: [
* {COL1.1:VAL1.1,...COL1.n:VAL1.n},
* ...
* {COLn.1:VALn.1,...COLn.n:VALs.n}
* ],
* qname: "...",
* total: "...",
* records: "...",
* page: "..."
* },
* RESULTSET: {
* ROWS: [
* {COL1.1:VAL1.1,...COL1.n:VAL1.n},
* ...
* {COLn.1:VALn.1,...COLn.n:VALs.n}
* ],
* qname: "...",
* total: "...",
* records: "...",
* page: "..."
* }
* ]
* }
*
*
*
* Single-query responses take the following form:
*
*
* {
* RESULTSET: {
* ROWS: [
* {COL1.1:VAL1.1,...COL1.n:VAL1.n},
* ...
* {COLn.1:VALn.1,...COLn.n:VALs.n}
* ],
* qname: "...",
* total: "...",
* records: "...",
* page: "..."s
* }
* }
*
* @author David Varon
*
*/
public class JSONResponse extends AbstractResponse {
/**
* Local logger handle
*/
@SuppressWarnings("unused")
private static Logger l = Logger.getLogger(JSONResponse.class);
/**
* The result to be returned by this class's {@link #toString()} method
*/
private JSONObject jsonResponse;
/**
* Default constructor, which creates the internal data structure for the response.
*/
public JSONResponse()
{
this.jsonResponse = new JSONObject();
}
/**
* Iterates over the results, appending each set as a JSONObject in the {@code ROWS} array.
* @throws YADAQueryConfigurationException when the {@link Response} spec in the request is malformed
* @see com.novartis.opensource.yada.format.AbstractResponse#compose(com.novartis.opensource.yada.YADAQueryResult[])
*/
@Override
public Response compose(YADAQueryResult[] yqrs) throws YADAResponseException, YADAConverterException, YADAQueryConfigurationException
{
setYADAQueryResults(yqrs);
create();
for(YADAQueryResult yqr : yqrs)
{
setYADAQueryResult(yqr);
// iterate over results
// at this point
if(yqr != null)
{
if(yqr.getResults() != null && yqr.getResults().size() > 0)
{
for(Object result : yqr.getResults())
{
if(result != null)
this.append(result); // should be a ResultSet
}
}
else if(yqr.getCountResults() != null && yqr.getCountResults().size() > 0)
{
for(Object result : yqr.getCountResults())
{
if(result != null)
this.append((Integer)result); // should be an Integer
}
}
}
}
//TODO there will be memory issues with multiple users and large result sets
//TODO implement a caching strategy for the format package
//TODO implement a server-level caching/queuing strategy to handle multi-user, large-request scenarios
// process converted headers into unique ordered Set
boolean join = this.yqr.hasJoin();
if(join)
{
JSONArray qname = new JSONArray();
JSONArray resultSets = this.jsonResponse.getJSONArray(RESULTSETS);
for(int i=0;i pagesize records. consider:
* resultSet 1 = 700, first 20 returned
* resultSet 2 = 400, first 20 returned
* What is on page 1, length 20, or change length to 50?
* Do resultSet 1 records by default always appear first?
* Does the algo return pagesize/number of queries from each resultSet?
* Should pagesize be divided by number of queries earlier in the process if
* harmonyMap is provided, i.e., pagesize = pagesize/number of queries
* -this would be wierd if there were pagesize=20, and 10 queries, 2 rows per
* query would be returned.
* Should a pagination handler be added, with options and a default? **probably this
*
* All these scenarios get wierder when page > 1 is involved, and sorting, filtering, etc.
* Some default behavior must be identified and implemented, then options can be whatever.
*/
int pagesize = Integer.parseInt(this.yqr.getYADAQueryParamValue(YADARequest.PS_PAGESIZE));
if(pagesize < existing.length())
{
rows = new JSONArray();
for(int i=0;i