/* * Copyright 2011 JBoss 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 org.jbpm.formapi.server.form; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jbpm.formapi.shared.api.FBScript; import org.jbpm.formapi.shared.api.FBValidation; import org.jbpm.formapi.shared.api.FormItemRepresentation; import org.jbpm.formapi.shared.api.FormRepresentation; import org.jbpm.formapi.shared.api.InputData; import org.jbpm.formapi.shared.api.Mappable; import org.jbpm.formapi.shared.api.OutputData; import org.jbpm.formapi.shared.form.FormEncodingException; import org.jbpm.formapi.shared.form.FormRepresentationDecoder; import org.jbpm.formapi.shared.menu.MenuItemDescription; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; public class FormRepresentationDecoderImpl implements FormRepresentationDecoder { @Override public Object decode(Map<String, Object> data) throws FormEncodingException { if (data == null || data.isEmpty()) { return null; } String className = (String) data.get("@className"); if (className == null) { throw new FormEncodingException( "@className attribute cannot be null"); } Object obj = null; try { obj = Class.forName(className).newInstance(); if (obj instanceof Mappable) { Mappable item = (Mappable) obj; item.setDataMap(data); } else { throw new FormEncodingException("Type " + obj.getClass().getName() + " cannot be casted to FormItemRepresentation"); } } catch (InstantiationException e) { throw new FormEncodingException("Couldn't instantiate class " + className, e); } catch (IllegalAccessException e) { throw new FormEncodingException( "Couldn't access constructor of class " + className, e); } catch (ClassNotFoundException e) { throw new FormEncodingException("Couldn't find class " + className, e); } return obj; } @Override @SuppressWarnings("unchecked") public Map<String, List<MenuItemDescription>> decodeMenuItemsMap(String json) throws FormEncodingException { JsonObject jsonObj = new JsonParser().parse(json).getAsJsonObject(); Map<String, Object> dataMap = asMap(jsonObj); Map<String, List<MenuItemDescription>> retval = null; if (dataMap != null) { retval = new HashMap<String, List<MenuItemDescription>>(); for (Map.Entry<String, Object> entry : dataMap.entrySet()) { List<MenuItemDescription> itemsList = new ArrayList<MenuItemDescription>(); String key = entry.getKey(); Object obj = entry.getValue(); if (obj != null) { List<Object> itemsMapList = (List<Object>) obj; for (Object itemObj : itemsMapList) { Map<String, Object> itemDescMap = (Map<String, Object>) itemObj; MenuItemDescription desc = new MenuItemDescription(); desc.setDataMap(itemDescMap); itemsList.add(desc); } } retval.put(key, itemsList); } } return retval; } @Override public FormRepresentation decode(String code) throws FormEncodingException { FormRepresentation form = new FormRepresentation(); JsonElement json = new JsonParser().parse(code); if (json.isJsonObject()) { JsonObject jsonObj = json.getAsJsonObject(); if (jsonObj.entrySet().isEmpty()) { return null; } if (jsonObj.get("action") != null && jsonObj.get("action").isJsonPrimitive() && jsonObj.get("action").getAsJsonPrimitive().isString()) { form.setAction(jsonObj.get("action").getAsString()); } if (jsonObj.get("documentation") != null && jsonObj.get("documentation").isJsonPrimitive() && jsonObj.get("documentation").getAsJsonPrimitive() .isString()) { form.setDocumentation(jsonObj.get("documentation") .getAsString()); } if (jsonObj.get("enctype") != null && jsonObj.get("enctype").isJsonPrimitive() && jsonObj.get("enctype").getAsJsonPrimitive().isString()) { form.setEnctype(jsonObj.get("enctype").getAsString()); } if (jsonObj.get("lastModified") != null && jsonObj.get("lastModified").isJsonPrimitive() && jsonObj.get("lastModified").getAsJsonPrimitive() .isString()) { form.setLastModified(Double.valueOf( jsonObj.get("lastModified").getAsString()).longValue()); } else if (jsonObj.get("lastModified") != null && jsonObj.get("lastModified").isJsonPrimitive() && jsonObj.get("lastModified").getAsJsonPrimitive() .isNumber()) { form.setLastModified(jsonObj.get("lastModified").getAsNumber() .longValue()); } if (jsonObj.get("method") != null && jsonObj.get("method").isJsonPrimitive() && jsonObj.get("method").getAsJsonPrimitive().isString()) { form.setMethod(jsonObj.get("method").getAsString()); } if (jsonObj.get("name") != null && jsonObj.get("name").isJsonPrimitive() && jsonObj.get("name").getAsJsonPrimitive().isString()) { form.setName(jsonObj.get("name").getAsString()); } if (jsonObj.get("taskId") != null && jsonObj.get("taskId").isJsonPrimitive() && jsonObj.get("taskId").getAsJsonPrimitive().isString()) { form.setTaskId(jsonObj.get("taskId").getAsString()); } if (jsonObj.get("processName") != null && jsonObj.get("processName").isJsonPrimitive() && jsonObj.get("processName").getAsJsonPrimitive() .isString()) { form.setProcessName(jsonObj.get("processName").getAsString()); } form.setFormItems(decodeList(jsonObj.get("formItems"), FormItemRepresentation.class)); form.setFormValidations(decodeList(jsonObj.get("formValidations"), FBValidation.class)); form.setInputs(decodeStringIndexedMap(jsonObj.get("inputs"), InputData.class)); form.setOutputs(decodeStringIndexedMap(jsonObj.get("outputs"), OutputData.class)); form.setOnLoadScripts(decodeList(jsonObj.get("onLoadScripts"), FBScript.class)); form.setOnSubmitScripts(decodeList(jsonObj.get("onSubmitScripts"), FBScript.class)); } return form; } @Override public FormItemRepresentation decodeItem(String json) throws FormEncodingException { JsonElement jsonValue = new JsonParser().parse(json); if (jsonValue.isJsonObject()) { JsonObject jsonObj = jsonValue.getAsJsonObject(); Map<String, Object> dataMap = asMap(jsonObj); return (FormItemRepresentation) decode(dataMap); } else { throw new FormEncodingException("Expected json object but found " + jsonValue); } } @SuppressWarnings("unchecked") public <V> Map<String, V> decodeStringIndexedMap(JsonElement json, Class<V> valueType) throws FormEncodingException { Map<String, V> retval = new HashMap<String, V>(); if (json != null && json.isJsonObject()) { for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject() .entrySet()) { if (entry.getValue().isJsonObject()) { JsonObject jsonObj = entry.getValue().getAsJsonObject(); retval.put(entry.getKey(), (V) decode(asMap(jsonObj))); } } } return retval; } @SuppressWarnings("unchecked") public <T> List<T> decodeList(JsonElement json, Class<T> elemType) throws FormEncodingException { List<T> retval = new ArrayList<T>(); if (json != null && json.isJsonArray()) { JsonArray array = json.getAsJsonArray(); for (int index = 0; index < array.size(); index++) { JsonElement elem = array.get(index); JsonObject jsonObj = elem.getAsJsonObject(); retval.add((T) decode(asMap(jsonObj))); } } return retval; } private Map<String, Object> asMap(JsonObject jsonObj) { Map<String, Object> retval = new HashMap<String, Object>(); for (Map.Entry<String, JsonElement> entry : jsonObj.entrySet()) { retval.put(entry.getKey(), fromJsonValue(entry.getValue())); } return retval; } private List<Object> asList(JsonArray array) { List<Object> retval = new ArrayList<Object>(); if (array != null) { for (JsonElement elem : array) { retval.add(fromJsonValue(elem)); } } return retval; } private Object fromJsonValue(JsonElement elem) { if (elem.isJsonPrimitive() && elem.getAsJsonPrimitive().isString()) { return elem.getAsString(); } else if (elem.isJsonPrimitive() && elem.getAsJsonPrimitive().isNumber()) { return elem.getAsNumber(); } else if (elem.isJsonArray()) { return asList(elem.getAsJsonArray()); } else if (elem.isJsonNull()) { return null; } else if (elem.isJsonObject()) { return asMap(elem.getAsJsonObject()); } else { return ""; } } }