Commit 8e00d71e authored by Eirik Alvær's avatar Eirik Alvær
Browse files

Merge remote-tracking branch 'remotes/origin/master' into tabulate-data-as-object

Conflicts:
	src/main/java/com/nesstar/rest/resources/CubeResource.java
parents bce7cbc9 b5aed346
......@@ -38,6 +38,17 @@
<artifactId>jetty-servlets</artifactId>
<version>8.1.10.v20130312</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
</dependency>
</dependencies>
<properties>
......
......@@ -182,7 +182,7 @@ public class CubeResource extends AbstractResource{
private int getDecimalsForMeasure(Measure measure) throws NotAuthorizedException, IOException {
int decimals = 0;
if (measure.getMetadataMap().containsKey("decimals")) {
decimals = (Integer)(measure.getMetadataMap().get("decimals"));
decimals = (Integer)measure.getMetadataMap().get("decimals");
}
return decimals;
}
......
package com.nesstar.rest.result_object_makers;
import com.nesstar.api.NotAuthorizedException;
import com.nesstar.api.Study;
import com.nesstar.api.*;
import com.nesstar.rest.common.DdiUtils;
import com.nesstar.rest.common.MissingResourceException;
import com.nesstar.rest.common.ResourceExtractor;
import com.nesstar.api.Server;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
......@@ -26,57 +24,22 @@ public final class MetadataMaker {
public static Object getStudyMetadata(Study study) throws Exception {
JSONObject destination = getJSONObjectFromFile("AllStudyMetadataSkeleton.json");
JSONObject source = XmlBasedObjectMaker.getJsonObject(study.getDDI());
copyJSONData(source.opt("codeBook"), destination.getJSONObject(DATA_ENVELOPE_NAME));
copyJSONData(study, destination.getJSONObject(DATA_ENVELOPE_NAME));
return destination.toString();
}
public static Object getVariableMetadata(String variableId, Server server) throws Exception {
JSONObject variableSource = getVariableObject(variableId, server);
Variable variable = getVariableObject(variableId, server);
JSONObject destination = getJSONObjectFromFile("VariableMetadataSkeleton.json");
copyJSONData(variableSource, destination.getJSONObject(DATA_ENVELOPE_NAME));
copyJSONData(variable, destination.getJSONObject(DATA_ENVELOPE_NAME));
DdiList<Category> categories = variable.getCategories();
destination.append("catgry", VariableMetadataMaker.getCategories(categories));
return destination.toString();
}
private static JSONObject getVariableObject(String variableId, Server server) throws Exception {
String[] ids = variableId.split("_");
String studyId = ids[0];
String shortVariableId = ids[1];
Study study = ResourceExtractor.getStudy(studyId, server);
JSONObject studyObject = XmlBasedObjectMaker.getJsonObject(study.getDDI());
JSONObject variableObject = getVariableObject(studyObject, shortVariableId);
if (variableObject == null) {
throw new MissingResourceException("Can't find variable: " + variableId);
}
return variableObject;
}
private static JSONObject getVariableObject(JSONObject studyObject, String shortVariableId) {
JSONObject variableObject = null;
try {
Object varObject = studyObject.getJSONObject("codeBook").getJSONObject("dataDscr").get("var");
if (varObject instanceof JSONArray) {
JSONArray vars = (JSONArray) varObject;
for (int i = 0; i < vars.length(); i++) {
JSONObject var = vars.getJSONObject(i);
if (shortVariableId.equals(var.get("ID"))) {
variableObject = var;
}
}
}
else {
JSONObject var = (JSONObject) varObject;
if (shortVariableId.equals(var.get("ID"))) {
variableObject = var;
}
}
}
catch (Exception e) {
return null;
}
return variableObject;
private static Variable getVariableObject(String variableId, Server server) throws Exception {
Bank<Variable> bank = server.getBank(Variable.class);
return bank.get(variableId);
}
private static JSONObject getJSONObjectFromFile(String fileName) throws IOException, JSONException {
......@@ -88,77 +51,49 @@ public final class MetadataMaker {
return new JSONObject(jsonObjectString);
}
private static void copyJSONData(Object source, JSONObject destination) throws JSONException {
private static void copyJSONData(ComplexDdiElement source, JSONObject destination) throws JSONException, IOException, XPathExpressionException, NotAuthorizedException {
Iterator it = destination.keys();
while (it.hasNext()) {
String key = it.next().toString();
Object destinationValue = destination.get(key);
Object sourceValue = getValue(source, key);
if (destinationValue instanceof JSONObject) {
copyJSONData(sourceValue, (JSONObject) destinationValue);
}
else if (destinationValue instanceof JSONArray) {
Object destinationArrayItemSkeleton = ((JSONArray) destinationValue).get(0);
if (destinationArrayItemSkeleton.toString().equals("this_object")) {
destinationArrayItemSkeleton = destination;
}
JSONArray destinationArray = new JSONArray();
copyJSONData(sourceValue, destinationArray, destinationArrayItemSkeleton);
destination.put(key, destinationArray);
}
else if (isSimpleValue(destinationValue)) {
String stringValue = "";
if (sourceValue != null && isSimpleValue(sourceValue)) {
stringValue = sourceValue.toString();
}
else if ("content".equals(key) && isSimpleValue(source)) {
stringValue = source.toString();
copyJSONData(source, (JSONObject) destinationValue);
} else if (destinationValue instanceof JSONArray) {
JSONArray jsonArray = (JSONArray) destinationValue;
for (int i = 0; i < jsonArray.length(); i++) {
Object obj = jsonArray.get(i);
if (obj instanceof JSONObject) {
copyJSONData(source, (JSONObject)obj);
} else {
insertValue(source, destination, key, destinationValue);
}
}
destination.put(key, stringValue);
} else {
insertValue(source, destination, key, destinationValue);
}
}
}
private static boolean isSimpleValue(Object object) {
return object instanceof String || object instanceof Number;
}
private static Object getValue(Object source, String key) {
if (source instanceof JSONObject) {
return ((JSONObject) source).opt(key);
}
else {
return null;
}
}
private static void copyJSONData(Object source, JSONArray destinationArray, Object destinationArrayItemSkeleton) throws JSONException {
if (source instanceof JSONArray) {
JSONArray sourceArray = (JSONArray) source;
for (int i = 0; i < sourceArray.length(); i++) {
Object sourceItem = sourceArray.opt(i);
addOneItemToArray(sourceItem, destinationArray, destinationArrayItemSkeleton);
private static void insertValue(ComplexDdiElement source, JSONObject destination, String key, Object destinationValue) throws NotAuthorizedException, XPathExpressionException, IOException, JSONException {
String stringValue = destinationValue.toString();
if (stringValue.charAt(0) == '.') {
DdiElement element = source.getElement(stringValue);
if (element != null) {
if (element instanceof DdiList) {
JSONArray array = new JSONArray();
DdiList<DdiElement> list = (DdiList<DdiElement>) element;
for (DdiElement ddiElement : list) {
array.put(ddiElement.toString());
}
destination.put(key, array);
} else {
destination.put(key, element.toString());
}
} else {
destination.put(key, "");
}
}
else if (source != null) {
addOneItemToArray(source, destinationArray, destinationArrayItemSkeleton);
}
}
private static void addOneItemToArray(Object sourceItem, JSONArray destinationArray, Object destinationArrayItemSkeleton) throws JSONException {
if (destinationArrayItemSkeleton instanceof JSONObject) {
JSONObject destinationObj = new JSONObject(destinationArrayItemSkeleton.toString());
copyJSONData(sourceItem, destinationObj);
destinationArray.put(destinationObj);
}
else if (destinationArrayItemSkeleton instanceof JSONArray) {
JSONArray newDestinationArray = new JSONArray();
Object newSkeleton = ((JSONArray) destinationArrayItemSkeleton).get(0);
copyJSONData(sourceItem, newDestinationArray, newSkeleton);
destinationArray.put(destinationArray);
}
else if (sourceItem != null) {
destinationArray.put(sourceItem.toString());
} else {
destination.put(key, stringValue);
}
}
......
{"payload":{
"concept":[
{
"content":"text",
"vocabURI":"text",
"vocab":"text"
}
],
"qstn":{
"postQTxt":"text",
"ivuInstr":"text",
"qstnLit":"text",
"preQTxt":"text"
},
"location":{
"RecSegNo":"number"
},
"labl":"text",
"respUnit":"text",
"sumStat":[
{
"content":"number",
"type":"vald/invd",
"wgtd":"wgtd"
}
],
"embargo":{
"content":"text",
"event":"notBefore",
"date":"2010-10-10",
"ExtLink":{
"title":"text",
"role":"text",
"URI":"text"
}
},
"security":"text",
"txt":"text",
"dcml":"number",
"undocCod":"text",
"wgt":"wgt",
"verStmt":{
"notes":{
"content":"text",
"ExtLink":{
"title":"text",
"role":"text",
"URI":"text"
}
},
"verResp":{
"content":"text",
"affiliation":"text",
"ExtLink":{
"title":"text",
"role":"text",
"URI":"text"
}
},
"version":{
"content":"text",
"type":"text",
"date":"2010-10-10",
"ExtLink":{
"title":"text",
"role":"text",
"URI":"text"
}
}
},
"name":"V1",
"ID":"V1",
"codInstr":"text",
"imputation":"text",
"catgry":[
{
"missing":"Y",
"labl":"text",
"txt":"text",
"catValu":"number",
"catStat": [
{
"content":"number",
"type":"freq",
"wgtd": "wgtd"
}
],
"catgry":["this_object"]
}
],
"files":"F1",
"TotlResp":"text",
"universe":{
"content":"text",
"ExtLink":{
"title":"text",
"role":"text",
"URI":"text"
}
},
"varFormat":{
"schema":"other",
"type":"numeric"
},
"invalrng":{
"range":[
{
"min":"number",
"UNITS":"REAL"
}
],
"item":{
"UNITS":"REAL",
"VALUE":"number"
}
},
"anlysUnit":"text",
"valrng":{
"range":{
"min":"number",
"UNITS":"REAL",
"max":"number"
}
},
"notes":{
"content":"text",
"ExtLink":{
"title":"text",
"role":"text",
"URI":"text"
}
},
"intrvl":"discrete",
"stdCatgry":{
"content":"text",
"date":"2010-10-10",
"ExtLink":{
"title":"text",
"role":"text",
"URI":"text"
}
}
}}
{"payload":{
"concept":"./concept",
"qstn":{
"postQTxt":"./qstn/postQTxt",
"ivuInstr":"./qstn/ivuInstr",
"qstnLit":"./qstn/qstnLit",
"preQTxt":"./qstn/preQTxt"
},
"labl":"./labl",
"sumStat":[
{
"content":"./sumStat[@type='vald' and @wgtd='wgtd']",
"type":"vald",
"wgtd":"wgtd"
},
{
"content":"./sumStat[@type='invd' and @wgtd='wgtd']",
"type":"invd",
"wgtd":"wgtd"
},
{
"content":"./sumStat[@type='mean' and @wgtd='wgtd']",
"type":"mean",
"wgtd":"wgtd"
},
{
"content":"./sumStat[@type='medn' and @wgtd='wgtd']",
"type":"medn",
"wgtd":"wgtd"
},
{
"content":"./sumStat[@type='stdev' and @wgtd='wgtd']",
"type":"stdev",
"wgtd":"wgtd"
},
{
"content":"./sumStat[@type='mode' and @wgtd='wgtd']",
"type":"mode",
"wgtd":"wgtd"
},
{
"content":"./sumStat[@type='vald' and @wgtd='not-wgtd']",
"type":"vald",
"wgtd":"not-wgtd"
},
{
"content":"./sumStat[@type='invd' and @wgtd='not-wgtd']",
"type":"invd",
"wgtd":"not-wgtd"
},
{
"content":"./sumStat[@type='mean' and @wgtd='not-wgtd']",
"type":"mean",
"wgtd":"not-wgtd"
},
{
"content":"./sumStat[@type='vald' and @wgtd='not-wgtd']",
"type":"medn",
"wgtd":"not-wgtd"
},
{
"content":"./sumStat[@type='min' and @wgtd='not-wgtd']",
"type":"min",
"wgtd":"not-wgtd"
},
{
"content":"./sumStat[@type='max' and @wgtd='not-wgtd']",
"type":"max",
"wgtd":"not-wgtd"
},
{
"content":"./sumStat[@type='stdev' and @wgtd='not-wgtd']",
"type":"stdev",
"wgtd":"not-wgtd"
},
{
"content":"./sumStat[@type='mode' and @wgtd='not-wgtd']",
"type":"mode",
"wgtd":"not-wgtd"
}
],
"txt":"./text",
"dcml":"./@dcml",
"wgt":"./@wgt",
"name":"./@name",
"ID":"./@ID",
"TotlResp":"./TotlResp",
"universe":"./universe",
"varFormat":{
"schema":"./varFormat/@schema",
"type":"./varFormat/@type"
},
"valrng":{
"range":{
"min":"./valrng/range/@min",
"max":"./valrng/range/@max"
}
},
"notes":"./notes",
"intrvl":"./@intrvl"
}}
package com.nesstar.rest.result_object_makers;
import com.nesstar.api.*;
import junit.framework.Assert;
import org.junit.Test;
import java.util.Collections;
import java.util.Iterator;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.*;
/**
* @author Ole Voldsæter
*/
public class MetadataMakerTest {
@Test
public void testGetVariableMetadata() throws Exception {
Server server = mock(Server.class);
Bank<Variable> varBank = mock(Bank.class);
Variable variable = mock(Variable.class);
DdiList<SimpleDdiElement<String>> list = mock(DdiList.class);
SimpleDdiElement<String> elt1 = mock(SimpleDdiElement.class);
SimpleDdiElement<String> elt2 = mock(SimpleDdiElement.class);
Iterator<SimpleDdiElement<String>> iterator = mock(Iterator.class);
DdiList<Category> categories = (DdiList<Category>) mock(DdiList.class);
when(categories.iterator()).thenReturn(Collections.<Category>emptyIterator());
when(varBank.get(anyObject())).thenReturn(variable);
when(server.getBank(Variable.class)).thenReturn(varBank);
when(variable.getElement(eq("./concept"))).thenReturn(list);
when(variable.getCategories()).thenReturn(categories);
when(list.iterator()).thenReturn(iterator);
when(iterator.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false);
when(iterator.next()).thenReturn(elt1).thenReturn(elt2);
when(elt1.toString()).thenReturn("concept1");
when(elt2.toString()).thenReturn("concept2");
Object o = MetadataMaker.getVariableMetadata("id", server);
assertNotNull(o);
assertTrue("o should be a String", o instanceof String);
assertFalse("o should not be empty", ((String) o).isEmpty());
verify(variable, times(33)).getElement(anyString());
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment