XFAJSONTransformer.java 14.8 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.commons.json.JSONArray
 *  org.apache.sling.commons.json.JSONObject
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.aemds.guide.xfa;

import com.adobe.aemds.guide.service.GuideException;
import com.adobe.aemds.guide.utils.CustomJSONWriter;
import com.adobe.aemds.guide.xfa.XFAJSONTransformerUtil;
import com.adobe.aemds.guide.xfa.XFAJSONWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.commons.json.JSONArray;
import org.apache.sling.commons.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/*
 * This class specifies class file version 49.0 but uses Java 6 signatures.  Assumed Java 6.
 */
public class XFAJSONTransformer {
    private Logger logger = LoggerFactory.getLogger(XFAJSONTransformer.class);
    private static List<String> panelCandidates = Arrays.asList("area", "subform", "subformSet");
    private static List<String> leafCandidates = Arrays.asList("draw", "exclGroup", "field");
    private static List<String> unsupportedUiTypes = Arrays.asList("barcode", "exObject", "signature");
    private static List<String> unsupportedValueTypes = Arrays.asList("arc", "line", "rectangle");
    private JSONObject xfaJson;
    private XFAJSONWriter jsonWriter;
    private StringWriter stringWriter;
    private Hashtable<String, String> xfaObjects;
    private XFAJSONTransformerUtil transformUtil;
    private Map<String, Integer> currentContainerChildren = new HashMap<String, Integer>();
    private ResourceResolver resourceResolver = null;

    public XFAJSONTransformer(JSONObject xfaJson) {
        this(xfaJson, null, "");
    }

    public XFAJSONTransformer(JSONObject xfaJson, ResourceResolver resourceResolver, String xfaPath) {
        this.xfaJson = xfaJson;
        this.stringWriter = new StringWriter();
        this.jsonWriter = new XFAJSONWriter(this.stringWriter);
        this.transformUtil = new XFAJSONTransformerUtil(resourceResolver, xfaPath);
    }

    public XFAJSONTransformer(JSONObject xfaJson, boolean saveObjects, ResourceResolver resourceResolver, String xfaPath) {
        this(xfaJson, resourceResolver, xfaPath);
        this.xfaObjects = new Hashtable();
    }

    public boolean acceptObject(JSONObject jsonObject) throws Exception {
        String childType = jsonObject.getString("_class");
        if (!panelCandidates.contains(childType) && !leafCandidates.contains(childType)) {
            return false;
        }
        if (leafCandidates.contains(childType) && !this.acceptLeaf(jsonObject)) {
            return false;
        }
        return true;
    }

