com.qualogy.qafe.gwt.client.component.QTree.java Source code

Java tutorial

Introduction

Here is the source code for com.qualogy.qafe.gwt.client.component.QTree.java

Source

/**
 * Copyright 2008-2015 Qualogy Solutions B.V.
 *
 * 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 com.qualogy.qafe.gwt.client.component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.UIObject;
import com.qualogy.qafe.gwt.client.ui.renderer.RendererHelper;
import com.qualogy.qafe.gwt.client.vo.functions.DataContainerGVO;
import com.qualogy.qafe.gwt.client.vo.ui.TreeItemGVO;

public class QTree extends Tree implements HasData {

    public static final String NODE = "id";
    public static final String NODE_TYPE = "fqn";
    public static final String PARENT_NODE = "parent";
    public static final String KEY_DELIMITER = "|";

    private class TreeHelper implements SelectionHandler<TreeItem> {

        public void onSelection(SelectionEvent<TreeItem> event) {
            doItemSelection(event);
        }
    }

    private Map<String, Object> items = new HashMap<String, Object>();
    private Map<String, String> key2Parent = new LinkedHashMap<String, String>();
    private Map<UIObject, Object> uiToKey = new HashMap<UIObject, Object>();
    private Map<Object, UIObject> keyToUI = new HashMap<Object, UIObject>();
    private Map<Object, Object> keyToUIModel = new HashMap<Object, Object>();

    private TreeHelper helper = new TreeHelper();
    private TreeItem selectedItem = null;
    private boolean structuredData;
    private TreeItem rootItem;
    private boolean showRootItem = true;

    public QTree(TreeItem rootItem) {
        this(rootItem, true);
    }

    public QTree(TreeItem rootItem, boolean showRootItem) {
        this.rootItem = rootItem;
        this.showRootItem = showRootItem;
        if (showRootItem) {
            super.addItem(rootItem);
        }
        addSelectionHandler(helper);
    }

    @Override
    public void addItem(TreeItem item) {
        addItem(item, null);
    }

    public void addItem(TreeItem item, TreeItem parent) {
        if (parent != null) {
            parent.addItem(item);
        } else {
            if (showRootItem) {
                getItem(0).addItem(item);
            } else {
                super.addItem(item);
            }
        }
    }

    public Object getData() {
        List data = null;
        if (selectedItem != null) {
            Object key = uiToKey.get(selectedItem);
            if ((key != null) || ((key == null) && isRootItem(selectedItem))) {
                data = new ArrayList();
                if (key != null) {
                    Object uiModel = keyToUIModel.get(key);
                    data.add(uiModel);
                }

                List itemList = null;

                populateData(data, key, structuredData);

            }
        }
        return data;
    }

    private boolean isRootItem(TreeItem treeItem) {
        return (rootItem == treeItem);
    }

    private void populateData(List data, Object key, boolean structured) {
        Object uiModel;
        Iterator<String> itrKey = key2Parent.keySet().iterator();
        while (itrKey.hasNext()) {
            String nodeKey = itrKey.next();
            String parentKey = key2Parent.get(nodeKey);
            if ((parentKey == key) || ((parentKey != null) && parentKey.equals(key))) {
                uiModel = keyToUIModel.get(nodeKey);
                data.add(uiModel);

                // in case of structured data the model itself contains the child items in it ,
                // so we have child items and relation implicitly.
                if (!structured) {
                    populateData(data, nodeKey, structured);
                }
            }
        }
    }

    public void setData(Object data, String action, Object mapping) {
        List itemList = null;
        if (data instanceof Map) {
            itemList = new ArrayList();
            itemList.add(data);
        } else if (data instanceof List) {
            itemList = (List) data;
        }
        if (isSetAction(action)) {
            clearAll();
        }
        processItems(itemList, action, mapping);
    }

    private void clearAll() {
        keyToUI.clear();
        keyToUIModel.clear();
        key2Parent.clear();
        uiToKey.clear();

        clearItems();
    }

    private void clearItems() {
        if (showRootItem) {
            TreeItem rootItem = getItem(0);
            if (rootItem != null) {
                int childCount = rootItem.getChildCount();
                for (int i = childCount - 1; i >= 0; i--) {
                    rootItem.getChild(i).remove();
                }
            }
        } else {
            int childCount = this.getItemCount();
            for (int i = childCount - 1; i >= 0; i--) {
                this.getItem(i).remove();
            }
        }
    }

    private void processItems(List itemList, String action, Object mapping) {
        createItems(itemList, action, mapping);
        connectItems();
    }

    private void createItems(List itemList, String action, Object mapping) {
        if (itemList == null) {
            return;
        }
        for (Object item : itemList) {
            Object itemKey = getKeyValue(item, NODE, mapping);
            if (itemKey != null) {
                items.put(itemKey.toString(), item);
            }
        }

        if (hasStructuredRelation(itemList)) {
            structuredData = true;
            createItemsFromStructuredData(null, itemList, action, mapping);
        } else {
            structuredData = false;
            createItemsFromKeyData(itemList, action, mapping);
        }
    }

    /**
     *  In sructured data - from java servive the relation between the items are implicit by its structure.
     *  We have store the relation for intenal use by iterating the items properties.
     * 
     */
    private void createItemsFromStructuredData(String parentKey, List itemList, String action, Object mapping) {
        if (itemList != null) {
            for (Object item : itemList) {
                String nodeKey = generateKey4Map(item, mapping);
                if (nodeKey != null) {
                    if (parentKey != null) {
                        nodeKey += KEY_DELIMITER + parentKey;
                    }

                    TreeItem treeItem = createTreeItem(item, mapping);

                    storeUIAndModel(nodeKey, treeItem, item);
                    key2Parent.put(nodeKey, parentKey);

                    if (isMapContainer(item)) {
                        //Map map = (Map)item;
                        Map map = ((DataContainerGVO) item).getDataMap();
                        Iterator<String> itrKeys = map.keySet().iterator();
                        while (itrKeys.hasNext()) {
                            String key = itrKeys.next();
                            //Object value = getKeyValue(map, key);
                            Object value = map.get(key);
                            if (value instanceof DataContainerGVO) {
                                DataContainerGVO valueGVO = (DataContainerGVO) value;
                                if (valueGVO.getKind() == DataContainerGVO.KIND_COLLECTION) {
                                    TreeItem subTreeItem = createTreeItem(key);
                                    String subNodeKey = key + KEY_DELIMITER + nodeKey;
                                    storeUIAndModel(subNodeKey, subTreeItem, null);
                                    createItemsFromStructuredData(subNodeKey, valueGVO.getListofDC(), action,
                                            mapping);
                                    key2Parent.put(subNodeKey, nodeKey);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    // If the data contains id and parent as attributes or if user specified in mapping the values for it. 
    private void createItemsFromKeyData(List itemList, String action, Object mapping) {
        if (itemList != null) {
            for (Object item : itemList) {
                String nodeKey = generateKey4Map(item, mapping);
                if (nodeKey != null) {
                    Object parentItem = getParentItem(item, mapping);
                    String parentKey = generateKey4Map(parentItem, mapping);

                    TreeItem treeItem = createTreeItem(item, mapping);

                    storeUIAndModel(nodeKey, treeItem, item);
                    key2Parent.put(nodeKey, parentKey);
                }
            }
        }
    }

    private Object getParentItem(Object item, Object mapping) {
        Object parentItemKey = getKeyValue(item, PARENT_NODE, mapping);
        if (parentItemKey != null) {
            return items.get(parentItemKey.toString());
        }
        return null;
    }

    private void connectItems() {
        Iterator<String> itrKeys = key2Parent.keySet().iterator();
        while (itrKeys.hasNext()) {
            String nodeKey = itrKeys.next();
            String parentKey = key2Parent.get(nodeKey);
            TreeItem treeItem = (TreeItem) getUIObject(nodeKey);
            TreeItem parentTreeItem = (TreeItem) getUIObject(parentKey);
            if (treeItem != null) {
                addItem(treeItem, parentTreeItem);
            }
        }
    }

    private boolean hasStructuredRelation(List itemList) {
        if (itemList != null) {
            for (Object item : itemList) {
                if (isMapContainer(item)) {
                    //Map map = (Map)item;
                    Map map = ((DataContainerGVO) item).getDataMap();
                    Iterator<String> itrKeys = map.keySet().iterator();
                    while (itrKeys.hasNext()) {
                        String key = itrKeys.next();
                        //Object value = getKeyValue(map, key);
                        Object value = map.get(key);
                        if (value instanceof DataContainerGVO) {
                            DataContainerGVO valueGVO = (DataContainerGVO) value;
                            if (valueGVO.getKind() == DataContainerGVO.KIND_COLLECTION) {
                                return true;
                            }
                        }
                    }
                }
            }
        }
        return false;
    }

    private void doItemSelection(SelectionEvent<TreeItem> event) {
        selectedItem = event.getSelectedItem();
        fireItemClickEvent(event);
    }

    private void fireItemClickEvent(final SelectionEvent<TreeItem> event) {
        // When a qaml is listening to a tree with its id, and when clicks on parent tree , as the parent tree is also an item 
        // we dont have to do implicit click handling of item. otherwise 2 times the event will be executed.
        if (isRootItem(event.getSelectedItem())) {
            return;
        }

        if (rootItem instanceof QTreeItem) {
            final Label rootItemlabel = ((QTreeItem) rootItem).getLabel();
            ClickEvent clickEvent = new ClickEvent() {
                // This is to make sure that we are making the item id and value available as src-id and src-value
                @Override
                public Object getSource() {
                    if (event.getSelectedItem() instanceof QTreeItem) {
                        return ((QTreeItem) event.getSelectedItem()).getLabel();
                    }
                    return rootItemlabel;
                }
            };
            rootItemlabel.fireEvent(clickEvent);
        }
    }

    private TreeItem createTreeItem(String name) {
        TreeItem treeItem = new QTreeItem(name, this);
        fillInAttributesFromRoot(name, treeItem);
        return treeItem;
    }

    private TreeItem createTreeItem(Object item, Object mapping) {
        TreeItemGVO itemGVO = populateGVO(item, mapping);

        TreeItem treeItem = new QTreeItem(itemGVO.getDisplayname(), this);
        fillInItemProperties(itemGVO, treeItem);
        fillInAttributesFromRoot(itemGVO.getId(), treeItem);
        return treeItem;
    }

    private void fillInAttributesFromRoot(String itemId, TreeItem treeItem) {
        String uuid = "";
        String appContext = "";
        String parent = "";

        String rootTreeId = RendererHelper.getComponentAttributeValue(this, "id");
        itemId = itemId + rootTreeId.substring(rootTreeId.indexOf("|"));
        uuid = RendererHelper.getComponentPropertyValue(this, "uuid");
        appContext = RendererHelper.getComponentContext(this);
        parent = RendererHelper.getParentComponent(this);

        Label itemLabel = ((QTreeItem) treeItem).getLabel();
        DOM.setElementAttribute(itemLabel.getElement(), "id", itemId);
        DOM.setElementProperty(itemLabel.getElement(), "uuid", uuid);
        RendererHelper.setComponentContext(itemLabel, appContext);
        RendererHelper.setParentComponent(itemLabel, parent);
    }

    private void fillInItemProperties(TreeItemGVO itemGVO, TreeItem treeItem) {
        treeItem.setState(itemGVO.getExpand());
    }

    private TreeItemGVO populateGVO(Object item, Object mapping) {
        Object id = getKeyValue(item, "id", mapping);
        Object displayName = getKeyValue(item, "displayname", mapping);
        Object disabled = getKeyValue(item, "disabled", mapping);
        Object visible = getKeyValue(item, "visible", mapping);
        Object tooltip = getKeyValue(item, "tooltip", mapping);
        Object value = getKeyValue(item, "value", mapping);
        Boolean expand = false;
        Object propExpand = getKeyValue(item, "expand", mapping);
        if (propExpand instanceof Boolean) {
            expand = (Boolean) propExpand;
        }
        if (displayName == null) {
            displayName = new String("Item");
        }

        TreeItemGVO itemGVO = new TreeItemGVO();
        itemGVO.setId(getDataString(id));
        itemGVO.setDisplayname(getDataString(displayName));
        itemGVO.setExpand(expand);
        itemGVO.setTooltip(getDataString(tooltip));

        return itemGVO;
    }

    public String getDataString(Object item) {
        String value = null;
        if (item instanceof DataContainerGVO) {
            value = ((DataContainerGVO) item).getDataString();
        }
        return value;
    }

    private void storeUIAndModel(Object key, UIObject uiObject, Object uiObjectModel) {
        uiToKey.put(uiObject, key);
        keyToUI.put(key, uiObject);
        keyToUIModel.put(key, uiObjectModel);
    }

    private UIObject getUIObject(Object key) {
        return keyToUI.get(key);
    }

    private Object getUIModel(Object key) {
        return keyToUIModel.get(key);
    }

    private String generateKey4Map(Object item, Object mapping) {
        return generateKey4Map(item, NODE, mapping);
    }

    private String generateKey4Map(Object item, String key, Object mapping) {
        Object nodeKey = getKeyValue(item, key, mapping);
        Object nodeTypeKey = getKeyValue(item, NODE_TYPE, mapping);
        if ((nodeKey != null)) {
            return nodeKey + KEY_DELIMITER + nodeTypeKey;
        }
        return null;
    }

    private Object getKeyValue(Object item, String key) {
        return getKeyValue(item, key, null);
    }

    private Object getKeyValue(Object item, String key, Object mapping) {
        if (isMapContainer(item) && (key != null)) {
            //Map map = (Map)item;
            Map map = ((DataContainerGVO) item).getDataMap();
            key = getMappedKey(key, mapping);
            if (map.containsKey(key)) {
                return map.get(key);
            } else if (map.containsKey(key.toLowerCase())) {
                return map.get(key.toLowerCase());
            } else if (map.containsKey(key.toUpperCase())) {
                return map.get(key.toUpperCase());
            }
        }
        return null;
    }

    private String getMappedKey(String key, Object mapping) {
        String newKey = key;
        if (mapping instanceof Map) {
            Map map = (Map) mapping;
            if (map.containsKey(key)) {
                newKey = (String) map.get(key);
            }
        }
        return newKey;
    }

    public static boolean isSetAction(String action) {
        return ((action != null) && (action.equals("set")));
    }

    /*public static boolean isMap(Object data) {
       return (data instanceof Map);
    }*/
    public static boolean isMapContainer(Object data) {
        if (data instanceof DataContainerGVO) {
            return (((DataContainerGVO) data).isMap());
        }
        return false;
    }

    public static boolean isList(Object data) {
        return (data instanceof List);
    }
}