All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.aemds.guide.xfa.XFAJSONTransformerUtil Maven / Gradle / Ivy

/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2014 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and may be covered by U.S. and Foreign Patents,
 * patents in process, and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/

package com.adobe.aemds.guide.xfa;

import com.adobe.aemds.guide.utils.GuideConstants;
import com.adobe.aemds.guide.utils.MeasurementUtils;
import com.adobe.aemds.guide.utils.NameUtils;
import com.day.cq.commons.jcr.JcrConstants;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.commons.json.JSONArray;
import org.apache.sling.commons.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * @pad.exclude Exclude from Published API.
 */
public class XFAJSONTransformerUtil {

    private Logger logger;

    public static final Hashtable fieldUiRTMap;
    public static final Hashtable defaultFieldUiMap;
    public static final Hashtable drawUiRTMap;
    public static final Hashtable mandatoryConvertor;
    public static final Hashtable visibleConverter;
    public static final Hashtable enabledConverter;
    public static final Hashtable assistPriorityConvertor;
    public static final Hashtable multiSelectConvertor;
    public static final Hashtable> oneOfChild;

    static {
        fieldUiRTMap = new Hashtable();
        String arr[] = {GuideConstants.RT_GUIDEBUTTON, "guideButton"};
        fieldUiRTMap.put("button",arr);

        String arr1[] = {GuideConstants.RT_GUIDECHECKBOX, "guideCheckBox"};
        fieldUiRTMap.put("checkButton",arr1);

        String arr2[] = {GuideConstants.RT_GUIDEDROPDOWNLIST, "guideDropDownList"};
        fieldUiRTMap.put("choiceList",arr2);

        String arr3[] = {GuideConstants.RT_GUIDEDATEPICKER, "guideDatePicker"};
        fieldUiRTMap.put("dateTimeEdit",arr3);

        String arr4[] = {GuideConstants.RT_GUIDENUMERICBOX, "guideNumericBox"};
        fieldUiRTMap.put("numericEdit",arr4);

        String arr5[] = {GuideConstants.RT_GUIDEPASSWORDBOX, "guidePasswordBox"};
        fieldUiRTMap.put("passwordEdit",arr5);

        String arr6[] = {GuideConstants.RT_GUIDETEXTBOX, "guideTextBox"};
        fieldUiRTMap.put("textEdit",arr6);

        String arr7[] = {GuideConstants.RT_GUIDESCRIBBLE, "guideScribble"};
        fieldUiRTMap.put("scribble",arr7);

        String arr8[] = {};
        fieldUiRTMap.put("defaultUi",arr8);
        fieldUiRTMap.put("exObject",arr8);
        fieldUiRTMap.put("imageEdit",arr8);
        fieldUiRTMap.put("signature",arr8);
        fieldUiRTMap.put("barcode",arr8);

        drawUiRTMap = new Hashtable();
        drawUiRTMap.put("textEdit",new String[] {GuideConstants.RT_GUIDEDRAWTEXT, GuideConstants.GUIDE_FIELD_TEXTDRAW});
        drawUiRTMap.put("imageEdit", new String[] {GuideConstants.RT_GUIDEDRAWIMAGE, GuideConstants.GUIDE_FIELD_IMAGE});

        defaultFieldUiMap = new Hashtable();
        defaultFieldUiMap.put("integer","numericEdit");
        defaultFieldUiMap.put("boolean","checkButton");
        defaultFieldUiMap.put("decimal","numericEdit");
        defaultFieldUiMap.put("float","numericEdit");
        defaultFieldUiMap.put("date","dateTimeEdit");
        defaultFieldUiMap.put("dateTime", "dateTimeEdit");
        defaultFieldUiMap.put("time", "dateTimeEdit");
        defaultFieldUiMap.put("text","textEdit");
        defaultFieldUiMap.put("exdata","textEdit");
        defaultFieldUiMap.put("arc", "defaultUi");
        defaultFieldUiMap.put("line", "defaultUi");
        defaultFieldUiMap.put("rectangle", "defaultUi");
        defaultFieldUiMap.put("image", "imageEdit");

        oneOfChild = new Hashtable>();
        oneOfChild.put("ui", Arrays.asList(new String[]{
                "barcode", "button", "checkButton",
                "choiceList", "dateTimeEdit", "defaultUi",
                "exObject", "imageEdit", "numericEdit",
                "passwordEdit", "signature", "textEdit"
        }));

        oneOfChild.put("value",Arrays.asList(new String[]{
                "arc", "boolean", "date",
                "dateTime", "decimal", "exData",
                "float", "image", "integer",
                "line", "rectangle", "text", "time"
        }));

        mandatoryConvertor = new Hashtable();
        mandatoryConvertor.put("disabled","false");
        mandatoryConvertor.put("error","true");
        mandatoryConvertor.put("warning","false");

        visibleConverter = new Hashtable();
        visibleConverter.put("visible", "true");
        visibleConverter.put("hidden", "false");
        visibleConverter.put("inactive", "false");
        visibleConverter.put("invisible", "false");

        enabledConverter = new Hashtable();
        enabledConverter.put("open", "true");
        enabledConverter.put("nonInteractive", "false");
        enabledConverter.put("protected", "false");
        enabledConverter.put("readOnly", "false");

        assistPriorityConvertor = new Hashtable();
        assistPriorityConvertor.put("custom","custom");
        assistPriorityConvertor.put("toolTip","shortDescription");
        assistPriorityConvertor.put("caption","label");
        assistPriorityConvertor.put("name","name");

        multiSelectConvertor = new Hashtable();
        multiSelectConvertor.put("multiSelect", "true");
    }

    private static String UNNAMED_PREFIX = "_unnamed";
    private int unnamedCount;
    private ResourceResolver resourceResolver;
    private String xfaPath;
    private HashMap nameCountMap;

    public XFAJSONTransformerUtil() {
        unnamedCount = 0;
        logger = LoggerFactory.getLogger(XFAJSONTransformerUtil.class);
        resourceResolver  = null;
        xfaPath = "";
        nameCountMap = new HashMap();
    }
    public XFAJSONTransformerUtil(ResourceResolver resourceResolver, String xfaPath) {
        unnamedCount = 0;
        logger = LoggerFactory.getLogger(XFAJSONTransformerUtil.class);
        this.resourceResolver = resourceResolver;
        this.xfaPath = xfaPath;
        nameCountMap = new HashMap();
    }

    public Object getOrElse(JSONObject jsonObject, String jsonXpath,
                            Object defaultValue, boolean isAttr) throws Exception {
        JSONObject currObject = jsonObject;
        String[] propChain = jsonXpath.split("\\.");
        Object value = null;
        for (int i = 0; i < propChain.length; i++) {
            String property = propChain[i];
            String attrName = "", attrValue = "";
            int attrIndex = property.indexOf("(");
            if(attrIndex != -1) {
                property = propChain[i].substring(0, attrIndex);
                String attrString =  propChain[i].substring(attrIndex + 1, propChain[i].length() - 1);
                attrName = attrString;
                int ind = attrString.indexOf("=");
                if(ind != -1) {
                    attrName = attrString.substring(0,ind);
                    attrValue = attrString.substring(ind+1);
                }
            }
            boolean isLastProp = i == (propChain.length - 1);
            JSONObject tmpCurrentObject = currObject;
            currObject = null;
            value = null;
            if (tmpCurrentObject != null) {
                //Only last property is allowed to be looked up as attribute/key
                if("oneOfChild".equals(property)) {
                    currObject = getOneOfChild(tmpCurrentObject, oneOfChild.get(tmpCurrentObject.get("_class")));
                } else if (isLastProp && tmpCurrentObject.has(property)) {
                    value = tmpCurrentObject.get(property);
                } else if (!(isLastProp && isAttr) &&
                        (tmpCurrentObject.has("children") && tmpCurrentObject.get("children") instanceof JSONArray) ||
                        (tmpCurrentObject.has("items") && tmpCurrentObject.get("items") instanceof JSONObject)) {
                     //If this is last property which must be attribute, don't go to children
                    JSONArray array = tmpCurrentObject.getJSONArray("children");
                    for (int j = 0; j < array.length(); j++) {
                        JSONObject arrayItem = array.getJSONObject(j);
                        if (property.equals(arrayItem.getString("_class")) || (arrayItem.has("guideNodeClass") && property.equals(arrayItem.getString("guideNodeClass")))) {
                            boolean flag = attrIndex == -1;
                            if(!flag) {
                                String arrayItemAttrValue = arrayItem.getString(attrName);
                                if(attrValue.equals(arrayItemAttrValue)) {
                                    flag = true;
                                }
                            }
                            if(flag) {
                                currObject = arrayItem;
                                break;
                            }
                        }
                    }
                }
            } else {
                return defaultValue;
            }
        }
        //If in last iteration we found json object, then we'll return.
        //Else if we found value then return it.
        //Else return default value
        if (currObject != null) {
            return currObject;
        } else if (value != null) {
            return value;
        } else {
            return defaultValue;
        }
    }

    /**
     *
     * Utility method to get json object/value of attribute from given adaptive forms json object
     *
     * @param jsonObject adaptive forms Json Object
     * @param jsonXpath Xpath of property/json object in given json
     * @param defaultValue Default value to return if xpath not found
     * @param isAttr boolean indicating if the xpath is an attribute or not
     * @return
     * @throws Exception
     */
    public Object getOrElseFromAfJson(JSONObject jsonObject, String jsonXpath,
                            Object defaultValue, boolean isAttr) throws Exception {
        JSONObject currObject = jsonObject;
        String[] propChain = jsonXpath.split("\\.");
        Object value = null;
        for (int i = 0; i < propChain.length; i++) {
            String property = propChain[i];
            boolean isLastProp = i == (propChain.length - 1);
            JSONObject tmpCurrentObject = currObject;
            currObject = null;
            value = null;
            if (tmpCurrentObject != null) {
                // check if not an attribute and if exists as a property, then get the object
                if (!isAttr && tmpCurrentObject.has(property)) {
                    currObject = (JSONObject)tmpCurrentObject.get(property);
                } else if (!(isLastProp && isAttr) &&
                        (tmpCurrentObject.has("items") && tmpCurrentObject.get("items") instanceof JSONObject)) {
                    //If this is last property which must be attribute, don't go to children
                    JSONObject itemsJsonObject = (JSONObject)tmpCurrentObject.get("items");
                    if(itemsJsonObject.has(property)){
                        currObject = (JSONObject)itemsJsonObject.get(property);
                    } else {
                        currObject = null;
                    }
                } else if(isLastProp && isAttr) {
                    value = tmpCurrentObject.getString(property);
                } else {
                    return defaultValue;
                }
            }
        }
        //If in last iteration we found json object, then we'll return.
        //Else if we found value then return it.
        //Else return default value
        if (currObject != null) {
            return currObject;
        } else if (value != null) {
            return value;
        } else {
            return defaultValue;
        }
    }

    /**
     * Returns a Hashtable with two keys saveItems, representing save Items in the form model
     * and displayItems, representing the items to be displayed to the user. If only one of them
     * is present in Form Model, the value of saveItems and displayItems will be equal to that only.
     *
     * If none of them is present, the returned hashtable will be empty.
     */
    private Hashtable getItems(final JSONObject fieldJson) throws Exception {
        Hashtable result = new Hashtable();
        if (fieldJson.has("children") && fieldJson.get("children") instanceof JSONArray) {
            JSONObject saveItems = null;
            JSONObject displayItems = null;
            JSONArray fieldChildren = fieldJson.getJSONArray("children");
            for (int i = 0; i < fieldChildren.length(); i++) {
                JSONObject fieldChild = fieldChildren.getJSONObject(i);
                if ("items".equals(fieldChild.get("_class"))) {
                    if (fieldChild.has("save") && "1".equals(fieldChild.getString("save"))) {
                        saveItems = fieldChild;
                    } else {
                        displayItems = fieldChild;
                    }
                }
            }
            if (saveItems == null && displayItems != null) {
                saveItems = displayItems;
            }
            if(saveItems != null) {
                result.put("saveItems", saveItems);
                if(displayItems == null) {
                    displayItems = saveItems;
                }
                result.put("displayItems", displayItems);
            }
        }
        return result;
    }

    /**
     * returns a non-null array containing the items present in the Field. The length of the returned array
     * is number of items in the field.
     * Each element of the array is of the type saveItem==displayItem, where displayItem will be equal to
     * saveItem if there is no display item for the corresponding save item in the field.
     *
     * will throw an exception if the items in the fieldJson are not in proper JSONObjects
     */
    public String[] getDropDownOptions(final JSONObject fieldJson) throws Exception {
        Hashtable items = getItems(fieldJson);
        JSONObject saveItems = items.get("saveItems");
        JSONObject displayItems = items.get("displayItems");
        JSONArray saveChildren = null, displayChildren = null;
        String[] result = new String[0];
        if(saveItems != null && saveItems.has("children")) {
            saveChildren = (JSONArray)saveItems.get("children");
            displayChildren = (JSONArray) displayItems.get("children");
        }
        if(saveChildren != null && saveChildren.length() > 0) {
            result = new String[saveChildren.length()];
            for (int i = 0; i < saveChildren.length(); i++) {
                JSONObject saveChild = saveChildren.getJSONObject(i);
                JSONObject displayChild = displayChildren.getJSONObject(i);
                String saveValue = (String) this.getOrElse(saveChild, "_value", "", true);
                String displayValue = (String) this.getOrElse(displayChild, "_value", "", true);
                result[i] = saveValue + "=" + displayValue;
            }
        }
        return result;
    }

    public String convertItemsToOptions(final JSONObject fieldJson) throws Exception {
        Hashtable items = getItems(fieldJson);
        JSONObject saveItems = items.get("saveItems");
        if(saveItems != null && saveItems.has("children") &&
           saveItems.get("children") instanceof JSONArray &&
           saveItems.getJSONArray("children").length() > 0) {

            JSONObject itemValueChild = saveItems.getJSONArray("children").getJSONObject(0);
            String itemOption = (String) this.getOrElse(itemValueChild, "_value", "", true);
            String title = this.getTitle(fieldJson);
            return itemOption + "=" + title;
        }
        return null;
    }

    public JSONObject getOneOfChild(final JSONObject jsonObject, List oneOfChildList) throws Exception {
        if (jsonObject != null && jsonObject.has("children") && jsonObject.get("children") instanceof JSONArray) {
            JSONArray objectChildren = jsonObject.getJSONArray("children");
            for (int i = 0; i < objectChildren.length(); i++) {
                JSONObject child = (JSONObject) objectChildren.get(i);
                String childType = child.getString("_class");
                if(oneOfChildList.contains(childType)) {
                    return child;
                }
            }
        }
        return null;
    }

    public Hashtable getTableProperties(Hashtable input) {
        if(input == null) {
            input = new Hashtable();
        }
        input.put(GuideConstants.SLING_RESOURCE_TYPE, GuideConstants.RT_TABLE);
        input.put(GuideConstants.ELEMENT_PROPERTY_NODECLASS, GuideConstants.GUIDE_TABLE);
        return input;
    }

    public Hashtable getPanelProperties(Hashtable input) {
        if(input == null) {
            input = new Hashtable();
        }
        input.put(GuideConstants.SLING_RESOURCE_TYPE, GuideConstants.RT_PANEL);
        input.put("guideNodeClass", "guidePanel");
        return input;
    }

    public Hashtable getLayoutProperties(Hashtable input, boolean isTableMode) {
        if(input == null) {
            input = new Hashtable();
        }
        input.put(JcrConstants.JCR_PRIMARYTYPE, GuideConstants.NT_UNSTRUCTURED);
        if(isTableMode){
            input.put(GuideConstants.SLING_RESOURCE_TYPE, GuideConstants.LAYOUT_TABLELAYOUT);
            // Adding mobile layout to json, so that styling is preserved
            input.put(GuideConstants.LAYOUT_TABLE_MOBILE_LAYOUT, GuideConstants.LAYOUT_TABLE_HEADERS_LEFT);
        } else {
            input.put(GuideConstants.SLING_RESOURCE_TYPE, GuideConstants.LAYOUT_GRIDFLUIDLAYOUT);
            input.put(GuideConstants.LAYOUT_NON_NAVIGABLE_PROPERTY, true);
        }
        return input;
    }

    public Hashtable getCommonProperties(Hashtable input, JSONObject jsonObject)
            throws Exception{
        if(input == null) {
            input = new Hashtable();
        }
        input.put("name", NameUtils.getOrGenerateUniqueName(getOrGenerateName(jsonObject),nameCountMap));
        String title = getTitle(jsonObject);
        if (title == null) {
            title = "";
        }
        input.put(JcrConstants.JCR_TITLE,title);
        input.put(JcrConstants.JCR_PRIMARYTYPE, GuideConstants.NT_UNSTRUCTURED);
        putGuideProp(input, jsonObject, GuideConstants.VISIBLE_GUIDE_PROPERTY, GuideConstants.PRESENCE_XFA_PROPERTY, "true", visibleConverter);
        // update the visible property in AF to hidden if its corresponding field in XFA has visibility set to print only
        String relevantValue = (String) this.getOrElse(jsonObject, "relevant", null, true);
        if (StringUtils.equals(relevantValue, "+print")) {
            // in case of print only visible in XFA, we need the field in DOR, hence visibility is set to hidden
            input.put(GuideConstants.VISIBLE_GUIDE_PROPERTY, "false");
        }
        putGuideProp(input, jsonObject, GuideConstants.ENABLED_GUIDE_PROPERTY, GuideConstants.ACCESS_XFA_PROPERTY, "true", enabledConverter);
        putGuideProp(input, jsonObject, "bindRef", "extras.extras(name=FS_EXTRAS).text(name=FS_SOM)._value",
                null, null);

        putGuideProp(input, jsonObject, "dataSom", "extras.extras(name=FS_EXTRAS).text(name=FS_DATA_SOM)._value",
                null, null);

       // this is for getting fragments from fragment XDP
        // this comes from          
        putGuideProp(input, jsonObject, "isFragment", "extras.extras(name=FS_EXTRAS).text(name=isFragment)._value",
                null, null);
        // this is for placing fragRef property which would auto replace XFA fragment with adaptive forms fragment
        String usehref =  (String) this.getOrElse(jsonObject, "extras.extras(name=FS_EXTRAS).text(name=usehref)._value", null, true);
        if(usehref != null && usehref.length() > 0) {
            handleXDPFragment(input, jsonObject, usehref);
        }

        return input;
    }

