catch up with branch daily

Signed-off-by: Ralf Mollik <ramollik@compex-commerce.com>
diff --git a/org.eclipse.osbp.xtext.datamart.common/src/org/eclipse/osbp/xtext/datamart/common/olap/CellSetToD3JsonConverter.java b/org.eclipse.osbp.xtext.datamart.common/src/org/eclipse/osbp/xtext/datamart/common/olap/CellSetToD3JsonConverter.java
index 2d8ef39..1c1c8dd 100644
--- a/org.eclipse.osbp.xtext.datamart.common/src/org/eclipse/osbp/xtext/datamart/common/olap/CellSetToD3JsonConverter.java
+++ b/org.eclipse.osbp.xtext.datamart.common/src/org/eclipse/osbp/xtext/datamart/common/olap/CellSetToD3JsonConverter.java
@@ -1,6 +1,6 @@
 /**
  *                                                                            
- *  Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) 
+ *  Copyright (c) 2011, 2019 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) 
  *                                                                            
  *  All rights reserved. This program and the accompanying materials           
  *  are made available under the terms of the Eclipse Public License 2.0        
@@ -16,9 +16,10 @@
  package org.eclipse.osbp.xtext.datamart.common.olap;
 
 import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 
 import elemental.json.JsonFactory;
 import elemental.json.impl.JreJsonArray;
@@ -32,12 +33,14 @@
 	private static final String KEY_TOOLTIPNAME="tooltipName";
 	private static JsonFactory factory = new JreJsonFactory();
 
-	public static String getD3JsonString(DerivedCellSet cxCellSet) {
+	public CellSetToD3JsonConverter() {
+	}
+	
+	public static String getD3JsonString(DerivedCellSet cxCellSet, boolean noMeasures) {
 	    // generate a new result component
 	    if (cxCellSet == null) {
 	    	return "";
 	    }
-	    
 		ArrayList<Integer> coordinateSystem = new ArrayList<>();
     	// create a multidimensional coordinate system against the cellSet
     	for	(int axis = 0; axis < cxCellSet.getAxes().size(); axis++) {
@@ -47,39 +50,32 @@
 	    // add styles to page for the axis's custom styles
 	    List<String> dataColumns = getDataColumnNameList(cxCellSet);
 		
-	    JreJsonArray jsonArrayStructure = new JreJsonArray(factory);
-	    
+	    Node root = new Node();
 	    // for every data row
 	    for	(DerivedPosition rows : cxCellSet.getAxes().get(1).getPositions()) {
 	    	// row Data
 	    	coordinate.set(1, rows.getOrdinal());
 	    	// fill in the row members for the row axis
 	    	for (DerivedMember member : rows.getMembers()) {
-	    		JreJsonObject childrenListMap = new JreJsonObject(factory);
-	    		String[] tokens = member.getUniqueName().split("\\]\\.\\[");
-	    		LinkedList<String> tokenList = new LinkedList<>(Arrays.asList(tokens));
-	    		// create a concatenated name of all members for the data column
-	    		childrenListMap.put(KEY_TOOLTIPNAME, member.getUniqueName().replace("[", "").replace("]", "").replace(".", "-"));
-	    		// create a name from the last member for the data column
-	    		childrenListMap.put(KEY_NAME, tokenList.getLast().replace("[", "").replace("]", ""));
-		    	for	(DerivedPosition columns : cxCellSet.getAxes().get(0).getPositions()) {
-		    		coordinate.set(0, columns.getOrdinal());
-		    		childrenListMap.put(dataColumns.get(columns.getOrdinal()), cxCellSet.getCell(coordinate).getFormattedValue());
-		    	}
-	    	    // creation of a LinkedHashMap structure
-	    	    createJsonMapStructure(jsonArrayStructure, tokenList, childrenListMap);
+	    		String qualifiedName = member.getUniqueName().replace("[", "").replace("]", "");
+	    		if(!noMeasures) {
+		    		JreJsonObject childrenListMap = new JreJsonObject(factory);
+		    		// create a concatenated name of all members for the data column
+		    		childrenListMap.put(KEY_TOOLTIPNAME, qualifiedName.replace(".", "-"));
+		    		childrenListMap.put(KEY_NAME, member.getCaption());
+			    	for	(DerivedPosition columns : cxCellSet.getAxes().get(0).getPositions()) {
+			    		coordinate.set(0, columns.getOrdinal());
+			    		childrenListMap.put(dataColumns.get(columns.getOrdinal()), ((Double)cxCellSet.getCell(coordinate).getValue()).toString());
+			    	}
+		    		addToHierachy(root, qualifiedName.split("\\."), childrenListMap);
+	    		}
+	    		addToHierachy(root, qualifiedName.split("\\."), null);
 	    	}
 	    }
-	    JreJsonObject jsonMap;
-	    // to ensure that only exist one root node
-	    if (jsonArrayStructure.length() > 0){
-	    	jsonMap = new JreJsonObject(factory);
-			jsonMap.put(KEY_NAME, "RootNode");
-			jsonMap.put(KEY_CHILDREN, jsonArrayStructure); 
-	    } else {
-	    	jsonMap = (JreJsonObject) jsonArrayStructure.get(0);
-	    }
-	    return jsonMap.toString();
+	    
+	    JreJsonArray json = convertToJSON(root);
+	    String result = json.toJson().toString();
+	    return result.substring(1, result.length()-1);
 	}
 
 	public static List<String> getDataColumnNameList(DerivedCellSet cxCellSet) {
@@ -100,46 +96,78 @@
 		return dataColumns;
 	}
 
-	private static JreJsonArray createJsonMapStructure(JreJsonArray jsonArray, LinkedList<String> tokenList, JreJsonObject childrenListMap) {
-		String tokenStr = tokenList.get(0).replace("]", "").replace("[", "");
-		tokenList.removeFirst();
-		JreJsonArray jsonChildrenArray = null;
-		JreJsonObject jsonMap = null;
-		// if a jsonMap with the current tokenStr already exist, then no new jsonChildrenArray is created, 
-		// but the existing jsonChildrenArray within the children key of the jsonMap is used.
-		for (int i=0; i < jsonArray.length(); i++) {
-			jsonMap = (JreJsonObject) jsonArray.get(i);
-			if (tokenStr.equals(jsonMap.get(KEY_NAME))) {
-				jsonChildrenArray = (JreJsonArray)jsonMap.get(KEY_CHILDREN);
-				break;
-			}
-		}
-		
-		// only checking existing jsonChildrenArray, 
-		// because jsonMap can be the last map of the jsonArray if exists.
-		// So if no jsonChildrenArray exist it has to be created with a new jsonMap.
-		if (jsonChildrenArray==null) {
-			jsonMap = new JreJsonObject(factory);
-			jsonMap.put(KEY_NAME, tokenStr);
-			jsonArray.set(jsonArray.length(), jsonMap);
-			jsonChildrenArray = new JreJsonArray(factory);
-		}
-		if (tokenList.size()==1){
-			JreJsonArray jsonRowsDataArray;
-			//check if children with JreJsonArray exist
-			if (jsonMap.hasKey(KEY_CHILDREN)){
-				jsonRowsDataArray = (JreJsonArray) jsonMap.get(KEY_CHILDREN);
-			} else {
-				jsonRowsDataArray = new JreJsonArray(factory);
-			}
-			jsonRowsDataArray.set(jsonRowsDataArray.length(), childrenListMap);
-			jsonMap.put(KEY_CHILDREN, jsonRowsDataArray);
-		} else {
-			jsonChildrenArray = createJsonMapStructure(jsonChildrenArray, tokenList, childrenListMap);
-			jsonMap.put(KEY_CHILDREN, jsonChildrenArray);
-		}
-		
-		return jsonArray;
-	}
+    private static void addToHierachy(Node root, Object[] row, JreJsonObject valueMap) {
+        Node current = root;
 
+        // Go through each column in the row
+        for(Object col : row) {
+        	// this is the last row element, so add the values
+        	current = current.getOrCreateChild((String) col);
+        	if(valueMap != null && col.equals(row[row.length-1])) {
+        		current.setValueMap(valueMap);
+        	}
+        }
+    }
+
+    private static JreJsonArray convertToJSON(Node root) {
+        // Use recursion to build the result JSON
+    	JreJsonArray array = new JreJsonArray(factory);
+
+        // Starting at this root, go through all of the child entries
+        for(Map.Entry<String, Node> child : root.getChildren().entrySet()) {
+            Node childNode = child.getValue();
+
+            // New object for this entry...
+            JreJsonObject object = new JreJsonObject(factory);
+            // Set the name
+            object.put(KEY_NAME, child.getKey());
+
+            // Set the value if it is present on this node
+            if(childNode.getValueMap() != null) {
+            	JreJsonArray values = new JreJsonArray(factory);
+            	values.set(0, childNode.getValueMap());
+                object.put(KEY_CHILDREN, values);
+            }
+
+            // Generate the child hierarchy if it has children
+            if(!childNode.getChildren().isEmpty()) {
+            	JreJsonArray childHierachy = convertToJSON(childNode);
+                object.put(KEY_CHILDREN, childHierachy);
+            }
+
+            array.set(array.length(), object);
+        }
+
+        return array;
+    }
+
+    // Class used to build the hierarchy
+    static class Node {
+        // The map of children, LABEL -> NODE
+        private Map<String, Node> children = new HashMap<>();
+		private JreJsonObject valueMap;
+
+        public Node getOrCreateChild(String key) {
+            Node node = children.get(key);
+
+            if(node == null) {
+                node = new Node();
+                children.put(key, node);
+            }
+
+            return node;
+        }
+
+        public Map<String, Node> getChildren() {
+            return children;
+        }
+
+        public JreJsonObject getValueMap() {
+            return valueMap;
+        }
+
+        public void setValueMap(JreJsonObject valueMap) {
+            this.valueMap = valueMap;
+        }
+    }	
 }
diff --git a/org.eclipse.osbp.xtext.datamart.common/src/org/eclipse/osbp/xtext/datamart/common/sql/SqlCellSet.java b/org.eclipse.osbp.xtext.datamart.common/src/org/eclipse/osbp/xtext/datamart/common/sql/SqlCellSet.java
index edb0bb5..7a8e760 100644
--- a/org.eclipse.osbp.xtext.datamart.common/src/org/eclipse/osbp/xtext/datamart/common/sql/SqlCellSet.java
+++ b/org.eclipse.osbp.xtext.datamart.common/src/org/eclipse/osbp/xtext/datamart/common/sql/SqlCellSet.java
@@ -389,7 +389,7 @@
 											}
 											
 											if(primaryMap.containsKey(columnLabel)) {
-												if(isHistorized) {
+												if(isHistorized || primaryMap.get(columnLabel).isHistorized()) {
 													primaryMap.get(columnLabel).add(new UUIDHist((String)value, (long)getCastedValue(rs, metaData, columnIdx+1)));
 												} else {
 													primaryMap.get(columnLabel).add(value);
@@ -535,7 +535,7 @@
 		case java.sql.Types.SMALLINT:
 			return rs.getShort(idx);
 		case java.sql.Types.BIGINT:
-			return rs.getBigDecimal(idx);
+			return rs.getLong(idx);
 		case java.sql.Types.INTEGER:
 			return (int) rs.getInt(idx);
 		case java.sql.Types.BOOLEAN: