/**
* Copyright 2008-2016 Qualogy Solutions B.V.
*
* 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.qualogy.qafe.gwt.client.vo.functions;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.google.gwt.user.client.rpc.IsSerializable;
import com.qualogy.qafe.gwt.client.component.DataMap;
public class DataContainerGVO implements IsSerializable {
public static String ROW_STATUS_KEY = "rowStatus";
public static String ROW_NUMBER = "rowNumber";
public static String ROW_STATUS_UNMODIFIED = "$$UNMODIFIED";
public static String ROW_STATUS_NEW = "$$NEW";
public static String ROW_STATUS_DELETED = "$$DELETED";
public static String ROW_STATUS_MODIFIED = "$$MODIFIED";
public static String ROW_STATUS_UNSELECTED = "$$UNSELECTED";
public static String ROW_STATUS_ALL = "$$ALL";
public static final String QAFE_CHECKSUM = "QAFE_CHECKSUM";
public static final int KIND_VALUE = -1;
public static final int KIND_STRING = 0;
public static final int KIND_MAP = 1;
public static final int KIND_COLLECTION = 5;
public static final int TYPE_INT = 0;
public static final int TYPE_DOUBLE = 1;
public static final int TYPE_BOOLEAN = 2;
public static final int TYPE_CHAR = 3;
public static final int TYPE_STRING = 4;
public static final int TYPE_BYTE = 5;
public static final int TYPE_BIGDECIMAL = 6;
public static final int TYPE_BIGINTEGER = 7;
public static final int TYPE_FLOAT = 8;
public static final int TYPE_LONG = 9;
public static final int TYPE_SHORT = 10;
public static final int TYPE_DATE = 11;
private String dataString;
private String parameterName;
private DataMap dataMap;
private int kind = KIND_VALUE;
private int stringDataType = TYPE_STRING;
private Date dateData = null;
private List<DataContainerGVO> listofDC;
public DataContainerGVO(){}
public DataContainerGVO(String value){
setKind(KIND_STRING);
setDataString(value);
}
public DataContainerGVO(DataMap map){
dataMap = map;
setKind(KIND_MAP);
}
public boolean isMap(){
return (kind==KIND_MAP);
}
public DataContainerGVO(DataContainerGVO clone){
if(clone!=null){
this.kind = clone.kind;
this.dataString = clone.dataString;
this.parameterName = clone.parameterName;
this.dateData = clone.dateData;
if (clone.dataMap!=null){
this.dataMap = (DataMap)dataMap.clone();
}
if (clone.listofDC!=null){
this.listofDC = new ArrayList<DataContainerGVO>();
for(DataContainerGVO dcg: clone.listofDC){
this.listofDC.add(new DataContainerGVO(dcg));
}
}
}
}
public List<DataContainerGVO> getListofDC() {
return listofDC;
}
public void setListofDC(List<DataContainerGVO> listofDC) {
this.listofDC = listofDC;
}
public Date getDateData() {
return dateData;
}
public void setDateData(Date dateData) {
this.dateData = dateData;
}
public String getDataString() {
return dataString;
}
public void setDataString(String dataString) {
this.dataString = dataString;
}
public int getKind() {
return kind;
}
public void setKind(int kind) {
this.kind = kind;
}
public DataMap getDataMap() {
return dataMap;
}
public void setDataMap(DataMap dataMap) {
this.dataMap = dataMap;
}
public String getParameterName() {
return parameterName;
}
public void setParameterName(String parameterName) {
this.parameterName = parameterName;
}
public int getStringDataType() {
return stringDataType;
}
public void setStringDataType(int stringDataType) {
this.stringDataType = stringDataType;
}
public static String resolveValue(DataContainerGVO vo) {
String returnValue = null;
if (vo != null) {
if (vo.getKind() == DataContainerGVO.KIND_STRING) {
returnValue = vo.getDataString();
}
}
return returnValue;
}
public Object createType() {
return createType(this);
}
// CHECKSTYLE.OFF: CyclomaticComplexity
public static Object createType(DataContainerGVO data) {
Object returnValue = null;
if (data != null) {
if (data.getKind() == DataContainerGVO.KIND_MAP) {
//returnValue = data.getDataMap();
HashMap<String, Object> map = new HashMap<String, Object>();
for(String key : data.getDataMap().keySet()) {
map.put(key, createType(data.getDataMap().get(key)));
}
returnValue = map;
} else if (data.getKind()==DataContainerGVO.KIND_COLLECTION){
//returnValue = data.getListofDC();
List<Object> listOfMap = new ArrayList<Object>();
for(DataContainerGVO gvo : data.getListofDC()) {
listOfMap.add(createType(gvo));
}
returnValue = listOfMap;
}
else {
if(isEmptyOrNullNumberType(data)) {
// If the value is empty or null for a number type then parsing to corresponding type will give exception.
returnValue = data.getDataString();
} else {
switch (data.getStringDataType()) {
case TYPE_BOOLEAN:
returnValue = new Boolean(data.getDataString());
break;
case TYPE_CHAR:
returnValue = data.getDataString().charAt(0);
break;
case TYPE_STRING:
returnValue = data.getDataString();
break;
case TYPE_DATE:
returnValue = data.getDateData();
break;
case TYPE_BYTE:
returnValue = new Byte(data.getDataString());
break;
case TYPE_BIGDECIMAL:
returnValue = new BigDecimal(data.getDataString());
break;
case TYPE_BIGINTEGER:
returnValue = new BigInteger(data.getDataString());
break;
case TYPE_DOUBLE:
returnValue = new Double(data.getDataString());
break;
case TYPE_FLOAT:
returnValue = new Float(data.getDataString());
break;
case TYPE_INT:
/**
* If the databse column is of type NUMBER type and if the value from the database is an integer value (10) ,
* then the datacontainer stringDataType is set as TYPE_INT. (Check SetValueBuiltInRenderer - createContainer method)
* Now if that value is updated by the user in the front-end as a decimal value (10.2) it is giving exception while
* converting to Integer. In that case we should convert that value to Double.
*
*/
try {
returnValue = new Integer(data.getDataString());
} catch(Exception e){
returnValue = new Double(data.getDataString());
}
break;
case TYPE_LONG:
returnValue = new Long(data.getDataString());
break;
case TYPE_SHORT:
returnValue = new Short(data.getDataString());
break;
default:
break;
}
}
}
}
return returnValue;
}
// CHECKSTYLE.ON: CyclomaticComplexity
public static DataContainerGVO create(Object object) {
if (object instanceof DataContainerGVO) {
return (DataContainerGVO) object;
}
if (object instanceof Boolean || object instanceof Character || object instanceof String || object instanceof Date || object instanceof Number) {
return createSimpleType(object);
}
if (object instanceof Map<?,?>) {
return create((Map<?,?>) object);
}
if (object instanceof Collection<?>) {
return create((Collection<?>) object);
}
return null;
}
private static DataContainerGVO create(Map<?,?> returnedObject) {
DataContainerGVO data = new DataContainerGVO();
if (returnedObject instanceof DataMap) {
data.setDataMap((DataMap) returnedObject);
} else {
data.setDataMap(createDataMap(returnedObject));
}
data.setKind(DataContainerGVO.KIND_MAP);
return data;
}
private static DataMap createDataMap(Map<?,?> map) {
DataMap dataMap = new DataMap();
for (Map.Entry<?,?> entry: map.entrySet()) {
if (entry.getKey() instanceof String) {
String key = (String) entry.getKey();
DataContainerGVO value = create(entry.getValue());
dataMap.put(key, value);
}
}
return dataMap;
}
// CHECKSTYLE.OFF: CyclomaticComplexity
private static DataContainerGVO createSimpleType(Object object) {
DataContainerGVO data = new DataContainerGVO();
boolean valueIsSet = false;
if (object instanceof Boolean) {
data.setStringDataType(DataContainerGVO.TYPE_BOOLEAN);
} else if (object instanceof Character) {
data.setStringDataType(DataContainerGVO.TYPE_CHAR);
} else if (object instanceof String) {
data.setStringDataType(DataContainerGVO.TYPE_STRING);
} else if (object instanceof Date) {
data.setStringDataType(DataContainerGVO.TYPE_DATE);
data.setDateData(new Date(((Date) object).getTime()));
} else if (object instanceof Number) {
if (object instanceof Byte) {
data.setStringDataType(DataContainerGVO.TYPE_BYTE);
} else if (object instanceof BigDecimal) {
data.setStringDataType(DataContainerGVO.TYPE_BIGDECIMAL);
} else if (object instanceof BigInteger) {
data.setStringDataType(DataContainerGVO.TYPE_BIGINTEGER);
} else if (object instanceof Double) {
data.setStringDataType(DataContainerGVO.TYPE_DOUBLE);
} else if (object instanceof Float) {
data.setStringDataType(DataContainerGVO.TYPE_FLOAT);
} else if (object instanceof Integer) {
data.setStringDataType(DataContainerGVO.TYPE_INT);
} else if (object instanceof Long) {
data.setStringDataType(DataContainerGVO.TYPE_LONG);
} else if (object instanceof Short) {
data.setStringDataType(DataContainerGVO.TYPE_SHORT);
}
}
if (!valueIsSet) {
data.setDataString(object.toString());
}
data.setKind(DataContainerGVO.KIND_STRING);
return data;
}
// CHECKSTYLE.ON: CyclomaticComplexity
@SuppressWarnings("unchecked")
private static DataContainerGVO create(Collection<?> collection) {
DataContainerGVO data = new DataContainerGVO();
if (isDataContainerGVOList(collection)) {
data.setListofDC((List<DataContainerGVO>) collection);
} else {
Collection<?> c = collection;
List<DataContainerGVO> list = new ArrayList<DataContainerGVO>();
data.setListofDC(list);
List<?> l = (List<?>) c;
for (Object o : l) {
list.add(create(o));
}
}
data.setKind(DataContainerGVO.KIND_COLLECTION);
return data;
}
private static boolean isDataContainerGVOList(Collection<?> collection) {
if (!(collection instanceof List<?>)) {
return false;
}
if (collection.isEmpty()) {
return false;
}
return collection.iterator().next() instanceof DataContainerGVO;
}
private static boolean isEmptyOrNullNumberType(DataContainerGVO data) {
boolean emptyNumberType = false;
switch (data.getStringDataType()) {
case TYPE_BYTE:
case TYPE_BIGDECIMAL:
case TYPE_BIGINTEGER:
case TYPE_DOUBLE:
case TYPE_FLOAT:
case TYPE_LONG:
case TYPE_SHORT:
case TYPE_INT:
if(data.getDataString() == null || data.getDataString().isEmpty()) {
emptyNumberType = true;
}
break;
}
return emptyNumberType;
}
@Override
public String toString() {
switch (getKind()) {
case KIND_STRING:
if (getDataString() != null) {
return getDataString();
} else {
return "null";
}
case KIND_MAP:
if (getDataMap() != null) {
return getDataMap().toString();
} else {
return "null";
}
case KIND_COLLECTION:
if (getListofDC() != null) {
return getListofDC().toString();
} else {
return "null";
}
default:
return "<not-assigned>";
}
}
public void clear(){
switch (getKind()) {
case KIND_STRING: break;
case KIND_MAP:
if (getDataMap() != null) {
for(Entry<String,DataContainerGVO> entry:getDataMap().entrySet()){
if (entry.getValue()!=null){
entry.getValue().clear();
}
}
getDataMap().clear();
} break;
case KIND_COLLECTION:
if (getListofDC() != null) {
for (DataContainerGVO dcvo : getListofDC()){
dcvo.clear();
}
}
getListofDC().clear();
break;
default:
break;
}
}
public boolean equalsValue(Object object) {
if (this == object) {
return true;
}
if (object == null) {
return false;
}
if (getClass() != object.getClass()) {
return false;
}
DataContainerGVO other = (DataContainerGVO)object;
Object thisValue = createType();
Object otherValue = other.createType();
if ((thisValue == null) && (otherValue != null)) {
return false;
}
if ((thisValue != null) && (otherValue == null)) {
return false;
}
if ((thisValue == null) && (otherValue == null)) {
return true;
}
return thisValue.equals(otherValue);
}
}