    public String transform() {
        try {
            JSONObject rootSubformJson = (JSONObject)this.transformUtil.getOrElse(this.xfaJson, "form.subform", null, false);
            String rootSubformName = this.transformUtil.getOrGenerateName(rootSubformJson);
            this.jsonWriter.startObject(null).startObject(rootSubformName);
            this.transformContainer(rootSubformJson);
            this.jsonWriter.completeObject(rootSubformName).completeObject(null);
            return this.stringWriter.toString();
        }
        catch (Exception e) {
            this.logger.error("Error in transforming xfa json:" + e.getMessage(), (Throwable)e);
            throw new GuideException(e);
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    private void transformChildren(JSONObject containerJson, boolean isChildOfTable) throws Exception {
        if (containerJson.has("children") && containerJson.get("children") instanceof JSONArray) {
            Map<String, Integer> oldChildMap = this.currentContainerChildren;
            this.currentContainerChildren = new HashMap<String, Integer>();
            try {
                JSONObject lastInstanceManager = null;
                this.jsonWriter.startObject("items");
                JSONArray containerChildren = containerJson.getJSONArray("children");
                for (int i = 0; i < containerChildren.length(); ++i) {
                    JSONObject childJson = containerChildren.getJSONObject(i);
                    String childType = childJson.getString("_class");
                    if (!"subform".equals(childType)) {
                        lastInstanceManager = null;
                    }
                    if ("instanceManager".equals(childType)) {
                        lastInstanceManager = childJson;
                        continue;
                    }
                    if (!this.acceptObject(childJson)) continue;
                    String childName = this.transformUtil.getOrGenerateName(childJson);
                    int childIndex = -1;
                    if (this.currentContainerChildren.containsKey(childName)) {
                        childIndex = this.currentContainerChildren.get(childName);
                    }
                    this.currentContainerChildren.put(childName, ++childIndex);
                    childName = childName + (childIndex == 0 ? "" : Integer.valueOf(childIndex));
                    this.jsonWriter.startObject(childName);
                    if (panelCandidates.contains(childType)) {
                        if (isChildOfTable && childJson.has("layout") && "row".equals((String)childJson.get("layout"))) {
                            this.transformTableChild(childJson);
                        } else {
                            this.transformContainer(childJson);
                        }
                        if (lastInstanceManager != null) {
                            if (lastInstanceManager.has("min")) {
                                this.jsonWriter.key("minOccur").value(lastInstanceManager.getInt("min"));
                            }
                            if (lastInstanceManager.has("max")) {
                                this.jsonWriter.key("maxOccur").value(lastInstanceManager.getInt("max"));
                            }
                        }
                    } else if ("exclGroup".equals(childType)) {
                        this.transformExclGroup(childJson, isChildOfTable);
                    } else if ("draw".equals(childType)) {
                        this.transformDraw(childJson, isChildOfTable);
                    } else {
                        this.transformField(childJson, isChildOfTable);
                    }
                    this.jsonWriter.completeObject(childName);
                }
                this.jsonWriter.completeObject("items");
            }
            finally {
                this.currentContainerChildren = oldChildMap;
            }
        }
    }

    private void transformContainer(JSONObject containerJson, boolean isJsonTable) throws Exception {
        if (isJsonTable) {
            this.transformTable(containerJson);
        } else {
            this.transformPanel(containerJson);
        }
        this.jsonWriter.startObject("layout");
        Hashtable<String, Object> hash = this.transformUtil.getLayoutProperties(null, isJsonTable);
        this.jsonWriter.writeProperties(hash);
        this.jsonWriter.completeObject("layout");
        this.transformChildren(containerJson, isJsonTable);
    }

    public boolean checkIfSupportedTable(JSONObject containerJson) throws Exception {
        return this.checkIfSupportedTable(containerJson, 0);
    }

    private boolean checkIfSupportedTable(JSONObject containerJson, int tableHeaderCount) throws Exception {
        if (containerJson.has("children") && containerJson.get("children") instanceof JSONArray) {
            JSONArray containerChildren = containerJson.getJSONArray("children");
            for (int i = 0; i < containerChildren.length(); ++i) {
                boolean isValidTable;
                JSONObject childJson = containerChildren.getJSONObject(i);
                String childType = childJson.getString("_class");
                if (!this.acceptObject(childJson) || !panelCandidates.contains(childType)) continue;
                if (childJson.has("layout") && "table".equals((String)childJson.get("layout"))) {
                    return false;
                }
                if (tableHeaderCount == 0) {
                    if (this.checkIfContainerIsTableHeader(childJson)) {
                        if (isValidTable = this.checkIfSupportedTable(childJson, tableHeaderCount++)) continue;
                        return false;
                    }
                    return false;
                }
                if (this.checkIfContainerIsTableHeader(childJson)) {
                    return false;
                }
                isValidTable = this.checkIfSupportedTable(childJson, tableHeaderCount);
                if (isValidTable) continue;
                return false;
            }
        }
        return true;
    }

    private void transformContainer(JSONObject containerJson) throws Exception {
        String layout;
        boolean bIsJsonTable = false;
        if (containerJson.has("layout") && containerJson.get("layout") instanceof String && (layout = (String)containerJson.get("layout")) != null && layout.length() > 0 && "table".equals(layout)) {
            bIsJsonTable = this.checkIfSupportedTable(containerJson, 0);
        }
        this.transformContainer(containerJson, bIsJsonTable);
    }

    private boolean checkIfContainerIsTableHeader(JSONObject containerJson) throws Exception {
        boolean isHeader = false;
        JSONArray containerChildren = containerJson.getJSONArray("children");
        for (int i = 0; i < containerChildren.length(); ++i) {
            JSONObject childJson = containerChildren.getJSONObject(i);
            String childType = childJson.getString("_class");
            if (!"assist".equals(childType)) continue;
            isHeader = "TH".equals(childJson.getString("role"));
            break;
        }
        return isHeader;
    }

    private void transformTableChild(JSONObject containerJson) throws Exception {
        Hashtable<String, Object> hash = this.transformUtil.getCommonProperties(null, containerJson);
        boolean bIsHeader = this.checkIfContainerIsTableHeader(containerJson);
        if (bIsHeader) {
            hash.put("sling:resourceType", "fd/af/components/tableHeader");
        } else {
            hash.put("sling:resourceType", "fd/af/components/tableRow");
        }
        hash.put("guideNodeClass", "guideTableRow");
        if (hash.containsKey("bindRef")) {
            this.transformObjectFromHash(hash);
        } else {
            this.logger.warn("XFA Element for: " + hash.get("jcr:title") + " does not contain bindRef.");
        }
        hash.clear();
        this.jsonWriter.startObject("layout");
        String layoutResourceType = null;
        layoutResourceType = bIsHeader ? "fd/af/layouts/table/headerLayout" : "fd/af/layouts/table/rowLayout";
        hash.put("jcr:primaryType", "nt:unstructured");
        hash.put("sling:resourceType", layoutResourceType);
        this.jsonWriter.writeProperties(hash);
        this.jsonWriter.completeObject("layout");
        this.transformChildren(containerJson, true);
    }

    private String getJsonStringFromHash(Hashtable<String, Object> hash) {
        StringWriter writer = new StringWriter();
        XFAJSONWriter jsonWriter = new XFAJSONWriter(writer);
        jsonWriter.startObject(null);
        jsonWriter.writeProperties(hash);
        jsonWriter.completeObject(null);
        return writer.toString();
    }

    public void transformTable(JSONObject tableJson) throws Exception {
        Hashtable<String, Object> hash = this.transformUtil.getCommonProperties(null, tableJson);
        if ((hash = this.transformUtil.getTableProperties(hash)).containsKey("bindRef")) {
            this.transformObjectFromHash(hash);
        } else {
            this.logger.warn("XFA Element for: " + hash.get("jcr:title") + " does not contain bindRef.");
        }
    }

    private void transformPanel(JSONObject panelJson) throws Exception {
        Hashtable<String, Object> hash = this.transformUtil.getCommonProperties(null, panelJson);
        if ((hash = this.transformUtil.getPanelProperties(hash)).containsKey("bindRef")) {
            this.transformObjectFromHash(hash);
        } else {
            this.logger.warn("XFA Element for: " + hash.get("jcr:title") + " does not contain bindRef.");
        }
    }

    private void transformObjectFromHash(Hashtable<String, Object> hash) {
        String jsonString = this.getJsonStringFromHash(hash);
        if (this.xfaObjects != null) {
            this.xfaObjects.put((String)hash.get("bindRef"), jsonString);
        }
        hash.put("xfajson", jsonString);
        this.jsonWriter.writeProperties(hash);
    }

    private void transformField(JSONObject fieldJson, boolean isChildOfTable) throws Exception {
        Hashtable<String, Object> input = this.transformUtil.getFieldProperties(null, fieldJson);
        if (isChildOfTable && fieldJson.has("colSpan")) {
            input.put("colspan", fieldJson.get("colSpan"));
        }
        this.transformObjectFromHash(input);
    }

    private void transformDraw(JSONObject drawJson, boolean isChildOfTable) throws Exception {
        Hashtable<String, Object> input = this.transformUtil.getDrawProperties(null, drawJson);
        if (isChildOfTable && drawJson.has("colSpan")) {
            input.put("colspan", drawJson.get("colSpan"));
        }
        this.transformObjectFromHash(input);
    }

    private void transformExclGroup(JSONObject exclGroupJson, boolean isChildOfTable) throws Exception {
        Hashtable<String, Object> input = this.transformUtil.getExclGroupProperties(null, exclGroupJson);
        if (isChildOfTable && exclGroupJson.has("colSpan")) {
            input.put("colspan", exclGroupJson.get("colSpan"));
        }
        this.transformObjectFromHash(input);
    }

    public final Hashtable<String, String> getXFAObjects() {
        return this.xfaObjects;
    }

    public boolean acceptLeaf(JSONObject leafJson) throws Exception {
        String childType = leafJson.getString("_class");
        if ("draw".equals(childType) || "field".equals(childType)) {
            String valueType;
            String fieldUiType = (String)this.transformUtil.getOrElse(leafJson, "ui.oneOfChild._class", null, true);
            if (unsupportedUiTypes.contains(fieldUiType)) {
                return false;
            }
            if ("defaultUi".equals(fieldUiType) && unsupportedValueTypes.contains(valueType = (String)this.transformUtil.getOrElse(leafJson, "value.oneOfChild._class", null, true))) {
                return false;
            }
            return true;
        }
        if ("exclGroup".equals(childType)) {
            return true;
        }
        return false;
    }
}