    public void handleXDPFragment( Hashtable input, JSONObject obj,String usehref ) {
        try {


            String xdpRef = StringUtils.substringBeforeLast(usehref, "#"),
                    fragmentModelRootFromUsehref = "",
                    fragRef=null,
                    bindRef = (String) input.get(GuideConstants.BIND_REF) ;
            // usehref is like  .\Fragments\tabs.xdp#som($template.#subform.bla)
            // we want XDP file path and fragment model root from this

            fragmentModelRootFromUsehref = StringUtils.substringAfter(usehref, "#subform");
            // strip  ) at the end
            fragmentModelRootFromUsehref  = StringUtils.substringBeforeLast(fragmentModelRootFromUsehref, ")");
            // replace all . to [0]. to generate some line expression and add [0] after last subform
            fragmentModelRootFromUsehref = StringUtils.replace(fragmentModelRootFromUsehref , "." ,"[0].") + "[0]";

            String basePathOfXFAFile = StringUtils.substringBeforeLast(this.xfaPath, "/");

            //  changing all the backslashes to forward slashes
            xdpRef = StringUtils.replace(xdpRef, "\\", "/");
            xdpRef = StringUtils.substringBeforeLast(xdpRef, "#");
            xdpRef = basePathOfXFAFile +  "/" +xdpRef;
            //  normalize the path
            xdpRef = ResourceUtil.normalize(xdpRef);


            String query = "/jcr:root/content/dam/formsanddocuments//element(*, dam:Asset) \n" +
                    "[\n" +
                    "jcr:content/metadata/@xdpRef = '" + xdpRef  +
                    "'\n]";
            Iterator fragmentNodes = resourceResolver.findResources(query, "xpath");
            if (fragmentNodes.hasNext()) {
                Resource resource = fragmentNodes.next();
                fragRef = resource.getPath();
                Resource fMmetaDataNode = resource.getChild(GuideConstants.JCR_CONTENT_NODENAME)
                        .getChild(GuideConstants.METADATA_NODENAME);
                ValueMap valueMap = fMmetaDataNode.adaptTo(ValueMap.class);
                String fragmentModelRootFromMetaData = (String)valueMap.get(GuideConstants.FRAGMENT_MODEL_ROOT);
               if(StringUtils.contains(fragmentModelRootFromMetaData,fragmentModelRootFromUsehref )) {
                   input.put(GuideConstants.FRAG_REF, fragRef);
               }
            }
            if(!input.containsKey(GuideConstants.FRAG_REF)) {
                // only when we do not get fragRef
                // used to auto create fragment from API
                input.put(GuideConstants.USEHREF, xdpRef + "#" + fragmentModelRootFromUsehref);
            }

        } catch (Exception e) {
            logger.error("Error in handling usehref for fragment", e);
        }

    }

    /**
     * Wrapper method to avoid dependency on JSON impl
     * @param jsonStr
     * @return
     */
    public Map getFieldProperties(String jsonStr) {

        Map fieldProperties = new Hashtable();

        try {
            fieldProperties = getFieldProperties(null, new JSONObject(jsonStr));
        } catch (Exception e) {
            logger.error("Error while extracting Field Properties", e);
        }

        return fieldProperties;
    }

