org.drools.workbench.screens.scenariosimulation.client.collectioneditor.CollectionPresenter.java Source code

Java tutorial

Introduction

Here is the source code for org.drools.workbench.screens.scenariosimulation.client.collectioneditor.CollectionPresenter.java

Source

/*
 * Copyright 2019 Red Hat, Inc. and/or its affiliates.
 *
 * 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.drools.workbench.screens.scenariosimulation.client.collectioneditor;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import javax.inject.Inject;

import com.google.gwt.dom.client.LIElement;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.UListElement;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import org.drools.workbench.screens.scenariosimulation.client.collectioneditor.editingbox.ItemEditingBoxPresenter;
import org.drools.workbench.screens.scenariosimulation.client.collectioneditor.editingbox.KeyValueEditingBoxPresenter;
import org.drools.workbench.screens.scenariosimulation.client.popup.ConfirmPopupPresenter;
import org.drools.workbench.screens.scenariosimulation.client.popup.ScenarioConfirmationPopupPresenter;
import org.drools.workbench.screens.scenariosimulation.client.resources.i18n.ScenarioSimulationEditorConstants;
import org.drools.workbench.screens.scenariosimulation.client.utils.ViewsProvider;

public class CollectionPresenter implements CollectionView.Presenter {

    @Inject
    protected ItemElementPresenter listElementPresenter;

    @Inject
    protected KeyValueElementPresenter mapElementPresenter;

    @Inject
    protected ViewsProvider viewsProvider;

    @Inject
    protected ItemEditingBoxPresenter listEditingBoxPresenter;

    @Inject
    protected KeyValueEditingBoxPresenter mapEditingBoxPresenter;

    @Inject
    protected ScenarioConfirmationPopupPresenter scenarioConfirmationPopupPresenter;

    @Inject
    protected ConfirmPopupPresenter confirmPopupPresenter;

    /**
     * <code>Map</code> used to pair the <code>Map</code> with instance' <b>simple properties</b> classes with a specific <b>key</b> representing the property, i.e Classname#propertyname (e.g Author#books)
     */
    protected Map<String, Map<String, String>> simplePropertiesMap = new HashMap<>();

    /**
     * <code>Map</code> used to pair the <code>Map</code> with instance' <b>expandable properties</b> classes with a specific <b>key</b> representing the property, i.e Classname#propertyname (e.g Author#books)
     */
    protected Map<String, Map<String, Map<String, String>>> expandablePropertiesMap = new HashMap<>();

    protected CollectionView collectionView;

    protected LIElement objectSeparatorLI;

    @Override
    public void initListStructure(String key, Map<String, String> simplePropertiesMap,
            Map<String, Map<String, String>> expandablePropertiesMap, CollectionView collectionView) {
        commonInit(key, collectionView);
        this.simplePropertiesMap.put(key, simplePropertiesMap);
        this.expandablePropertiesMap.put(key, expandablePropertiesMap);
        listEditingBoxPresenter.setCollectionEditorPresenter(this);
        listElementPresenter.setCollectionEditorPresenter(this);
        listElementPresenter.onToggleRowExpansion(false);
    }

    @Override
    public void initMapStructure(String key, Map<String, String> keyPropertyMap,
            Map<String, String> valuePropertyMap, CollectionView collectionView) {
        commonInit(key, collectionView);
        simplePropertiesMap.put(key + "#key", keyPropertyMap);
        simplePropertiesMap.put(key + "#value", valuePropertyMap);
        mapEditingBoxPresenter.setCollectionEditorPresenter(this);
        mapElementPresenter.setCollectionEditorPresenter(this);
        mapElementPresenter.onToggleRowExpansion(false);
    }

    @Override
    public void setValue(String jsonString) {
        if (jsonString == null || jsonString.isEmpty()) {
            return;
        }
        JSONValue jsonValue = getJSONValue(jsonString);
        if (collectionView.isListWidget()) {
            populateList(jsonValue);
        } else {
            populateMap(jsonValue);
        }
    }

    @Override
    public void showEditingBox() {
        String key = collectionView.getEditorTitle().getInnerText();
        if (collectionView.isListWidget()) {
            LIElement editingBox = listEditingBoxPresenter.getEditingBox(key, simplePropertiesMap.get(key),
                    expandablePropertiesMap.get(key));
            collectionView.getElementsContainer().appendChild(editingBox);
        } else {
            LIElement editingBox = mapEditingBoxPresenter.getEditingBox(key, simplePropertiesMap.get(key + "#key"),
                    simplePropertiesMap.get(key + "#value"));
            collectionView.getElementsContainer().appendChild(editingBox);
        }
        toggleEditingStatus(true);
    }

    @Override
    public void onToggleRowExpansion(boolean isShown) {
        collectionView.toggleRowExpansion();
        if (collectionView.isListWidget()) {
            listElementPresenter.onToggleRowExpansion(isShown);
        } else {
            mapElementPresenter.onToggleRowExpansion(isShown);
        }
    }

    @Override
    public void updateRowExpansionStatus(boolean isShown) {
        collectionView.updateRowExpansionStatus(isShown);
    }

    @Override
    public void addListItem(Map<String, String> simplePropertiesValues,
            Map<String, Map<String, String>> expandablePropertiesValues) {
        final UListElement elementsContainer = collectionView.getElementsContainer();
        String itemId = String.valueOf(elementsContainer.getChildCount() - 1);
        final LIElement itemElement = listElementPresenter.getItemContainer(itemId, simplePropertiesValues,
                expandablePropertiesValues);
        elementsContainer.appendChild(itemElement);
        toggleEditingStatus(false);
    }

    @Override
    public void addMapItem(Map<String, String> keyPropertiesValues, Map<String, String> valuePropertiesValues) {
        final UListElement elementsContainer = collectionView.getElementsContainer();
        String itemId = String.valueOf(elementsContainer.getChildCount() - 1);
        final LIElement itemElement = mapElementPresenter.getKeyValueContainer(itemId, keyPropertiesValues,
                valuePropertiesValues);
        elementsContainer.appendChild(itemElement);
        toggleEditingStatus(false);
    }

    @Override
    public void save() {
        try {
            String updatedValue;
            if (collectionView.isListWidget()) {
                updatedValue = getListValue();
            } else {
                updatedValue = getMapValue();
            }
            collectionView.updateValue(updatedValue);
        } catch (IllegalStateException e) {
            confirmPopupPresenter.show(ScenarioSimulationEditorConstants.INSTANCE.collectionError(),
                    e.getMessage());
        }
    }

    @Override
    public void remove() {
        org.uberfire.mvp.Command okRemoveCommand = this::okRemoveCommandMethod;
        scenarioConfirmationPopupPresenter.show(
                ScenarioSimulationEditorConstants.INSTANCE.removeCollectionMainTitle(),
                ScenarioSimulationEditorConstants.INSTANCE.removeCollectionMainQuestion(),
                ScenarioSimulationEditorConstants.INSTANCE.removeCollectionText1(),
                ScenarioSimulationEditorConstants.INSTANCE.removeCollectionQuestion(),
                ScenarioSimulationEditorConstants.INSTANCE.removeCollectionWarningText(),
                ScenarioSimulationEditorConstants.INSTANCE.remove(), okRemoveCommand);
    }

    @Override
    public void toggleEditingStatus(boolean toDisable) {
        collectionView.getAddItemButton().setDisabled(toDisable);
        collectionView.getCancelButton().setDisabled(toDisable);
        collectionView.getRemoveButton().setDisabled(toDisable);
        collectionView.getSaveButton().setDisabled(toDisable);
        mapElementPresenter.toggleEditingStatus(toDisable);
        listElementPresenter.toggleEditingStatus(toDisable);
    }

    // Indirection add for test
    protected void okRemoveCommandMethod() {
        if (collectionView.isListWidget()) {
            listElementPresenter.remove();
        } else {
            mapElementPresenter.remove();
        }
        collectionView.updateValue(null);
        collectionView.close();
    }

    protected void commonInit(String key, CollectionView collectionView) {
        this.collectionView = collectionView;
        String propertyName = key.substring(key.lastIndexOf("#") + 1);
        this.collectionView.getEditorTitle().setInnerText(key);
        this.collectionView.getPropertyTitle().setInnerText(propertyName);
        objectSeparatorLI = collectionView.getObjectSeparator();
        objectSeparatorLI.addClassName("kie-object-list");
        objectSeparatorLI.getStyle().setPadding(5, Style.Unit.PX);
    }

    protected void populateList(JSONValue jsonValue) {
        final JSONArray array = jsonValue.isArray();
        for (int i = 0; i < array.size(); i++) {
            final JSONObject jsonObject = array.get(i).isObject();
            final Map<String, String> propertiesValues = getSimplePropertiesMap(jsonObject);
            final Map<String, Map<String, String>> expandablePropertiesValues = getExpandablePropertiesValues(
                    jsonObject);
            addListItem(propertiesValues, expandablePropertiesValues);
        }
    }

    protected void populateMap(JSONValue jsonValue) {
        final JSONObject jsValueObject = jsonValue.isObject();
        jsValueObject.keySet().forEach(key -> {
            Map<String, String> keyPropertiesValues = new HashMap<>();
            Map<String, String> valuePropertiesValues = new HashMap<>();
            final JSONObject jsonObjectKey = getJSONObject(key);
            if (jsonObjectKey == null) {
                keyPropertiesValues.put("value", key);
            } else {
                jsonObjectKey.keySet().forEach(propertyName -> keyPropertiesValues.put(propertyName,
                        jsonObjectKey.get(propertyName).isString().stringValue()));
            }
            JSONObject jsonObjectValue = jsValueObject.get(key).isObject();
            if (jsonObjectValue != null) {
                jsonObjectValue.keySet().forEach(propertyName -> valuePropertiesValues.put(propertyName,
                        jsonObjectValue.get(propertyName).isString().stringValue()));
            } else {
                valuePropertiesValues.put("value", jsValueObject.get(key).toString());
            }
            addMapItem(keyPropertiesValues, valuePropertiesValues);
        });
    }

    protected JSONObject getJSONObject(String jsonString) {
        try {
            return getJSONValue(jsonString).isObject();
        } catch (Exception e) {
            return null;
        }
    }

    protected JSONValue getJSONValue(String jsonString) {
        try {
            return JSONParser.parseStrict(jsonString);
        } catch (Exception e) {
            return null;
        }
    }

    protected String getListValue() {
        Map<String, Map<String, String>> simpleItemsProperties = listElementPresenter.getSimpleItemsProperties();
        Map<String, Map<String, Map<String, String>>> nestedItemsProperties = listElementPresenter
                .getExpandableItemsProperties();
        JSONArray jsonArray = new JSONArray();
        AtomicInteger counter = new AtomicInteger();
        simpleItemsProperties.forEach((itemId, simpleProperties) -> {
            final JSONObject jsonObject = getJSONObject(simpleProperties);
            Map<String, Map<String, String>> nestedProperties = nestedItemsProperties.get(itemId);
            if (nestedProperties != null) {
                nestedProperties.forEach((nestedPropertyName, nestedPropertyValues) -> {
                    JSONObject nestedJSONObject = getJSONObject(nestedPropertyValues);
                    jsonObject.put(nestedPropertyName, nestedJSONObject);
                });
            }
            jsonArray.set(counter.getAndIncrement(), jsonObject);
        });
        return jsonArray.toString();
    }

    /**
     * Translates a <code>Map</code> to a <code>JSONObject</code>
     * @param properties
     * @return
     */
    protected JSONObject getJSONObject(Map<String, String> properties) {
        JSONObject toReturn = new JSONObject();
        properties.forEach(
                (propertyName, propertyValue) -> toReturn.put(propertyName, new JSONString(propertyValue)));
        return toReturn;
    }

    /**
     *
     * @param jsonObject
     * @return a <code>Map</code> with <b>propertyName/propertyValue</b>
     */
    protected Map<String, String> getSimplePropertiesMap(JSONObject jsonObject) {
        Map<String, String> toReturn = new HashMap<>();
        jsonObject.keySet().forEach(propertyName -> {
            final JSONValue jsonValue = jsonObject.get(propertyName);
            if (jsonValue.isString() != null) {
                toReturn.put(propertyName, jsonValue.isString().stringValue());
            }
        });
        return toReturn;
    }

    /**
     *
     * @param jsonObject
     * @return a <code>Map</code> where the <b>key</b> is the name of the complex property, and the value is a a <code>Map</code> with
     * the nested <b>propertyName/propertyValue</b>
     */
    protected Map<String, Map<String, String>> getExpandablePropertiesValues(JSONObject jsonObject) {
        Map<String, Map<String, String>> toReturn = new HashMap<>();
        jsonObject.keySet().forEach(propertyName -> {
            final JSONValue jsonValue = jsonObject.get(propertyName);
            if (jsonValue.isObject() != null) {
                final Map<String, String> simplePropertiesMap = getSimplePropertiesMap(jsonValue.isObject());
                toReturn.put(propertyName, simplePropertiesMap);
            }
        });
        return toReturn;
    }

    /**
     * @return
     */
    protected String getMapValue() throws IllegalStateException {
        Map<Map<String, String>, Map<String, String>> itemsProperties = mapElementPresenter.getItemsProperties();
        JSONObject toReturnModel = new JSONObject();
        itemsProperties.forEach((keyPropertiesValues, valuePropertiesMap) -> {
            String jsonKey;
            if (keyPropertiesValues.size() == 1) { // simple object - TO CHECK WRONG ASSUMPTION
                jsonKey = keyPropertiesValues.values().iterator().next();
            } else {
                JSONObject nestedKey = new JSONObject();
                keyPropertiesValues.forEach((propertyName, propertyValue) -> nestedKey.put(propertyName,
                        new JSONString(propertyValue)));
                jsonKey = nestedKey.toString();
            }
            JSONObject nestedValue = new JSONObject();
            valuePropertiesMap.forEach(
                    (propertyName, propertyValue) -> nestedValue.put(propertyName, new JSONString(propertyValue)));
            toReturnModel.put(jsonKey, nestedValue);
        });
        return toReturnModel.toString();
    }
}