/***************************************************************************** * Copyright [2013] [Jules White] * * * * 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 org.magnum.soda.protocol.generic; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.magnum.soda.marshalling.Marshaller; import org.magnum.soda.proxy.ObjRef; public class PolymorphicUnmarshallingHelper { private static final String URI = "uri"; private static final String OBJ_REF = "ObjRef"; private static final String TYPE = "type"; private JSONParser parser_ = new JSONParser(); private Marshaller marshaller_; public PolymorphicUnmarshallingHelper(Marshaller m) { marshaller_ = m; } public Object[] unmarshall(Class<?>[] types, JSONArray values) { Object[] params = new Object[types.length]; for (int i = 0; i < params.length; i++) { Class<?> type = types[i]; Object val = values.get(i); if (isJsonObjRef(val)) { ObjRef ref = new ObjRef("" + ((JSONObject) val).get(URI), types[i].getName()); params[i] = ref; } else { String data = values.get(i).toString(); params[i] = unmarshall(type, data); } } return params; } private boolean isJsonObjRef(Object val) { return val instanceof JSONObject && OBJ_REF.equals(((JSONObject) val).get(TYPE)); } public Object unmarshall(Class<?> type, String data) { try { return (isPrimitive(type)) ? unMarshallPrimitive(type, data) : unmarshallObject(type, data); } catch (Exception e) { throw new RuntimeException(e); } } public Object unmarshallObject(Class<?> type, String data) { Object rslt = null; try { Object pval = parser_.parse(data); if(!(pval instanceof JSONObject) && !(pval instanceof JSONArray)){ return pval; } else if (pval instanceof JSONArray){ rslt = marshaller_.fromTransportFormat(type, data); } else if (isJsonObjRef((JSONObject)pval)) { JSONObject obj = (JSONObject)pval; rslt = new ObjRef("" + obj.get(URI), type.getName()); } else { rslt = marshaller_.fromTransportFormat(type, data); } } catch (Exception e) { throw new RuntimeException(e); } return rslt; } public boolean isPrimitive(Class<?> type) { return (type == Integer.class || type == int.class || type == Double.class || type == double.class || type == Float.class || type == float.class || type == Long.class || type == long.class || type == Boolean.class || type == boolean.class || type == Byte.class || type == byte.class || type == Short.class || type == short.class || type == String.class || type == Class.class); } public Object unMarshallPrimitive(Class<?> type, String json) { if (type == Integer.class || type == int.class) { return Integer.parseInt(json); } else if (type == Double.class || type == double.class) { return Double.parseDouble(json); } else if (type == Float.class || type == float.class) { return Float.parseFloat(json); } else if (type == Long.class || type == long.class) { return Long.parseLong(json); } else if (type == Boolean.class || type == boolean.class) { return Boolean.parseBoolean(json); } else if (type == Byte.class || type == byte.class) { return Byte.parseByte(json); } else if (type == Short.class || type == short.class) { return Short.parseShort(json); } else if (type == Class.class) { json = (json.startsWith("class ")) ? json.substring(6) : json; try { return Class.forName(json); } catch (Exception ex) { throw new RuntimeException(ex); } } else { return json; } } }