    public Hashtable getFieldProperties(Hashtable input, JSONObject fieldJson)
            throws Exception {
        if(fieldJson == null) {
            return null;
        }
        if(input == null) {
            input = new Hashtable();
        }
        input = getCommonProperties(input,fieldJson);
        String fieldUiType = (String)getOrElse(fieldJson,"ui.oneOfChild._class","defaultUi",true);
        String fieldValueType = (String)getOrElse(fieldJson,"value.oneOfChild._class",null,true);
        if("defaultUi".equals(fieldUiType) && fieldValueType != null) {
            fieldUiType = defaultFieldUiMap.get(fieldValueType);
        }
        if("imageEdit".equals(fieldUiType)) {
            String scribbleName = (String)getOrElse(fieldJson,"ui.extras.name",null,true);
            if("x-scribble-add-on".equals(scribbleName)) {
                fieldUiType = "scribble";
            }
        } else if ("dateTimeEdit".equals(fieldUiType) && ("time".equals(fieldValueType)
                    || "dateTime".equals(fieldValueType))) {
            // we do not support dateTime and time fields. They should appear as textfields
            fieldUiType = "textEdit";
        }
        String guideUiType[] = null;
        if(fieldUiType != null) {
            guideUiType = fieldUiRTMap.get(fieldUiType);
        }
        if(guideUiType != null && guideUiType.length == 2) {
            input.put(GuideConstants.SLING_RESOURCE_TYPE,guideUiType[0]);
            input.put("guideNodeClass",guideUiType[1]);

            putGuideProp(input, fieldJson,"mandatory","validate.nullTest","false",mandatoryConvertor);
            putGuideProp(input, fieldJson,"mandatoryMessage","validate.message.text(name=nullTest)._value",
                    null,null);
            putGuideProp(input, fieldJson,"_value","value.oneOfChild._value",null,null);
            putGuideProp(input, fieldJson,"validateExpMessage","validate.message.text(name=scriptTest)._value"
                    ,null,null);
            putGuideProp(input, fieldJson,"validatePictureClauseMessage",
                    "validate.message.text(name=formatTest)._value",null,null);
            putGuideProp(input, fieldJson,"assistPriority","assist.speak.priority",null,assistPriorityConvertor);
            putGuideProp(input, fieldJson,"custom","assist.speak._value",null,null);
            putGuideProp(input, fieldJson,"shortDescription","assist.toolTip._value",null,null);
            if(!("time".equals(fieldValueType) || "dateTime".equals(fieldValueType))) {
                // picture clause for time and datetime is not supported, ignoring them
                String prop = (String)getOrElse(fieldJson,"format.picture._value",null,true);
                if(prop != null && prop.length() > 0) {
                    input.put("displayPictureClause", prop);
                }
                prop = (String) getOrElse(fieldJson,"validate.picture._value",null,true);
                if(prop != null && prop.length() > 0) {
                    input.put("validatePictureClause", prop);
                }
            }
            if("guideScribble".equals(guideUiType[1])){
                input.put("aspectRatio", String.valueOf(calculateAspectRatio(fieldJson)));
            }
            // edit pattern has been implemented specifically for date picker
            if("guideDatePicker".equals(guideUiType[1])){
                String prop = (String)getOrElse(fieldJson,"ui.picture._value",null,true);
                if(prop != null && prop.length() > 0) {
                    input.put("editPictureClause", prop);
                }
            }
            if("guideCheckBox".equals(guideUiType[1])) {
                String[] option = {this.convertItemsToOptions(fieldJson)};
                input.put("options",option);
            }  else if("guideNumericBox".equals(guideUiType[1])) {
                input.put("dataType", fieldValueType);
                putGuideProp(input, fieldJson, "leadDigits", "value.oneOfChild.fracDigits", null,null);
                putGuideProp(input, fieldJson, "leadDigits", "value.oneOfChild.leadDigits", null,null);
            } else if("guideTextBox".equals(guideUiType[1])) {
                if("exData".equals(fieldValueType)) {
                    input.put("allowRichText", true);
                }
                Hashtable multiLineConvertor = new Hashtable();
                multiLineConvertor.put("1","true");
                putGuideProp(input, fieldJson, "multiLine", "ui.textEdit.multiLine", null, multiLineConvertor);
                putGuideProp(input, fieldJson, "maxChars", "value.text.maxChars", null, null);
            } else if("guideDropDownList".equals(guideUiType[1])) {
                putGuideProp(input, fieldJson, "multiSelect", "ui.choiceList.open", null, multiSelectConvertor);
                String[] options = this.getDropDownOptions(fieldJson);
                if(options.length > 0) {
                    input.put("options", options);
                }
            }
        } else {
            logger.warn("unrecognized type, treating it as text: " + fieldUiType + " : " + fieldUiType);   //TODO: log
            input.put(GuideConstants.SLING_RESOURCE_TYPE, GuideConstants.RT_GUIDETEXTBOX);
            input.put("guideNodeClass", "guideTextBox");
        }
        return input;
    }

    public static double calculateAspectRatio(final JSONObject fieldJson)throws Exception{
        double ratio, height = MeasurementUtils.convertToPx((String)fieldJson.get("h"));
        if((height-GuideConstants.DEFAULT_HEIGHT) > 0){
            ratio = MeasurementUtils.convertToPx((String)fieldJson.get("w"))/height;
        } else {
            ratio = (double)GuideConstants.DEFAULT_ASPECT_RATIO;
        }
        return ratio ;
    }

    public Hashtable getExclGroupProperties(Hashtable input,
                                                           JSONObject exclGroupJson) throws Exception {
        if(exclGroupJson == null) {
            return null;
        }
        if(input == null) {
            input = new Hashtable();
        }
        input = getCommonProperties(input, exclGroupJson);
        input.put(GuideConstants.SLING_RESOURCE_TYPE, GuideConstants.RT_GUIDERADIOBUTTON);
        input.put("guideNodeClass", "guideRadioButton");
        if (exclGroupJson.has("children") && exclGroupJson.get("children") instanceof JSONArray) {
            JSONArray children = exclGroupJson.getJSONArray("children");
            ArrayList options = new ArrayList();
            String value = null;
            for (int i = 0; i < children.length(); i++) {
                JSONObject child = children.getJSONObject(i);
                if ("field".equals(child.getString("_class"))) {
                    options.add(convertItemsToOptions(child));
                    value = (String)getOrElse(child, "value.oneOfChild._value", value, true);
                }
            }
            input.put("options", options.toArray(new String[options.size()]));
            if(value != null) {
                input.put("_value", value);
            }
            putGuideProp(input, exclGroupJson, "mandatory", "validate.nullTest", "false", mandatoryConvertor);
            putGuideProp(input, exclGroupJson,"mandatoryMessage","validate.message.text(name=nullTest)._value", null, null);
        }
        return input;
    }

    /**
     * Wrapper method to avoid dependency on JSON impl
     *
     * @param jsonStr
     * @return
     */
    public Map getDrawProperties(String jsonStr) {

        Map drawProperties = new Hashtable();

        try {
            drawProperties = getDrawProperties(null, new JSONObject(jsonStr));
        } catch (Exception e) {
            logger.error("Error while extracting Draw Properties", e);
        }

        return drawProperties;
    }

    public Hashtable getDrawProperties(Hashtable input, JSONObject drawJson)
            throws Exception {
        if(drawJson == null) {
            return null;
        }
        if(input == null) {
            input = new Hashtable();
        }
        input = getCommonProperties(input, drawJson);
        String drawUiType = (String)getOrElse(drawJson,"ui.oneOfChild._class","defaultUi",true);
        String drawValueType = (String)getOrElse(drawJson,"value.oneOfChild._class",null,true);
        if("defaultUi".equals(drawUiType) && drawValueType != null) {
            drawUiType = defaultFieldUiMap.get(drawValueType);
        }
        String[] guideUiType = null;
        if(drawUiType != null) {
            guideUiType = drawUiRTMap.get(drawUiType);
        }
        if(guideUiType != null && guideUiType.length == 2) {
            input.put(GuideConstants.SLING_RESOURCE_TYPE, guideUiType[0]);
            input.put("guideNodeClass", guideUiType[1]);
            if ("guideTextDraw".equals(guideUiType[1])) {
                String textValue = (String) this.getOrElse(drawJson, "value." + drawValueType + "._value", "", true);
                input.put("_value", StringEscapeUtils.escapeHtml4(textValue));
                if ("text".equals(drawValueType)) {
                    input.put("textIsRich", false);
                } else if ("exData".equals(drawValueType)) {
                    input.put("textIsRich", true);
                }
            }
        } else {
            logger.warn("Unsupported draw type:" + drawUiType + ":" + drawValueType);
        }
        return input;
    }

    public String getTitle(JSONObject jsonObject) throws Exception {
        String title = null;
        if ("field".equals(jsonObject.getString("_class"))) {
            title = (String) this.getOrElse(jsonObject, "caption.value.text._value", null, true);
        }
        if (title == null && jsonObject.has("name")) {
            String nodeName = jsonObject.getString("name");
            title = NameUtils.humanize(nodeName);
        }
        return title;
    }

    public String getOrGenerateName(JSONObject jsonObject) throws Exception {
        String name = (String) this.getOrElse(jsonObject, "name", null, true);
        if (name == null || name.isEmpty()) {
            name = UNNAMED_PREFIX + unnamedCount++ + "_" + jsonObject.getString("_class");
        }
        return name;
    }

    private boolean putGuideProp(Hashtable input, JSONObject obj, String guideProp,
                                 String xfaProp, String def, Hashtable convertor)
            throws Exception{
        String val = (String) this.getOrElse(obj, xfaProp, null, true);
        val = convertor == null ? val
                : val == null ? val
                : convertor.get(val);
        val = val == null ? def : val;
        if(val != null) {
            input.put(guideProp, val);
            return true;
        }
        return false;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy